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