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 abe4a275cd..c91fb69270 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,7 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; import org.springframework.util.MimeTypeUtils; +import org.springframework.util.ObjectUtils; /** * Base class for {@link MailReceiver} implementations. @@ -362,6 +363,7 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl public Object[] receive() throws jakarta.mail.MessagingException { this.folderReadLock.lock(); // NOSONAR - guarded with the getReadHoldCount() try { + Object[] messagesToReturn = null; try { Folder folderToCheck = getFolder(); if (folderToCheck == null || !folderToCheck.isOpen()) { @@ -375,10 +377,11 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl this.folderWriteLock.unlock(); } } - return convertMessagesIfNecessary(searchAndFilterMessages()); + messagesToReturn = convertMessagesIfNecessary(searchAndFilterMessages()); + return messagesToReturn; } finally { - if (this.autoCloseFolder) { + if (this.autoCloseFolder || ObjectUtils.isEmpty(messagesToReturn)) { closeFolder(); } } diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/MailReceiverTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/MailReceiverTests.java index d74cb4f4fe..41b9544e14 100644 --- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/MailReceiverTests.java +++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/MailReceiverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2021 the original author or authors. + * Copyright 2014-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.integration.mail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -46,12 +48,12 @@ import org.springframework.beans.DirectFieldAccessor; public class MailReceiverTests { @Test - public void testStoreConnect() throws Exception { + public void testStoreConnectAndFolderCloseWhenNoMessages() throws Exception { AbstractMailReceiver receiver = new AbstractMailReceiver() { @Override protected Message[] searchForNewMessages() { - return null; + return new Message[0]; } }; @@ -59,18 +61,24 @@ public class MailReceiverTests { Session session = Session.getInstance(props); receiver.setSession(session); receiver.setProtocol("imap"); + receiver.setAutoCloseFolder(false); Store store = session.getStore("imap"); store = spy(store); new DirectFieldAccessor(receiver).setPropertyValue("store", store); when(store.isConnected()).thenReturn(false); Folder folder = mock(Folder.class); when(folder.exists()).thenReturn(true); - when(folder.isOpen()).thenReturn(false); + when(folder.isOpen()).thenReturn(false, true); doReturn(folder).when(store).getFolder((URLName) null); doNothing().when(store).connect(); receiver.openFolder(); receiver.openFolder(); verify(store, times(2)).connect(); + + Object[] receive = receiver.receive(); + assertThat(receive).isEmpty(); + + verify(folder).close(anyBoolean()); } } diff --git a/src/reference/asciidoc/mail.adoc b/src/reference/asciidoc/mail.adoc index 24fdab51bd..00da0a77a1 100644 --- a/src/reference/asciidoc/mail.adoc +++ b/src/reference/asciidoc/mail.adoc @@ -140,6 +140,9 @@ This functionality is enabled with this combination of options: no `headerMapper The `MimeMessage` is present as the payload of the Spring message produced. In this case, the only header populated is the mentioned above `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` for the folder which must be closed when processing of the `MimeMessage` is complete. +Starting with version 5.5.11, the folder is closed automatically after `AbstractMailReceiver.receive()` if no messages received or all of them are filtered out independently of the `autoCloseFolder` flag. +In this case there is nothing to produce downstream for possible logic around `IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE` header. + [[mail-mapping]] === Inbound Mail Message Mapping