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 2021/03/08 05:44:16 UTC

[james-project] 06/30: JAMES-3506 Avoid a copy for mail sent with JMAP

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 6197af2b4f949f53104279f34b4c2e3c5f3ca1b5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Feb 26 21:59:25 2021 +0700

    JAMES-3506 Avoid a copy for mail sent with JMAP
    
    We achieve this by wrapping (byte array) based structure
    using custom MimeMessageSource rather than the input
    stream based one (that is forcing a copy).
    
    Implemented both for JMAP draft and JMAP RFC-8621.
---
 .../james/jmap/draft/methods/MessageSender.java    | 31 ++++++++++++++++++++--
 .../jmap/method/EmailSubmissionSetMethod.scala     | 16 ++++++++---
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageSender.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageSender.java
index dae8b34..c0505a3 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageSender.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/methods/MessageSender.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.jmap.draft.methods;
 
+import java.io.InputStream;
+
 import javax.inject.Inject;
 import javax.mail.MessagingException;
 
@@ -30,12 +32,37 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.server.core.Envelope;
 import org.apache.james.server.core.MailImpl;
-import org.apache.james.server.core.MimeMessageInputStreamSource;
+import org.apache.james.server.core.MimeMessageSource;
 import org.apache.mailet.Mail;
 
 import com.google.common.annotations.VisibleForTesting;
 
 public class MessageSender {
+    public static class MessageMimeMessageSource extends MimeMessageSource {
+        private final String id;
+        private final MetaDataWithContent message;
+
+        public MessageMimeMessageSource(String id, MetaDataWithContent message) {
+            this.id = id;
+            this.message = message;
+        }
+
+        @Override
+        public String getSourceId() {
+            return id;
+        }
+
+        @Override
+        public InputStream getInputStream() {
+            return message.getContent();
+        }
+
+        @Override
+        public long getMessageSize() {
+            return message.getSize();
+        }
+    }
+
     private final MailSpool mailSpool;
 
     @Inject
@@ -62,7 +89,7 @@ public class MessageSender {
             .sender(envelope.getFrom().asOptional().orElseThrow(() -> new RuntimeException("Sender is mandatory")))
             .addRecipients(envelope.getRecipients())
             .build();
-        mail.setMessageContent(new MimeMessageInputStreamSource(name, message.getContent()));
+        mail.setMessageContent(new MessageMimeMessageSource(name, message));
         return mail;
     }
 
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
index 9529f14..544f13b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
@@ -45,7 +45,7 @@ import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.queue.api.MailQueueFactory.SPOOL
 import org.apache.james.queue.api.{MailQueue, MailQueueFactory}
 import org.apache.james.rrt.api.CanSendFrom
-import org.apache.james.server.core.{MailImpl, MimeMessageInputStreamSource, MimeMessageWrapper}
+import org.apache.james.server.core.{MailImpl, MimeMessageSource, MimeMessageWrapper}
 import org.apache.mailet.{Attribute, AttributeName, AttributeValue}
 import org.reactivestreams.Publisher
 import org.slf4j.{Logger, LoggerFactory}
@@ -69,6 +69,14 @@ case class NoRecipientException() extends Exception
 case class ForbiddenFromException(from: String) extends Exception
 case class ForbiddenMailFromException(from: List[String]) extends Exception
 
+case class MessageMimeMessageSource(id: String, message: MessageResult) extends MimeMessageSource {
+  override def getSourceId: String = id
+
+  override def getInputStream: InputStream = message.getFullContent.getInputStream
+
+  override def getMessageSize: Long = message.getFullContent.size()
+}
+
 class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerializer,
                                          messageIdManager: MessageIdManager,
                                          mailQueueFactory: MailQueueFactory[_ <: MailQueue],
@@ -211,7 +219,7 @@ class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerialize
       val submissionId = EmailSubmissionId.generate
 
       val result: Try[EmailSubmissionCreationResponse] = for {
-        message <- toMimeMessage(submissionId.value, m.getFullContent.getInputStream)
+        message <- toMimeMessage(submissionId.value, m)
         envelope <- resolveEnvelope(message, request.envelope)
         validation <- validate(mailboxSession)(message, envelope)
         mail <- Try({
@@ -232,8 +240,8 @@ class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerialize
     })
   }
 
-  private def toMimeMessage(name: String, inputStream: InputStream): Try[MimeMessageWrapper] = {
-    val source = new MimeMessageInputStreamSource(name, inputStream)
+  private def toMimeMessage(name: String, message: MessageResult): Try[MimeMessageWrapper] = {
+    val source = MessageMimeMessageSource(name, message)
     // if MimeMessageCopyOnWriteProxy throws an error in the constructor we
     // have to manually care disposing our source.
     Try(new MimeMessageWrapper(source))


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