GH-3356: Add the way to not load mail message (#3402)

* 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`

* Fix language in Docs

Co-authored-by: Gary Russell <grussell@vmware.com>

Co-authored-by: Gary Russell <grussell@vmware.com>
This commit is contained in:
Artem Bilan
2020-10-12 17:36:22 -04:00
committed by GitHub
parent cadd4e6b7f
commit 3e501905e3
4 changed files with 24 additions and 10 deletions

View File

@@ -502,8 +502,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl
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;

View File

@@ -33,9 +33,8 @@ import javax.mail.search.FlagTerm;
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.MessageHandler;
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 class MailTests {
.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")

View File

@@ -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.
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
@@ -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` 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

View File

@@ -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` can now produce the `MimeMessage` as-is without eager fetching its content.
See <<./mail.adoc#mail-inbound, Mail-receiving Channel Adapter>> for more information.