allthingssecurity opened a new pull request, #27671: URL: https://github.com/apache/camel/pull/27671
# Description [CAMEL-25520](https://issues.apache.org/jira/browse/CAMEL-25520) The `google-mail-stream` consumer hands each exchange to the route with an empty callback and does not wait; the message is marked as read (`markAsRead`, the default) by the exchange's on completion. With an asynchronous route (`seda`, which hands the on completion over, kafka or another async producer, `threads()`), the next poll lists the still unread message again (the default query is `is:unread`) and routes it a second time. If one of the duplicates fails, its rollback adds the UNREAD label back, so a message that was already processed successfully is consumed once more. This is the defect fixed for aws2-s3 in CAMEL-17110. The consumer now keeps the ids of the messages whose exchanges are in progress: a poll skips them, and an id is released when its exchange completes or fails (after marking the message read or unread), or when the poll does not process it (get failure, consumer stopping). No new option: a plain set in the consumer, not cleared on route stop (in-flight ids are released when their exchanges complete). With `markAsRead=false` a message is now consumed again only after its previous exchange completed; 4.23 upgrade-guide note. Tests (`FakeGmailClientFactory`: a Gmail client whose `MockHttpTransport` answers from an in-memory mailbox, no network): - `GoogleMailStreamConsumerInProgressTest.messageInFlightIsNotConsumedAgain`: the seda route holds the exchange until the consumer has completed a second poll (counted with a `pollStrategy`). Without the change: `m1 was consumed again by a later poll while its first exchange was still in flight ==> expected: <1> but was: <2>`. - `failedMessageIsConsumedAgain`: a message whose exchange failed is consumed again and then marked as read; `messageIsConsumedAfterAFailedGet`: the get of the first poll fails (status 500) and a later poll consumes the message; `notProcessedMessageIsConsumedAgain`: a message whose exchange a stopping consumer did not process is not left in progress. All three pass without the change too (there is no in-progress set on main); they guard the releases on failure, on a failed get and on stop. - With the change, the camel-google-mail unit tests pass (48). Found with a TLA+ model of the poll and the asynchronous completion: "a message is routed again only after an exchange for it failed" is violated in 10 steps (poll, get, dispatch, poll again, get, dispatch again). I then reproduced it with the real consumer. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built and tested camel-google-mail, including the formatter and import-sort plugins; the build did not change any generated file. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. This PR was prepared with Claude Code (Claude Opus 5.5). The commit carries a `Co-Authored-By` trailer. _Claude Code on behalf of allthingssecurity_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
