Safely read expunged IMAP messages

If application is connected to a Domino mail server via IMAP, it can happen from time to time that a message is expunged.
This leads to a `MessageRemovedException` when calling `IMAPMessage#getSubject`.
And although debug is set to false this again leads to a `MessageException` and the whole integration flow stops.

* Check for `isExpunged()` before logging a filtered message

* Add `@author`
* Fix debug message for expunged to reflect reality
* Clean up new unit tests a bit

**Cherry-pick to `5.4.x`**
This commit is contained in:
Dominik Simmen
2021-07-23 09:02:29 -04:00
committed by Artem Bilan
parent b12540d2ac
commit c189a125a6
2 changed files with 60 additions and 6 deletions

View File

@@ -28,6 +28,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.lang.reflect.Field;
@@ -100,6 +101,7 @@ import com.sun.mail.imap.IMAPFolder;
* @author Gary Russell
* @author Artem Bilan
* @author Alexander Pinske
* @author Dominik Simmen
*/
@SpringJUnitConfig
@ContextConfiguration(
@@ -336,6 +338,53 @@ public class ImapMailReceiverTests {
verify(receiver, times(0)).deleteMessages(Mockito.any());
}
@Test
public void receiveAndDebugIsDisabledNotLogFiltered() throws Exception {
AbstractMailReceiver receiver = new ImapMailReceiver();
LogAccessor logger = spy(TestUtils.getPropertyValue(receiver, "logger", LogAccessor.class));
new DirectFieldAccessor(receiver).setPropertyValue("logger", logger);
when(logger.isDebugEnabled()).thenReturn(false);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
Expression selectorExpression = new SpelExpressionParser().parseExpression("false");
receiver.setSelectorExpression(selectorExpression);
receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2);
verify(logger, times(2)).isDebugEnabled();
verify(msg1, never()).isExpunged();
verify(msg2, never()).isExpunged();
verify(msg1, never()).getSubject();
verify(msg2, never()).getSubject();
verify(logger, never()).debug(Mockito.startsWith("Expunged message received"));
verify(logger, never()).debug(org.mockito.ArgumentMatchers.contains("will be discarded by the matching filter"));
}
@Test
public void receiveExpungedAndNotExpungedLogFiltered() throws Exception {
AbstractMailReceiver receiver = new ImapMailReceiver();
LogAccessor logger = spy(TestUtils.getPropertyValue(receiver, "logger", LogAccessor.class));
new DirectFieldAccessor(receiver).setPropertyValue("logger", logger);
when(logger.isDebugEnabled()).thenReturn(true);
Message msg1 = mock(MimeMessage.class);
Message msg2 = mock(MimeMessage.class);
given(msg1.isExpunged()).willReturn(true);
given(msg1.getSubject()).willReturn("msg1");
given(msg2.getSubject()).willReturn("msg2");
Expression selectorExpression = new SpelExpressionParser().parseExpression("false");
receiver.setSelectorExpression(selectorExpression);
receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2);
verify(logger, times(2)).isDebugEnabled();
verify(msg1).isExpunged();
verify(msg2).isExpunged();
verify(msg1, never()).getSubject();
verify(msg2).getSubject();
verify(logger).debug(Mockito.startsWith("Expunged message discarded"));
verify(logger).debug(org.mockito.ArgumentMatchers.contains("'msg2' will be discarded by the matching filter"));
}
@Test
public void receiveMarkAsReadAndDelete() throws Exception {