You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/12/22 19:57:51 UTC
(james-project) 05/09: JAMES-3944 Record forward loops as rrt-error
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 <bt...@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;
* <mailet match="RecipientIsLocal" class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
*/
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-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org