From 48b9323872a6adc487305581634694876ec3bc4b Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 12 Oct 2020 15:54:50 -0400 Subject: [PATCH 1/2] GH-3356: Add the way to not load mail message Fixes https://github.com/spring-projects/spring-integration/issues/3356 In some cases it is not necessary to have a whole mail message to be load when it could be filtered out downstream * Treat "no eager load" for `MimeMessage` in the `AbstractMailReceiver` when no `headerMapper`, not `simpleContent` and no `autoCloseFolder` --- .../integration/mail/AbstractMailReceiver.java | 4 ++-- .../integration/mail/dsl/MailTests.java | 13 ++++++------- src/reference/asciidoc/mail.adoc | 10 +++++++++- src/reference/asciidoc/whats-new.adoc | 7 +++++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java index b288a898291..7e43e44772d 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java @@ -502,8 +502,8 @@ private void postProcessFilteredMessages(Message[] filteredMessages) throws Mess if (shouldDeleteMessages()) { deleteMessages(filteredMessages); } - if (this.headerMapper == null) { - // Copy messages to cause an eager fetch + // Copy messages to cause an eager fetch + if (this.headerMapper == null && (this.autoCloseFolder || this.simpleContent)) { for (int i = 0; i < filteredMessages.length; i++) { MimeMessage mimeMessage = new IntegrationMimeMessage((MimeMessage) filteredMessages[i]); filteredMessages[i] = mimeMessage; diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/dsl/MailTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/dsl/MailTests.java index 1677757b5a5..151c81f35f7 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/dsl/MailTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/dsl/MailTests.java @@ -33,9 +33,8 @@ import javax.mail.search.FromTerm; import javax.mail.search.SearchTerm; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -63,13 +62,13 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.PollableChannel; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; /** * @author Gary Russell * @author Artem Bilan */ -@RunWith(SpringRunner.class) +@SpringJUnitConfig @DirtiesContext public class MailTests { @@ -82,7 +81,7 @@ public class MailTests { private static final ImapServer imapIdleServer = TestMailServer.imap(0); - @BeforeClass + @BeforeAll public static void setup() throws InterruptedException { int n = 0; while (n++ < 100 && (!smtpServer.isListening() || !pop3Server.isListening() @@ -216,7 +215,7 @@ public IntegrationFlow sendMailFlow() { .enrichHeaders(Mail.headers() .subjectFunction(m -> "foo") .from("foo@bar") - .toFunction(m -> new String[] { "bar@baz" })) + .toFunction(m -> new String[]{ "bar@baz" })) .handle(Mail.outboundAdapter("localhost") .port(smtpServer.getPort()) .credentials("user", "pw") diff --git a/src/reference/asciidoc/mail.adoc b/src/reference/asciidoc/mail.adoc index 71308d70ae2..6f0a93233bf 100644 --- a/src/reference/asciidoc/mail.adoc +++ b/src/reference/asciidoc/mail.adoc @@ -128,13 +128,17 @@ Closeable closeableResource = StaticMessageHeaderAccessor.getCloseableResource(m if (closeableResource != null) { closeableResource.close(); } - ---- ==== Keeping the folder open is useful in cases where communication with the server is needed during parsing multipart content of the email with attachments. The `close()` on the `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` header delegates to the `AbstractMailReceiver` to close the folder with `expunge` option if `shouldDeleteMessages` is configured respectively on the `AbstractMailReceiver`. +Starting with version 5.4, it is possible now to return a `MimeMessage` as is without any conversion or eager content loading. +These functionality is possible with these options combination: no `headerMapper` provided, the `simpleContent` is disabled and the `autoCloseFolder` is turned off. +The whole `MimeMessage` is present as a payload of the Spring message to produce. +Only a header presented is the mentioned above `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` for the folder to close when done with the `MimeMessage` processing. + [[mail-mapping]] === Inbound Mail Message Mapping @@ -210,6 +214,10 @@ Starting with version 4.3, the transformer handles embedded `Part` instances (as The transformer is a subclass of `AbstractMailTransformer` that maps the address and subject headers from the preceding list. If you wish to perform some other transformation on the message, consider subclassing `AbstractMailTransformer`. +Starting with version 5.4, when no `headerMapper`, no `autoCloseFolder` and no `simpleContent`, the `MimeMessage` is returned as is in the payload of produced Spring message. +This way a content of the `MimeMessage` is loaded on demand. +All the mentioned above transformations are still valid. + [[mail-namespace]] === Mail Namespace Support diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index 9848ad6f571..70788b7e684 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -78,6 +78,7 @@ See <<./ip.adoc#ip-collaborating-adapters,Collaborating Channel Adapters>> and < The `spring-integration-rmi` module is deprecated with no replacement and is going to be removed in the next major version. See <<./rmi.adoc#rmi, RMI Support>> for more information. + [[x5.4-amqp]] === AMQP Changes @@ -86,3 +87,9 @@ See <<./amqp.adoc#alternative-confirms-returns,Alternative Mechanism for Publish A new `BatchMode.EXTRACT_PAYLOAD_WITH_HEADERS` is supported by the `AmqpInboundChannelAdapter`. See <<./amqp.adoc#amqp-inbound-channel-adapter,Inbound Channel Adapter>> for more information. + +[[x5.4-mail]] +=== Mail Changes + +The `AbstractMailReceiver` now can produce `MimeMessage` as is without eager fetching for its content. +See <<./mail.adoc#mail-inbound, Mail-receiving Channel Adapter>> for more information. From 236e28aab3af1b0f9205a78474ea0d16a83bf241 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 12 Oct 2020 16:21:00 -0400 Subject: [PATCH 2/2] Fix language in Docs Co-authored-by: Gary Russell --- src/reference/asciidoc/mail.adoc | 12 ++++++------ src/reference/asciidoc/whats-new.adoc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/reference/asciidoc/mail.adoc b/src/reference/asciidoc/mail.adoc index 6f0a93233bf..aac93902cab 100644 --- a/src/reference/asciidoc/mail.adoc +++ b/src/reference/asciidoc/mail.adoc @@ -135,9 +135,9 @@ Keeping the folder open is useful in cases where communication with the server i The `close()` on the `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` header delegates to the `AbstractMailReceiver` to close the folder with `expunge` option if `shouldDeleteMessages` is configured respectively on the `AbstractMailReceiver`. Starting with version 5.4, it is possible now to return a `MimeMessage` as is without any conversion or eager content loading. -These functionality is possible with these options combination: no `headerMapper` provided, the `simpleContent` is disabled and the `autoCloseFolder` is turned off. -The whole `MimeMessage` is present as a payload of the Spring message to produce. -Only a header presented is the mentioned above `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` for the folder to close when done with the `MimeMessage` processing. +This functionality is enabled with this combination of options: no `headerMapper` provided, the `simpleContent` property is `false` and the `autoCloseFolder` property is `false`. +The `MimeMessage` is present as the payload of the Spring message produced. +In this case, the only header populated is the above mentioned `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` for the folder which must be closed when processing of the the `MimeMessage` is complete. [[mail-mapping]] === Inbound Mail Message Mapping @@ -214,9 +214,9 @@ Starting with version 4.3, the transformer handles embedded `Part` instances (as The transformer is a subclass of `AbstractMailTransformer` that maps the address and subject headers from the preceding list. If you wish to perform some other transformation on the message, consider subclassing `AbstractMailTransformer`. -Starting with version 5.4, when no `headerMapper`, no `autoCloseFolder` and no `simpleContent`, the `MimeMessage` is returned as is in the payload of produced Spring message. -This way a content of the `MimeMessage` is loaded on demand. -All the mentioned above transformations are still valid. +Starting with version 5.4, when no `headerMapper` is provided, `autoCloseFolder` is `false` and `simpleContent` is `false`, the `MimeMessage` is returned as-is in the payload of the Spring message produced. +This way, the content of the `MimeMessage` is loaded on demand when referenced, later in the flow. +All of the mentioned above transformations are still valid. [[mail-namespace]] === Mail Namespace Support diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index 70788b7e684..605104b36ae 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -91,5 +91,5 @@ See <<./amqp.adoc#amqp-inbound-channel-adapter,Inbound Channel Adapter>> for mor [[x5.4-mail]] === Mail Changes -The `AbstractMailReceiver` now can produce `MimeMessage` as is without eager fetching for its content. +The `AbstractMailReceiver` can now produce the `MimeMessage` as-is without eager fetching its content. See <<./mail.adoc#mail-inbound, Mail-receiving Channel Adapter>> for more information.