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 2020/12/21 07:29:37 UTC

[james-project] 12/17: JAMES-3431 DSNBounce: Allow configuration of default status code

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 3635e022e54a3d9a42439e731ec8802852e608fe
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Dec 17 10:05:58 2020 +0700

    JAMES-3431 DSNBounce: Allow configuration of default status code
    
    This enable positioning a meaningful default value instead of defaulting to 'unknown' - which is not spec compliant.
---
 .../apache/james/transport/mailets/DSNBounce.java  | 13 ++++++-
 .../james/transport/mailets/DSNBounceTest.java     | 44 +++++++++++++++++++++-
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/DSNBounce.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/DSNBounce.java
index 11be842..c3ffb8d 100755
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/DSNBounce.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/DSNBounce.java
@@ -110,10 +110,17 @@ import com.google.common.collect.ImmutableSet;
  *   &lt;passThrough&gt;<i>true or false, default=true</i>&lt;/passThrough&gt;
  *   &lt;debug&gt;<i>true or false, default=false</i>&lt;/debug&gt;
  *   &lt;action&gt;<i>failed, delayed, delivered, expanded or relayed, default=failed</i>&lt;/action&gt;
+ *   &lt;defaultStatus&gt;<i>failed, delayed, delivered, expanded or relayed, default=unknown</i>&lt;/defaultStatus&gt;  &lt;!-- See https://tools.ietf.org/html/rfc3463 --&gt;
  * &lt;/mailet&gt;
  * </code>
  * </pre>
  *
+ * Possible values for defaultStatus (X being a digit):
+ *  - General structure is X.XXX.XXX
+ *  - 2.XXX.XXX indicates success and is suitable for relayed, delivered and expanded actions. 2.0.0 provides no further information.
+ *  - 4.XXX.XXX indicates transient failures and is suitable for delayed action. 4.0.0 provides no further information.
+ *  - 5.XXX.XXX indicates permanent failures and is suitable for failed. 5.0.0 provides no further information.
+ *
  * @see RedirectNotify
  */
 
@@ -150,7 +157,7 @@ public class DSNBounce extends GenericMailet implements RedirectNotify {
         }
     }
 
-    private static final ImmutableSet<String> CONFIGURABLE_PARAMETERS = ImmutableSet.of("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action");
+    private static final ImmutableSet<String> CONFIGURABLE_PARAMETERS = ImmutableSet.of("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action", "defaultStatus");
     private static final List<MailAddress> RECIPIENT_MAIL_ADDRESSES = ImmutableList.of(SpecialAddress.REVERSE_PATH);
     private static final List<InternetAddress> TO_INTERNET_ADDRESSES = ImmutableList.of(SpecialAddress.REVERSE_PATH.toInternetAddress());
 
@@ -163,6 +170,7 @@ public class DSNBounce extends GenericMailet implements RedirectNotify {
     private final DateTimeFormatter dateFormatter;
     private String messageString = null;
     private Action action = null;
+    private String defaultStatus;
 
     @Inject
     public DSNBounce(DNSService dns) {
@@ -195,6 +203,7 @@ public class DSNBounce extends GenericMailet implements RedirectNotify {
             .map(configuredValue -> Action.parse(configuredValue)
                 .orElseThrow(() -> new IllegalArgumentException("Action '" + configuredValue + "' is not supported")))
             .orElse(Action.FAILED);
+        defaultStatus = getInitParameter("defaultStatus", "unknown");
     }
 
     @Override
@@ -497,7 +506,7 @@ public class DSNBounce extends GenericMailet implements RedirectNotify {
     private String getDeliveryError(Mail originalMail) {
         return AttributeUtils
             .getValueAndCastFromMail(originalMail, DELIVERY_ERROR, String.class)
-            .orElse("unknown");
+            .orElse(defaultStatus);
     }
 
     private String getDiagnosticType(String diagnosticCode) {
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
index e05a81f..c06f0ba 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
@@ -91,7 +91,7 @@ public class DSNBounceTest {
 
         @Test
         void getAllowedInitParametersShouldReturnTheParameters() {
-            assertThat(dsnBounce.getAllowedInitParameters()).containsOnly("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action");
+            assertThat(dsnBounce.getAllowedInitParameters()).containsOnly("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action", "defaultStatus");
         }
 
         @Test
@@ -1275,4 +1275,46 @@ public class DSNBounceTest {
         SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) content.getBodyPart(1).getContent();
         assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8)).isEqualTo(expectedContent);
     }
+
+    @Test
+    void defaultStatusShouldBeUsedWhenNone() throws Exception {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            .mailetName(MAILET_NAME)
+            .mailetContext(fakeMailContext)
+            .setProperty("defaultStatus", "4.0.0")
+            .build();
+        dsnBounce.init(mailetConfig);
+
+        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+        FakeMail mail = FakeMail.builder()
+            .name(MAILET_NAME)
+            .sender(senderMailAddress)
+            .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                .setText("My content"))
+            .recipient("recipient@domain.com")
+            .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+            .remoteAddr("remoteHost")
+            .build();
+        mail.setDsnParameters(DsnParameters.builder().envId(DsnParameters.EnvId.of("xyz")).build().get());
+
+        dsnBounce.service(mail);
+
+        String expectedContent = "Reporting-MTA: dns; myhost\n" +
+            "Received-From-MTA: dns; 111.222.333.444\n" +
+            "Original-Envelope-Id: xyz\n" +
+            "\n" +
+            "Final-Recipient: rfc822; recipient@domain.com\n" +
+            "Action: failed\n" +
+            "Status: 4.0.0\n" +
+            "Diagnostic-Code: X-James; 4.0.0\n" +
+            "Last-Attempt-Date: Thu, 8 Sep 2016 14:25:52 XXXXX (UTC)\n";
+
+        List<SentMail> sentMails = fakeMailContext.getSentMails();
+        assertThat(sentMails).hasSize(1);
+        SentMail sentMail = sentMails.get(0);
+        MimeMessage sentMessage = sentMail.getMsg();
+        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+        SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) content.getBodyPart(1).getContent();
+        assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8)).isEqualTo(expectedContent);
+    }
 }
\ No newline at end of file


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