Skip to content

Commit 87b78c6

Browse files
committed
Flag and maybe delete messages after messages have been copied
1 parent 6b42758 commit 87b78c6

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

Diff for: spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -503,17 +503,26 @@ private Object byteArrayToContent(Map<String, Object> headers, ByteArrayOutputSt
503503
}
504504

505505
private void postProcessFilteredMessages(Message[] filteredMessages) throws MessagingException {
506-
setMessageFlags(filteredMessages);
507-
508-
if (shouldDeleteMessages()) {
509-
deleteMessages(filteredMessages);
510-
}
511506
// Copy messages to cause an eager fetch
512507
if (this.headerMapper == null && (this.autoCloseFolder || this.simpleContent)) {
508+
Message[] originalMessages = new Message[filteredMessages.length];
513509
for (int i = 0; i < filteredMessages.length; i++) {
514-
MimeMessage mimeMessage = new IntegrationMimeMessage((MimeMessage) filteredMessages[i]);
510+
Message originalMessage = filteredMessages[i];
511+
originalMessages[i] = originalMessage;
512+
MimeMessage mimeMessage = new IntegrationMimeMessage((MimeMessage) originalMessage);
515513
filteredMessages[i] = mimeMessage;
516514
}
515+
setMessageFlagsAndMaybeDeleteMessages(originalMessages);
516+
} else {
517+
setMessageFlagsAndMaybeDeleteMessages(filteredMessages);
518+
}
519+
}
520+
521+
private void setMessageFlagsAndMaybeDeleteMessages(Message[] messages) throws MessagingException {
522+
setMessageFlags(messages);
523+
524+
if (shouldDeleteMessages()) {
525+
deleteMessages(messages);
517526
}
518527
}
519528

Diff for: spring-integration-mail/src/test/java/org/springframework/integration/mail/ImapMailReceiverTests.java

+50-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.integration.mail;
1818

1919
import java.io.IOException;
20+
import java.io.OutputStream;
2021
import java.lang.reflect.Field;
2122
import java.util.ArrayList;
2223
import java.util.Arrays;
@@ -88,6 +89,7 @@
8889
import org.springframework.util.MimeTypeUtils;
8990

9091
import static org.assertj.core.api.Assertions.assertThat;
92+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
9193
import static org.mockito.ArgumentMatchers.any;
9294
import static org.mockito.ArgumentMatchers.anyString;
9395
import static org.mockito.BDDMockito.given;
@@ -299,6 +301,11 @@ public void receiveAndMarkAsReadDontDelete() throws Exception {
299301

300302
private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1,
301303
Message msg2) throws NoSuchFieldException, IllegalAccessException, MessagingException {
304+
return receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, true);
305+
}
306+
307+
private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1,
308+
Message msg2, boolean receive) throws NoSuchFieldException, IllegalAccessException, MessagingException {
302309

303310
((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(true);
304311
receiver = spy(receiver);
@@ -326,7 +333,9 @@ private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailRece
326333
willAnswer(invocation -> messages).given(folder).search(any(SearchTerm.class));
327334

328335
willAnswer(invocation -> null).given(receiver).fetchMessages(messages);
329-
receiver.receive();
336+
if (receive) {
337+
receiver.receive();
338+
}
330339
return receiver;
331340
}
332341

@@ -980,6 +989,28 @@ private void setUpScheduler(ImapMailReceiver mailReceiver, ThreadPoolTaskSchedul
980989
mailReceiver.setBeanFactory(bf);
981990
}
982991

992+
@Test
993+
public void receiveAndMarkAsReadDontDeleteWithThrowingWhenCopying() throws Exception {
994+
AbstractMailReceiver receiver = new ImapMailReceiver();
995+
MimeMessage msg1 = GreenMailUtil.newMimeMessage("test1");
996+
MimeMessage greenMailMsg2 = GreenMailUtil.newMimeMessage("test2");
997+
TestThrowingMimeMessage msg2 = new TestThrowingMimeMessage(greenMailMsg2, 1);
998+
receiver = receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, false);
999+
assertThatThrownBy(receiver::receive)
1000+
.isInstanceOf(MessagingException.class)
1001+
.hasMessage("IOException while copying message")
1002+
.cause()
1003+
.isInstanceOf(IOException.class)
1004+
.hasMessage("Simulated exception");
1005+
assertThat(msg1.getFlags().contains(Flag.SEEN)).isFalse();
1006+
assertThat(msg2.getFlags().contains(Flag.SEEN)).isFalse();
1007+
1008+
receiver.receive();
1009+
assertThat(msg1.getFlags().contains(Flag.SEEN)).isTrue();
1010+
assertThat(msg2.getFlags().contains(Flag.SEEN)).isTrue();
1011+
verify(receiver, times(0)).deleteMessages(Mockito.any());
1012+
}
1013+
9831014
private static class ImapSearchLoggingHandler extends Handler {
9841015

9851016
private final List<String> searches = new ArrayList<>();
@@ -1015,4 +1046,22 @@ public void close() throws SecurityException {
10151046

10161047
}
10171048

1049+
private static class TestThrowingMimeMessage extends MimeMessage {
1050+
1051+
protected final AtomicInteger exceptionsBeforeWrite;
1052+
1053+
public TestThrowingMimeMessage(MimeMessage source, int exceptionsBeforeWrite) throws MessagingException {
1054+
super(source);
1055+
this.exceptionsBeforeWrite = new AtomicInteger(exceptionsBeforeWrite);
1056+
}
1057+
1058+
@Override
1059+
public void writeTo(OutputStream os) throws IOException, MessagingException {
1060+
if (this.exceptionsBeforeWrite.decrementAndGet() >= 0) {
1061+
throw new IOException("Simulated exception");
1062+
}
1063+
super.writeTo(os);
1064+
}
1065+
}
1066+
10181067
}

0 commit comments

Comments
 (0)