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 2022/03/28 07:23:52 UTC
[james-project] branch master updated: JAMES-3729 LocalDelivery error handling is non-standard (#936)
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
The following commit(s) were added to refs/heads/master by this push:
new fff209a JAMES-3729 LocalDelivery error handling is non-standard (#936)
fff209a is described below
commit fff209a0f9cd50c35fbec1596c9d6fa261c9d808
Author: vttran <vt...@linagora.com>
AuthorDate: Mon Mar 28 14:23:48 2022 +0700
JAMES-3729 LocalDelivery error handling is non-standard (#936)
---
.../james/transport/mailets/LocalDelivery.java | 1 +
.../transport/mailets/delivery/MailDispatcher.java | 44 ++++++++---
.../mailets/delivery/MailDispatcherTest.java | 85 ++++++++++++++++++++++
3 files changed, 118 insertions(+), 12 deletions(-)
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java
index b6ac485..3b11028 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/LocalDelivery.java
@@ -77,6 +77,7 @@ public class LocalDelivery extends GenericMailet {
.metric(metricFactory.generate(LOCAL_DELIVERED_MAILS_METRIC_NAME))
.build())
.consume(getInitParameter("consume", true))
+ .onMailetException(getInitParameter("onMailetException", Mail.ERROR))
.mailetContext(getMailetContext())
.build();
}
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailDispatcher.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailDispatcher.java
index b8cb379..c191d95 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailDispatcher.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailDispatcher.java
@@ -59,13 +59,15 @@ public class MailDispatcher {
}
public static class Builder {
- static final boolean CONSUME = true;
+ static final boolean DEFAULT_CONSUME = true;
+ static final String DEFAULT_ERROR_PROCESSOR = Mail.ERROR;
private MailStore mailStore;
- private Optional<Boolean> consume = Optional.empty();
+ private Boolean consume;
private MailetContext mailetContext;
+ private String onMailetException;
public Builder consume(boolean consume) {
- this.consume = Optional.of(consume);
+ this.consume = consume;
return this;
}
@@ -79,27 +81,39 @@ public class MailDispatcher {
return this;
}
+ public Builder onMailetException(String onMailetException) {
+ this.onMailetException = onMailetException;
+ return this;
+ }
+
public MailDispatcher build() {
Preconditions.checkNotNull(mailStore);
Preconditions.checkNotNull(mailetContext);
- return new MailDispatcher(mailStore, consume.orElse(CONSUME), mailetContext);
+ return new MailDispatcher(mailStore, mailetContext,
+ Optional.ofNullable(consume).orElse(DEFAULT_CONSUME),
+ Optional.ofNullable(onMailetException).orElse(DEFAULT_ERROR_PROCESSOR));
}
-
}
private final MailStore mailStore;
- private final boolean consume;
private final MailetContext mailetContext;
+ private final boolean consume;
+ private final boolean ignoreError;
+ private final boolean propagate;
+ private final String errorProcessor;
- private MailDispatcher(MailStore mailStore, boolean consume, MailetContext mailetContext) {
+ private MailDispatcher(MailStore mailStore, MailetContext mailetContext, boolean consume, String onMailetException) {
this.mailStore = mailStore;
this.consume = consume;
this.mailetContext = mailetContext;
+ this.errorProcessor = onMailetException;
+ this.ignoreError = onMailetException.equalsIgnoreCase("ignore");
+ this.propagate = onMailetException.equalsIgnoreCase("propagate");
}
public void dispatch(Mail mail) throws MessagingException {
- List<MailAddress> errors = customizeHeadersAndDeliver(mail);
- if (!errors.isEmpty()) {
+ List<MailAddress> errors = customizeHeadersAndDeliver(mail);
+ if (!errors.isEmpty() && !ignoreError) {
// If there were errors, we redirect the email to the ERROR
// processor.
// In order for this server to meet the requirements of the SMTP
@@ -112,10 +126,13 @@ public class MailDispatcher {
.sender(mail.getMaybeSender())
.addRecipients(errors)
.mimeMessage(mail.getMessage())
- .state(Mail.ERROR)
+ .state(errorProcessor)
.build();
- mailetContext.sendMail(newMail);
- LifecycleUtil.dispose(newMail);
+ try {
+ mailetContext.sendMail(newMail);
+ } finally {
+ LifecycleUtil.dispose(newMail);
+ }
}
if (consume) {
// Consume this message
@@ -145,6 +162,9 @@ public class MailDispatcher {
Throwing.consumer(savedHeaders -> restoreHeaders(mail.getMessage(), savedHeaders)))
.onErrorResume(ex -> {
LOGGER.error("Error while storing mail. This is a final exception.", ex);
+ if (propagate) {
+ return Mono.error(ex);
+ }
return Mono.just(recipient);
}))
.collectList()
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailDispatcherTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailDispatcherTest.java
index d00e156..744893c 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailDispatcherTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailDispatcherTest.java
@@ -20,6 +20,7 @@
package org.apache.james.transport.mailets.delivery;
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.doReturn;
import static org.mockito.Mockito.mock;
@@ -336,6 +337,90 @@ class MailDispatcherTest {
assertThat(mail.getMessage().getHeader(TEST_HEADER_NAME)).containsOnly(headerValue);
}
+ @Test
+ void errorsShouldBeIgnoredWhenConfigIsProvided() throws Exception {
+ MailDispatcher testee = MailDispatcher.builder()
+ .mailetContext(fakeMailContext)
+ .mailStore(mailStore)
+ .onMailetException("ignore")
+ .build();
+
+ doReturn(Mono.error(new MessagingException()))
+ .when(mailStore)
+ .storeMail(any(MailAddress.class), any(Mail.class));
+
+ FakeMail mail = FakeMail.builder()
+ .name("name")
+ .sender(MailAddressFixture.OTHER_AT_JAMES)
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .setMultipartWithBodyParts(
+ MimeMessageBuilder.bodyPartBuilder()
+ .data("toto")))
+ .recipients(MailAddressFixture.ANY_AT_JAMES)
+ .state("state")
+ .build();
+
+ testee.dispatch(mail);
+
+ assertThat(fakeMailContext.getSentMails()).isEmpty();
+ }
+
+ @Test
+ void errorShouldFlowToTheErrorProcessor() throws Exception {
+ MailDispatcher testee = MailDispatcher.builder()
+ .mailetContext(fakeMailContext)
+ .mailStore(mailStore)
+ .onMailetException("errorProcessor1")
+ .build();
+
+ doReturn(Mono.error(new MessagingException()))
+ .when(mailStore)
+ .storeMail(any(MailAddress.class), any(Mail.class));
+
+ FakeMail mail = FakeMail.builder()
+ .name("name")
+ .sender(MailAddressFixture.OTHER_AT_JAMES)
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .setMultipartWithBodyParts(
+ MimeMessageBuilder.bodyPartBuilder()
+ .data("toto")))
+ .recipients(MailAddressFixture.ANY_AT_JAMES)
+ .state("state")
+ .build();
+
+ testee.dispatch(mail);
+
+ assertThat(fakeMailContext.getSentMails()).hasSize(1)
+ .allSatisfy(sentMail -> assertThat(sentMail.getState()).isEqualTo("errorProcessor1"));
+ }
+
+ @Test
+ void dispatchShouldThrowWhenOnMailetExceptionIsPropagate() throws Exception {
+ MailDispatcher testee = MailDispatcher.builder()
+ .mailetContext(fakeMailContext)
+ .mailStore(mailStore)
+ .onMailetException("propagate")
+ .build();
+
+ doReturn(Mono.error(new MessagingException()))
+ .when(mailStore)
+ .storeMail(any(MailAddress.class), any(Mail.class));
+
+ FakeMail mail = FakeMail.builder()
+ .name("name")
+ .sender(MailAddressFixture.OTHER_AT_JAMES)
+ .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+ .setMultipartWithBodyParts(
+ MimeMessageBuilder.bodyPartBuilder()
+ .data("toto")))
+ .recipients(MailAddressFixture.ANY_AT_JAMES)
+ .state("state")
+ .build();
+
+ assertThatThrownBy(()-> testee.dispatch(mail))
+ .isInstanceOf(Exception.class);
+ }
+
public static class AccumulatorHeaderMailStore implements MailStore {
private final ArrayListMultimap<MailAddress, String[]> headerValues;
private final String headerName;
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org