JAMES-2242 Make JamesMailetContext match its documentation

 - sendMail(mail) intend to have the same behaviour as incoming SMTP
   - It was not the case, mail was set on top of the mail state, Hence the mail 
was directly processed by THAT processor, and not executed by ROOT processor
   - When correcting that issue, we then miss a way to send a mail to a 
specific processor. We need to add a method for that.

 Hence, I added sendMail(mail, state)

 This solves the `Boucing issues` encountered in RemoteDelivery


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/9c1a7cdb
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/9c1a7cdb
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/9c1a7cdb

Branch: refs/heads/master
Commit: 9c1a7cdb57f3a39d392d51c512fd036b2475358c
Parents: 8e60652
Author: benwa <btell...@linagora.com>
Authored: Wed Nov 29 16:49:49 2017 +0700
Committer: Antoine Duprat <adup...@linagora.com>
Committed: Mon Dec 4 14:42:20 2017 +0100

----------------------------------------------------------------------
 .../java/org/apache/mailet/MailetContext.java   |  17 +++
 .../mailet/base/test/FakeMailContext.java       |   9 +-
 .../GatewayRemoteDeliveryIntegrationTest.java   |   8 --
 .../impl/JamesMailetContext.java                |   9 +-
 .../impl/JamesMailetContextTest.java            | 113 ++++++++++++++++++-
 .../mailets/remoteDelivery/Bouncer.java         |   3 +-
 6 files changed, 144 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
----------------------------------------------------------------------
diff --git a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java 
b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
index 202caf7..e43b201 100644
--- a/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
+++ b/mailet/api/src/main/java/org/apache/mailet/MailetContext.java
@@ -338,6 +338,23 @@ public interface MailetContext {
     void sendMail(Mail mail)
             throws MessagingException;
 
+
+
+    /**
+     * Sends an outgoing message to the top of this mailet container's root 
queue,
+     * targeting a specific processing state.
+     *
+     * This functionally allows mail treatment done out of the MailetProcessor 
to be sent
+     * to a specific processor inside the MailetContainer. This is for 
instance useful for bouncing mail
+     * being remote delivered (asynchronously to original mail treatment)
+     *
+     * @param message The message to send
+     * @param state   The state of the message, indicating the name of the 
processor for
+     *                which the message will be queued
+     * @throws MessagingException if an error occurs accessing or sending the 
message
+     */
+    void sendMail(Mail mail, String state) throws MessagingException;
+
     /**
      * Bounces the message using a standard format with the given message.
      * <p/>

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
----------------------------------------------------------------------
diff --git 
a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java 
b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
index 9c54dc0..62d2c9d 100644
--- a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
+++ b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMailContext.java
@@ -27,13 +27,14 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.MailAddress;
 import org.apache.mailet.HostAddress;
 import org.apache.mailet.LookupException;
 import org.apache.mailet.Mail;
-import org.apache.james.core.MailAddress;
 import org.apache.mailet.MailetContext;
 import org.slf4j.Logger;
 
@@ -404,6 +405,12 @@ public class FakeMailContext implements MailetContext {
     }
 
     public void sendMail(Mail mail) throws MessagingException {
+        sendMail(mail, Mail.DEFAULT);
+    }
+
+    @Override
+    public void sendMail(Mail mail, String state) throws MessagingException {
+        mail.setState(state);
         sentMails.add(fromMail(mail));
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
index 2e01488..e325ef2 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/GatewayRemoteDeliveryIntegrationTest.java
@@ -52,7 +52,6 @@ import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.SMTPMessageSender;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
@@ -220,13 +219,6 @@ public class GatewayRemoteDeliveryIntegrationTest {
                 .body("", hasSize(0));
         }
     }
-
-    @Ignore("JAMES-2242" +
-        
"https://issues.apache.org/jira/browse/JAMES-2242?focusedCommentId=16270289&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16270289";
 +
-        "Bouncing is failing due to several issues:" +
-        " - A loop in Bounce processor, keeps posting in bounce processor 
(DSNBounce processor don't rest mail state)" +
-        " - Memory mail queue don't preserve state field like other Mail Queue 
implementations" +
-        " - Memory DNS returns RuntimeExceptions upon absent address, not DNS 
failures")
     @Test
     public void remoteDeliveryShouldBounceUponFailure() throws Exception {
         String gatewayProperty = "invalid.domain";

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
 
b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
index f460d55..51d01f9 100644
--- 
a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
+++ 
b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
@@ -406,15 +406,20 @@ public class JamesMailetContext implements MailetContext, 
Configurable {
 
     @Override
     public void sendMail(Mail mail) throws MessagingException {
+        sendMail(mail, Mail.DEFAULT);
+    }
+
+    @Override
+    public void sendMail(Mail mail, String state) throws MessagingException {
         mail.setAttribute(Mail.SENT_BY_MAILET, "true");
+        mail.setState(state);
         rootMailQueue.enQueue(mail);
     }
 
     public void sendMail(MailAddress sender, Collection<MailAddress> 
recipients, MimeMessage message, String state) throws MessagingException {
         MailImpl mail = new MailImpl(MailImpl.getId(), sender, recipients, 
message);
         try {
-            mail.setState(state);
-            sendMail(mail);
+            sendMail(mail, state);
         } finally {
             LifecycleUtil.dispose(mail);
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
 
b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
index ccb8abd..61abeeb 100644
--- 
a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
+++ 
b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
@@ -21,11 +21,14 @@ package org.apache.james.mailetcontainer.impl;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import javax.mail.internet.MimeMessage;
+
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.core.MailAddress;
 import org.apache.james.dnsservice.api.DNSService;
@@ -35,9 +38,11 @@ import org.apache.james.queue.api.MailQueue;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.server.core.MailImpl;
 import org.apache.james.user.memory.MemoryUsersRepository;
+import org.apache.mailet.Mail;
 import org.apache.mailet.base.test.MimeMessageBuilder;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 
 import com.google.common.collect.ImmutableList;
 
@@ -52,6 +57,7 @@ public class JamesMailetContextTest {
     private MemoryUsersRepository usersRepository;
     private JamesMailetContext testee;
     private MailAddress mailAddress;
+    private MailQueue spoolMailQueue;
 
     @Before
     public void setUp() throws Exception {
@@ -65,7 +71,8 @@ public class JamesMailetContextTest {
         usersRepository.setDomainList(domainList);
         testee = new JamesMailetContext();
         MailQueueFactory mailQueueFactory = mock(MailQueueFactory.class);
-        
when(mailQueueFactory.getQueue(anyString())).thenReturn(mock(MailQueue.class));
+        spoolMailQueue = mock(MailQueue.class);
+        
when(mailQueueFactory.getQueue(MailQueueFactory.SPOOL)).thenReturn(spoolMailQueue);
         testee.retrieveRootMailQueue(mailQueueFactory);
         testee.setDomainList(domainList);
         testee.setUsersRepository(usersRepository);
@@ -160,4 +167,106 @@ public class JamesMailetContextTest {
         mail.setMessage(MimeMessageBuilder.defaultMimeMessage());
         testee.bounce(mail, "message");
     }
+
+    @Test
+    public void bounceShouldEnqueueEmailWithRootState() throws Exception {
+        MailImpl mail = new MailImpl();
+        mail.setSender(mailAddress);
+        mail.setRecipients(ImmutableList.of(mailAddress));
+        mail.setMessage(MimeMessageBuilder.defaultMimeMessage());
+        testee.bounce(mail, "message");
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        
assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    public void sendMailShouldEnqueueEmailWithRootState() throws Exception {
+        MailImpl mail = new MailImpl();
+        mail.setSender(mailAddress);
+        mail.setRecipients(ImmutableList.of(mailAddress));
+        mail.setMessage(MimeMessageBuilder.defaultMimeMessage());
+        testee.sendMail(mail);
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        
assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    public void sendMailShouldEnqueueEmailWithOtherStateWhenSpecified() throws 
Exception {
+        MailImpl mail = new MailImpl();
+        mail.setSender(mailAddress);
+        mail.setRecipients(ImmutableList.of(mailAddress));
+        mail.setMessage(MimeMessageBuilder.defaultMimeMessage());
+        String other = "other";
+        testee.sendMail(mail, other);
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(other);
+    }
+
+    @Test
+    public void sendMailForMessageShouldEnqueueEmailWithRootState() throws 
Exception {
+        MimeMessage message = MimeMessageBuilder.mimeMessageBuilder()
+            .addFrom(mailAddress.asString())
+            .addToRecipient(mailAddress.asString())
+            .setText("Simple text")
+            .build();
+
+        testee.sendMail(message);
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        
assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    public void sendMailForMessageAndEnvelopeShouldEnqueueEmailWithRootState() 
throws Exception {
+        MimeMessage message = MimeMessageBuilder.mimeMessageBuilder()
+            .addFrom(mailAddress.asString())
+            .addToRecipient(mailAddress.asString())
+            .setText("Simple text")
+            .build();
+
+        MailAddress sender = mailAddress;
+        ImmutableList<MailAddress> recipients = ImmutableList.of(mailAddress);
+        testee.sendMail(sender, recipients, message);
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        
assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    public void 
sendMailForMessageAndEnvelopeShouldEnqueueEmailWithOtherStateWhenSpecified() 
throws Exception {
+        MimeMessage message = MimeMessageBuilder.mimeMessageBuilder()
+            .addFrom(mailAddress.asString())
+            .addToRecipient(mailAddress.asString())
+            .setText("Simple text")
+            .build();
+
+        MailAddress sender = mailAddress;
+        ImmutableList<MailAddress> recipients = ImmutableList.of(mailAddress);
+        String otherState = "other";
+        testee.sendMail(sender, recipients, message, otherState);
+
+        ArgumentCaptor<Mail> mailArgumentCaptor = 
ArgumentCaptor.forClass(Mail.class);
+        verify(spoolMailQueue).enQueue(mailArgumentCaptor.capture());
+        verifyNoMoreInteractions(spoolMailQueue);
+
+        
assertThat(mailArgumentCaptor.getValue().getState()).isEqualTo(otherState);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9c1a7cdb/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/Bouncer.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/Bouncer.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/Bouncer.java
index 05a302b..ce2539c 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/Bouncer.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/Bouncer.java
@@ -52,9 +52,8 @@ public class Bouncer {
         } else {
             if (configuration.getBounceProcessor() != null) {
                 mail.setAttribute(DELIVERY_ERROR, getErrorMsg(ex));
-                mail.setState(configuration.getBounceProcessor());
                 try {
-                    mailetContext.sendMail(mail);
+                    mailetContext.sendMail(mail, 
configuration.getBounceProcessor());
                 } catch (MessagingException e) {
                     LOGGER.warn("Exception re-inserting failed mail: ", e);
                 }


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

Reply via email to