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 d7b0c26128e0c84ab6d01c41221f67d171426aca
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Mon Dec 18 20:58:05 2023 +0100

    JAMES-3944 Record forward loops as rrt-error
---
 .../mailets/FilterForwardIntegrationTest.java      | 43 +++++++++++
 .../james/mailets/ForwardIntegrationTest.java      | 45 +++++++++++
 .../james/mailets/ForwardLoopIntegrationTest.java  | 88 +++++++++++++++++++++-
 .../mailets/RecipientRewriteTableProcessor.java    | 24 +++++-
 .../james/jmap/mailet/filter/ActionApplier.java    | 34 +++++++--
 .../james/jmap/mailet/filter/JMAPFiltering.java    | 11 ++-
 6 files changed, 233 insertions(+), 12 deletions(-)

diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
index adeb67b63b..aded25a862 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/FilterForwardIntegrationTest.java
@@ -21,9 +21,11 @@ package org.apache.james.mailets;
 
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.CONTAINS;
 import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
+import static 
org.apache.james.mailets.configuration.CommonProcessors.RRT_ERROR_REPOSITORY;
 import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
 import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
 import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
 
@@ -46,6 +48,7 @@ import org.apache.james.utils.FilteringManagementProbeImpl;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.MailRepositoryProbeImpl;
 import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.SpoolerProbe;
 import org.apache.mailet.Mail;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.AfterEach;
@@ -95,6 +98,7 @@ public class FilterForwardIntegrationTest {
                         .mailet(ToRepository.class)
                         .addProperty("repositoryPath", 
CUSTOM_REPOSITORY.asString())))
                 .putProcessor(CommonProcessors.error())
+                .putProcessor(CommonProcessors.rrtError())
                 .putProcessor(CommonProcessors.transport())
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder);
@@ -152,4 +156,43 @@ public class FilterForwardIntegrationTest {
         SoftAssertions.assertSoftly(Throwing.consumer(softly -> 
softly.assertThat(mailRepositoryProbe.listMails(CUSTOM_REPOSITORY)
             .anyMatch(Throwing.predicate(mail -> 
mail.getRecipients().contains(BOB.asMailAddress())))).isFalse()));
     }
+
+    @Test
+    void regularForwardShouldNotLeadToRecordingRRTError() throws Exception {
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to(CEDRIC.asMailAddress()).withoutACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(ALICE.asString(), PASSWORD)
+            .sendMessage(ALICE.asString(), BOB.asString());
+
+        Awaitility.await().until(() -> 
mailRepositoryProbe.getRepositoryMailCount(CUSTOM_REPOSITORY) == 1L);
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
+
+    @Test
+    void localCopyShouldNotLeadToRecordingRRTError() throws Exception {
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to(CEDRIC.asMailAddress()).keepACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(ALICE.asString(), PASSWORD)
+            .sendMessage(ALICE.asString(), BOB.asString());
+
+        Awaitility.await().until(() -> 
mailRepositoryProbe.getRepositoryMailCount(CUSTOM_REPOSITORY) == 2L);
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
+
+    @Test
+    void localCopyAloneShouldNotLeadToRecordingRRTError() throws Exception {
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to().keepACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(ALICE.asString(), PASSWORD)
+            .sendMessage(ALICE.asString(), BOB.asString());
+
+        Awaitility.await().until(() -> 
mailRepositoryProbe.getRepositoryMailCount(CUSTOM_REPOSITORY) == 1L);
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
 }
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardIntegrationTest.java
index 2c93ef3617..73f59c5cf5 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardIntegrationTest.java
@@ -20,9 +20,11 @@
 package org.apache.james.mailets;
 
 import static org.apache.james.MemoryJamesServerMain.SMTP_ONLY_MODULE;
+import static 
org.apache.james.mailets.configuration.CommonProcessors.RRT_ERROR_REPOSITORY;
 import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
 import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
 import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
 
@@ -45,6 +47,7 @@ import org.apache.james.transport.matchers.All;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.MailRepositoryProbeImpl;
 import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.SpoolerProbe;
 import org.apache.mailet.Mail;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.AfterEach;
@@ -360,6 +363,48 @@ public class ForwardIntegrationTest {
         }));
     }
 
+    @Test
+    void localCopyAloneShouldNotLeadToRecordingRRTError() throws Exception {
+        jamesServer.getProbe(DataProbeImpl.class)
+            .addMapping(MappingSource.fromUser(BOB),
+                Mapping.forward(BOB.asString()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(FROM, PASSWORD)
+            .sendMessage(FROM, BOB.asString());
+
+        Awaitility.await().until(() -> 
mailRepositoryProbe.getRepositoryMailCount(CUSTOM_REPOSITORY) == 1L);
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
+
+    @Test
+    void localCopyShouldNotLeadToRecordingRRTError() throws Exception {
+        
jamesServer.getProbe(DataProbeImpl.class).addMapping(MappingSource.fromUser(BOB),
 Mapping.forward(BOB.asString()));
+        
jamesServer.getProbe(DataProbeImpl.class).addMapping(MappingSource.fromUser(BOB),
 Mapping.forward(CEDRIC.asString()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(FROM, PASSWORD)
+            .sendMessage(FROM, BOB.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
+
+    @Test
+    void forwardShouldNotLeadToRecordingRRTError() throws Exception {
+        
jamesServer.getProbe(DataProbeImpl.class).addMapping(MappingSource.fromUser(BOB),
 Mapping.forward(CEDRIC.asString()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(FROM, PASSWORD)
+            .sendMessage(FROM, BOB.asString());
+
+        Awaitility.await().until(() -> 
mailRepositoryProbe.getRepositoryMailCount(CUSTOM_REPOSITORY) == 1L);
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isZero();
+    }
+
     @Test
     void forwardShouldSupportSeveralTargets() throws Exception {
         jamesServer.getProbe(DataProbeImpl.class)
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
index 5c86a41d6e..1168a86d28 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/ForwardLoopIntegrationTest.java
@@ -21,13 +21,14 @@ package org.apache.james.mailets;
 
 import static 
org.apache.james.jmap.api.filtering.Rule.Condition.Comparator.NOT_CONTAINS;
 import static org.apache.james.jmap.api.filtering.Rule.Condition.Field.FROM;
+import static 
org.apache.james.mailets.configuration.CommonProcessors.RRT_ERROR_REPOSITORY;
 import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
 import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
 import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
 import java.util.List;
-import java.util.stream.Stream;
 
 import org.apache.james.core.Username;
 import org.apache.james.jmap.api.filtering.Rule;
@@ -97,7 +98,8 @@ public class ForwardLoopIntegrationTest {
                 .putProcessor(ProcessorConfiguration.root()
                     .addMailet(MailetConfiguration.builder()
                         .matcher(All.class)
-                        .mailet(RecipientRewriteTable.class))
+                        .mailet(RecipientRewriteTable.class)
+                        .addProperty("errorProcessor", "rrt-error"))
                     .addMailet(MailetConfiguration.builder()
                         .matcher(All.class)
                         .mailet(JMAPFiltering.class))
@@ -106,6 +108,12 @@ public class ForwardLoopIntegrationTest {
                         .mailet(ToRepository.class)
                         .addProperty("repositoryPath", 
CUSTOM_REPOSITORY.asString())))
                 .putProcessor(CommonProcessors.error())
+                .putProcessor(ProcessorConfiguration.builder()
+                    .state("rrt-error")
+                    .addMailet(MailetConfiguration.builder()
+                        .matcher(All.class)
+                        .mailet(ToRepository.class)
+                        .addProperty("repositoryPath", 
RRT_ERROR_REPOSITORY.asString())))
                 .putProcessor(CommonProcessors.transport())
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder);
@@ -198,6 +206,82 @@ public class ForwardLoopIntegrationTest {
         }));
     }
 
+    @Test
+    void loopShouldLeadToRrtError() throws Exception {
+        dataProbe.addMapping(MappingSource.fromUser(ALICE), 
Mapping.forward(BOB.asString()));
+        dataProbe.addMapping(MappingSource.fromUser(BOB), 
Mapping.forward(CEDRIC.asString()));
+        dataProbe.addMapping(MappingSource.fromUser(CEDRIC), 
Mapping.forward(ALICE.asString()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(SENDER.asString(), PASSWORD)
+            .sendMessage(SENDER.asString(), ALICE.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isEqualTo(1);
+    }
+
+    @Test
+    void shouldDetectSenderInLoopWhenAliasAndForwardRules() throws Exception {
+        
dataProbe.addMapping(MappingSource.fromUser(Username.of("sender-alias@" + 
DEFAULT_DOMAIN)),
+            Mapping.alias(SENDER.asString()));
+        filteringManagementProbe.defineRulesForUser(ALICE, 
asRule(Forward.to(SENDER.asMailAddress()).withoutACopy()));
+        filteringManagementProbe.defineRulesForUser(SENDER, 
asRule(Forward.to(ALICE.asMailAddress()).withoutACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(SENDER.asString(), PASSWORD)
+            .sendMessage("sender-alias@" + DEFAULT_DOMAIN, ALICE.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isEqualTo(1);
+    }
+
+    @Test
+    void loopWithRuleShouldLeadToRrtError() throws Exception {
+        filteringManagementProbe.defineRulesForUser(ALICE, 
asRule(Forward.to(BOB.asMailAddress()).withoutACopy()));
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to(CEDRIC.asMailAddress()).withoutACopy()));
+        filteringManagementProbe.defineRulesForUser(CEDRIC, 
asRule(Forward.to(ALICE.asMailAddress()).withoutACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(SENDER.asString(), PASSWORD)
+            .sendMessage(SENDER.asString(), ALICE.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isEqualTo(1);
+    }
+
+    @Test
+    void loopWithLocalCopyShouldLeadToRrtError() throws Exception {
+        filteringManagementProbe.defineRulesForUser(ALICE, 
asRule(Forward.to(BOB.asMailAddress()).keepACopy()));
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to(CEDRIC.asMailAddress()).withoutACopy()));
+        filteringManagementProbe.defineRulesForUser(CEDRIC, 
asRule(Forward.to(ALICE.asMailAddress()).withoutACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(SENDER.asString(), PASSWORD)
+            .sendMessage(SENDER.asString(), ALICE.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isEqualTo(1);
+    }
+
+    @Test
+    void mixedLoopShouldLeadToRrtError() throws Exception {
+        dataProbe.addMapping(MappingSource.fromUser(ALICE), 
Mapping.forward(BOB.asString()));
+        filteringManagementProbe.defineRulesForUser(BOB, 
asRule(Forward.to(CEDRIC.asMailAddress()).withoutACopy()));
+        filteringManagementProbe.defineRulesForUser(CEDRIC, 
asRule(Forward.to(ALICE.asMailAddress()).withoutACopy()));
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(SENDER.asString(), PASSWORD)
+            .sendMessage(SENDER.asString(), ALICE.asString());
+
+        Awaitility.await().until(() -> 
jamesServer.getProbe(SpoolerProbe.class).processingFinished());
+
+        
assertThat(mailRepositoryProbe.getRepositoryMailCount(RRT_ERROR_REPOSITORY)).isEqualTo(1);
+    }
+
     @Test
     void 
forwardShouldNotCreateLoopErrorWhenFilterForwardAndRegularForwardWorkTogether() 
throws Exception {
         filteringManagementProbe.defineRulesForUser(ALICE, 
asRule(Forward.to(BOB.asMailAddress()).withoutACopy()));
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
index a34c12482c..a6dd91e2d5 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RecipientRewriteTableProcessor.java
@@ -244,6 +244,23 @@ public class RecipientRewriteTableProcessor {
             };
         }
 
+        static ForwardDecision recordLoop(MailetContext context,
+                                          MailAddress originalRecipient,
+                                          ProcessingState errorProcessor) {
+            return mail -> {
+                MailImpl copy = MailImpl.duplicate(mail);
+                try {
+                    copy.setRecipients(ImmutableList.of(originalRecipient));
+                    copy.setState(errorProcessor.getValue());
+                    copy.setName(MailImpl.getId());
+
+                    context.sendMail(copy, errorProcessor.getValue());
+                } finally {
+                    LifecycleUtil.dispose(copy);
+                }
+            };
+        }
+
         private static void recordInAuditTrail(Mail mail, MailImpl copy, 
MailAddress originalRecipient) {
             AuditTrail.entry()
                 .protocol("mailetcontainer")
@@ -300,9 +317,14 @@ public class RecipientRewriteTableProcessor {
         if (!forwardRecipients.isEmpty()) {
             result.add(ForwardDecision.sendACopy(mailetContext, 
originalRecipient, forwardRecipients));
         }
-        if (!newRecipients.contains(originalRecipient)) {
+        boolean localCopy = newRecipients.contains(originalRecipient);
+        if (!localCopy) {
             result.add(ForwardDecision.removeRecipient(originalRecipient));
         }
+        boolean emailIsDropped = !forwardedRecipients.isEmpty() && 
forwardRecipients.isEmpty() && !localCopy;
+        if (emailIsDropped) {
+            result.add(ForwardDecision.recordLoop(mailetContext, 
originalRecipient, errorProcessor));
+        }
 
         return result.build().stream();
     }
diff --git 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
index f5c2038223..0017dba5ca 100644
--- 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
+++ 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/ActionApplier.java
@@ -19,11 +19,12 @@
 
 package org.apache.james.jmap.mailet.filter;
 
+import static org.apache.james.jmap.mailet.filter.JMAPFiltering.RRT_ERROR;
+
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Stream;
 
-import com.google.common.collect.Sets;
 import javax.inject.Inject;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
@@ -52,6 +53,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
 
 public class ActionApplier {
     public static final Logger LOGGER = 
LoggerFactory.getLogger(ActionApplier.class);
@@ -146,9 +148,14 @@ public class ActionApplier {
                 if (!forwardRecipients.isEmpty()) {
                     sendACopy(recordedRecipients, forwardRecipients);
                 }
-                if (!newRecipients.contains(mailAddress)) {
+                boolean localCopy = newRecipients.contains(mailAddress);
+                if (!localCopy) {
                     removeFromRecipients();
                 }
+                boolean emailIsDropped = !forward.getAddresses().isEmpty() && 
forwardRecipients.isEmpty() && !localCopy;
+                if (emailIsDropped) {
+                    recordLoop();
+                }
             }));
     }
 
@@ -210,17 +217,15 @@ public class ActionApplier {
         }
     }
 
-    private void sendACopy(MailetContext context,
-                           MailAddress originalRecipient,
-                           LoopPrevention.RecordedRecipients 
recordedRecipients,
+    private void sendACopy(LoopPrevention.RecordedRecipients 
recordedRecipients,
                            Set<MailAddress> newRecipients) throws 
MessagingException {
         MailImpl copy = MailImpl.duplicate(mail);
         try {
-            copy.setSender(originalRecipient);
+            copy.setSender(mailAddress);
             copy.setRecipients(newRecipients);
-            recordedRecipients.merge(originalRecipient).recordOn(copy);
+            recordedRecipients.merge(mailAddress).recordOn(copy);
 
-            context.sendMail(copy);
+            mailetContext.sendMail(copy);
 
             recordInAuditTrail(copy);
         } finally {
@@ -228,6 +233,19 @@ public class ActionApplier {
         }
     }
 
+    private void recordLoop() throws MessagingException {
+        MailImpl copy = MailImpl.duplicate(mail);
+        try {
+            copy.setRecipients(ImmutableList.of(mailAddress));
+            copy.setState(RRT_ERROR.getValue());
+            copy.setName(MailImpl.getId());
+
+            mailetContext.sendMail(copy);
+        } finally {
+            LifecycleUtil.dispose(copy);
+        }
+    }
+
     private void recordInAuditTrail(MailImpl copy) {
         AuditTrail.entry()
             .protocol("mailetcontainer")
diff --git 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
index ce150ab6ee..af16c98ac4 100644
--- 
a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
+++ 
b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/mailet/filter/JMAPFiltering.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.jmap.mailet.filter;
 
+import java.util.Collection;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -32,10 +33,13 @@ import org.apache.james.jmap.api.filtering.Rules;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.mailet.Mail;
+import org.apache.mailet.ProcessingState;
 import org.apache.mailet.base.GenericMailet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
+
 import reactor.core.publisher.Mono;
 
 /**
@@ -50,7 +54,7 @@ import reactor.core.publisher.Mono;
  *  &lt;mailet match="RecipientIsLocal" 
class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/&gt;
  */
 public class JMAPFiltering extends GenericMailet {
-
+    static final ProcessingState RRT_ERROR = new ProcessingState("rrt-error");
     private final Logger logger = LoggerFactory.getLogger(JMAPFiltering.class);
 
     private final FilteringManagement filteringManagement;
@@ -94,4 +98,9 @@ public class JMAPFiltering extends GenericMailet {
             return Optional.empty();
         }
     }
+
+    @Override
+    public Collection<ProcessingState> requiredProcessingState() {
+        return ImmutableList.of(RRT_ERROR);
+    }
 }


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

Reply via email to