JAMES-2301 JMS mail queue do not preserve per-recipient headers. Now we serialize per-recipient headers as a message property and deserialize it when dequeue.
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2db5e2fb Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2db5e2fb Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2db5e2fb Branch: refs/heads/master Commit: 2db5e2fb00b8af08e544347f628b7b0f87c5577b Parents: 196c637 Author: Edgar Asatryan <[email protected]> Authored: Thu Jul 5 13:49:58 2018 +0400 Committer: benwa <[email protected]> Committed: Wed Jul 11 10:31:55 2018 +0700 ---------------------------------------------------------------------- .../activemq/ActiveMQMailQueueBlobTest.java | 15 ++------ server/queue/queue-jms/pom.xml | 4 ++ .../apache/james/queue/jms/JMSMailQueue.java | 39 +++++++++++--------- .../org/apache/james/queue/jms/JMSSupport.java | 3 ++ 4 files changed, 33 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/2db5e2fb/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java index e7e41dd..36dfa8b 100644 --- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java +++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java @@ -56,7 +56,7 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont MyFileSystem fileSystem; @BeforeEach - public void setUp(BrokerService broker) throws Exception { + public void setUp(BrokerService broker) { fileSystem = new MyFileSystem(); ActiveMQConnectionFactory connectionFactory = createConnectionFactory(); FileSystemBlobTransferPolicy policy = new FileSystemBlobTransferPolicy(); @@ -71,7 +71,7 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont } @AfterEach - public void tearDown() throws Exception { + public void tearDown() { mailQueue.dispose(); fileSystem.destroy(); } @@ -102,13 +102,6 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont @Test @Override - @Disabled("JAMES-2301 Per recipients headers are not attached to the message.") - public void queueShouldPreservePerRecipientHeaders() { - - } - - @Test - @Override @Disabled("JAMES-2308 Flushing JMS mail queue randomly re-order them" + "Random test failing around 1% of the time") public void flushShouldPreserveBrowseOrder() { @@ -145,7 +138,7 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont private static final Logger LOGGER = LoggerFactory.getLogger(MyFileSystem.class); @Override - public InputStream getResource(String url) throws IOException { + public InputStream getResource(String url) { return null; } @@ -166,7 +159,7 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont throw new FileNotFoundException(); } - public void destroy() throws FileNotFoundException { + public void destroy() { try { FileUtils.forceDelete(getFile(BASE_DIR)); } catch (FileNotFoundException e) { http://git-wip-us.apache.org/repos/asf/james-project/blob/2db5e2fb/server/queue/queue-jms/pom.xml ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/pom.xml b/server/queue/queue-jms/pom.xml index 59a65b8..785a143 100644 --- a/server/queue/queue-jms/pom.xml +++ b/server/queue/queue-jms/pom.xml @@ -86,6 +86,10 @@ <artifactId>guava</artifactId> </dependency> <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/2db5e2fb/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java index 75f65bc..e6a6958 100644 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java +++ b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java @@ -32,6 +32,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; +import java.util.Optional; import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; @@ -50,7 +51,9 @@ import javax.mail.MessagingException; import javax.mail.internet.AddressException; import javax.mail.internet.MimeMessage; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.iterators.EnumerationIterator; +import org.apache.commons.lang3.SerializationUtils; import org.apache.james.core.MailAddress; import org.apache.james.lifecycle.api.Disposable; import org.apache.james.metrics.api.Metric; @@ -63,10 +66,13 @@ import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.server.core.MailImpl; import org.apache.james.server.core.MimeMessageCopyOnWriteProxy; import org.apache.mailet.Mail; +import org.apache.mailet.PerRecipientHeaders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.extra.Temporals; +import com.github.fge.lambdas.Throwing; +import com.google.common.base.Joiner; import com.google.common.collect.Iterators; /** @@ -297,27 +303,20 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori props.put(JAMES_MAIL_MESSAGE_SIZE, mail.getMessageSize()); props.put(JAMES_MAIL_NAME, mail.getName()); - StringBuilder recipientsBuilder = new StringBuilder(); - - Iterator<MailAddress> recipients = mail.getRecipients().iterator(); - while (recipients.hasNext()) { - String recipient = recipients.next().toString(); - recipientsBuilder.append(recipient.trim()); - if (recipients.hasNext()) { - recipientsBuilder.append(JAMES_MAIL_SEPARATOR); - } + // won't serialize the empty headers so it is mandatory + // to handle nulls when reconstructing mail from message + if (!mail.getPerRecipientSpecificHeaders().getHeadersByRecipient().isEmpty()) { + byte[] serialize = SerializationUtils.serialize(mail.getPerRecipientSpecificHeaders()); + props.put(JAMES_MAIL_PER_RECIPIENT_HEADERS, Base64.encodeBase64String(serialize)); } - props.put(JAMES_MAIL_RECIPIENTS, recipientsBuilder.toString()); + + String recipientsAsString = Joiner.on(JAMES_MAIL_SEPARATOR).skipNulls().join(mail.getRecipients()); + + props.put(JAMES_MAIL_RECIPIENTS, recipientsAsString); props.put(JAMES_MAIL_REMOTEADDR, mail.getRemoteAddr()); props.put(JAMES_MAIL_REMOTEHOST, mail.getRemoteHost()); - String sender; - MailAddress s = mail.getSender(); - if (s == null) { - sender = ""; - } else { - sender = mail.getSender().toString(); - } + String sender = Optional.ofNullable(mail.getSender()).map(MailAddress::asString).orElse(""); StringBuilder attrsBuilder = new StringBuilder(); Iterator<String> attrs = mail.getAttributeNames(); @@ -386,6 +385,12 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori mail.setLastUpdated(new Date(message.getLongProperty(JAMES_MAIL_LAST_UPDATED))); mail.setName(message.getStringProperty(JAMES_MAIL_NAME)); + Optional.ofNullable(message.getStringProperty(JAMES_MAIL_PER_RECIPIENT_HEADERS)) + .map(String::getBytes) + .map(Throwing.function(Base64::decodeBase64)) + .<PerRecipientHeaders>map(SerializationUtils::deserialize) + .ifPresent(mail::addAllSpecificHeaderForRecipient); + List<MailAddress> rcpts = new ArrayList<>(); String recipients = message.getStringProperty(JAMES_MAIL_RECIPIENTS); StringTokenizer recipientTokenizer = new StringTokenizer(recipients, JAMES_MAIL_SEPARATOR); http://git-wip-us.apache.org/repos/asf/james-project/blob/2db5e2fb/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSupport.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSupport.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSupport.java index a19d078..cdc5026 100644 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSupport.java +++ b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSSupport.java @@ -41,6 +41,9 @@ public interface JMSSupport { /** JMS Property which holds the mail name as String */ String JAMES_MAIL_NAME = "JAMES_MAIL_NAME"; + /** JMS Property which holds the association between recipients and specific headers*/ + String JAMES_MAIL_PER_RECIPIENT_HEADERS = "JAMES_MAIL_PER_RECIPIENT_HEADERS"; + /** * Separator which is used for separate an array of String values in the JMS * Property value --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
