[ 
https://issues.apache.org/jira/browse/CAMEL-25808?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25808.
---------------------------------
    Resolution: Fixed

> camel-mail - after the IMAP folder connection dropped during a poll, the 
> consumer marks (or deletes) another mail than the one it routed
> ----------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25808
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25808
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-mail
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> {{MailConsumer.processCommit}} (main 7aae27315946, lines 520-589) marks a 
> mail once its exchange completed: it opens the folder again if it is closed, 
> then sets SEEN or DELETED (and copies / moves the mail for {{copyTo}} / 
> {{moveTo}}) on the mail object of the poll:
> {code:java}
> // ensure folder is open
> if (!folder.isOpen()) {
>     folder.open(Folder.READ_WRITE);
> }
> ...
> mail.setFlag(Flags.Flag.SEEN, true);   // or DELETED, after 
> folder.copyMessages(new Message[] { mail }, dest)
> {code}
> The folder is closed at that point when its IMAP connection dropped while the 
> mail was routed (an idle timeout of the server during a long exchange, a 
> network failure): angus-mail cleans the folder up when it notices that, and 
> {{isOpen()}} returns false. The mail object belongs to the earlier open. An 
> angus-mail {{IMAPMessage}} sends its commands with {{getSequenceNumber()}}, 
> which looks its message number up in the message cache of the *current* open 
> of its folder ({{folder.messageCache.seqnumOf(msgnum)}}); the new open builds 
> that cache from the mailbox as it is now. When mails were expunged between 
> the two opens (another mail client, a second Camel consumer on the same 
> mailbox with a shared {{idempotentRepository}} closing its folder, or a 
> server that expunges a deleted mail at once), the number designates another 
> mail:
> * the mail that was routed is not marked: it stays unread and is routed again 
> (a duplicate);
> * another mail is marked instead. With the default {{unseen=true}} a mail 
> marked SEEN is never polled again, so if it was not routed yet (for example a 
> mail after the {{maxMessagesPerPoll}} limit) it is never consumed. With 
> {{delete=true}} or {{moveTo}} it is deleted (moved) without being routed. 
> Nothing is logged.
> *Reproduction* ({{MailConsumerFolderReopenedTest}}, GreenMail and the real 
> angus-mail client, as the other tests of the module): three mails, 
> {{maxMessagesPerPoll=2}}, the consumer connects through a small TCP proxy. 
> While the second mail is routed, another client removes the first one 
> (already consumed) and the proxy drops the consumer's connections. On main 
> the commit of the second mail marks the third mail SEEN: the mock receives 
> "Message 0", "Message 1", "Message 1" and never "Message 2" ({{Message with 
> body Message 2 was expected but not found in [Message 1]}}, 2 of 2 runs).
> *Fix*: {{MailConsumer}} fetches the UIDs of the mails of a poll when it 
> retrieves them (one FETCH), and counts the opens of the folder. When the 
> folder was opened again after the mails of the batch were retrieved, the mail 
> to mark is looked up by its UID (same UIDVALIDITY); when it is no longer 
> there, nothing is marked (WARN). The batch is not routed further once the 
> folder was opened again (the other mail objects are stale too, and with 
> {{mapMailMessage=false}} their content would be read from other mails); those 
> mails are given back as for a batch cut short by a stop (CAMEL-25710) and 
> consumed by the next poll. POP3 is not changed: {{processCommit}} already 
> finds a POP3 mail again by its key (see CAMEL-24434 for that key).
> *Tests*: the new test fails on main and passes with the fix. camel-mail unit 
> tests with the fix: 246 run, 0 failures, 0 errors, 4 skipped.
> *How it was found*: deterministic simulation testing with a fake IMAP world 
> (camel-test-dst, CAMEL-25738): the real {{MailConsumer}}, a fake IMAP server 
> and client that follows RFC 3501 and the angus-mail message cache behaviour 
> above, seeded connection drops, a second consumer, other clients that expunge 
> and a server that expunges at once. Invariant: no mail is marked SEEN or 
> DELETED, or copied, before its exchange completed. 384 of 5000 seeds failed 
> on main, first failing seed 4 (a failing seed replays with the same trace 
> hash); 0 of 5000 with the fix. The world re-finds CAMEL-25710 when that fix 
> is reverted. Then the JUnit test above with the real client.
> *Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x (the same 
> {{processCommit}}; read, not run). Not run against a real IMAP server other 
> than GreenMail.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to