allthingssecurity opened a new pull request, #27923: URL: https://github.com/apache/camel/pull/27923
# Description [CAMEL-25684](https://issues.apache.org/jira/browse/CAMEL-25684) `SlackConsumer.createExchanges` moved the timestamp to the most recent message of the poll before `processBatch` routes the messages. `processBatch` stops when `isBatchAllowed()` is false, which `ScheduledBatchPollingConsumer` returns when the route is being suspended (`RouteController.suspendRoute`, also from a route policy that suspends the route through the route controller, such as `DurationRoutePolicy`, or `CamelContext.suspend()`, which resumes the same consumer). The rest of that poll was then never routed: after the resume the same consumer asks Slack only for messages after the timestamp. Nothing is logged. With the defaults the most recent message is routed first, so the older messages of the poll were lost: the rest of that poll, which since CAMEL-25523 can be several pages of `maxResults` (default 10) messages each. This is the shape that CAMEL-25570 fixed for aws2-ddbstream. A consumer suspended directly (`consumer.suspend()`, as `ScheduledRoutePolicy` and the throttl ing route policies do) does not end the batch and is not affected; a route that is stopped and started gets a new consumer and is not affected either. This change: - keeps the messages that were not routed and routes them with the next poll, together with the messages posted in the meantime, in the order of the endpoint (`naturalOrder`). The timestamp cannot stay before them as in the ddbstream fix: by default the most recent message is routed first, so a timestamp before the messages that were not routed would route the ones that were routed again; - as in the ddbstream fix, gives the exchanges of those messages back to the exchange factory, and makes `processBatch` return the number of exchanges it routed (used by `sendEmptyMessageWhenIdle` and greedy polling) instead of the number it was given; - sets the timestamp in `poll()` instead of `createExchanges` (same value). Returning the routed count means that a suspend that arrives before the first message of a poll is routed gives 0; with `sendEmptyMessageWhenIdle=true` the scheduled poll consumer then routes an empty exchange while the route is suspending (`processEmptyMessage` does not check `isPollAllowed()`). The early return of the paging path already behaves this way; a guard in `ScheduledPollConsumer` would be a core follow-up. The kept messages are in memory only: a route that is stopped and started again does not route them. Upgrade guide: an entry in the 4.24 guide, next to the github2 entry of the same kind. Tests: - New `SlackConsumerSuspendedBatchTest` (4 tests): a real route against a small local HTTP server that answers `conversations.history` as Slack does (messages after `oldest`, most recent first). The processor of one message suspends the route from another thread and waits until the batch has ended; then the route is resumed. The fourth test suspends and resumes the whole `CamelContext` instead of the route. Without the change all 4 fail: `expected: <[m5, m4, m3, m2]> but was: <[m5, m4]>`, in natural order `expected: <[m2, m3, m4, m5]> but was: <[m2, m3]>`, with a message posted while suspended `expected: <[m5, m6, m4, m3, m2]> but was: <[m5, m6]>`, and for the context suspend `expected: <[m5, m4, m3, m2]> but was: <[m5, m4]>`. - New `SlackConsumerSuspendedBatchPooledExchangeTest`: the same 4 tests with the pooled exchange factory, plus one that checks the factory statistics: the exchanges of the messages that were not routed are given back to the pool, once (`created + acquired == released`, nothing discarded). Without the change all 5 fail (`exchanges given back to the pool ==> expected: <5> but was: <3>` for the statistics test). - camel-slack unit tests with the change, built together with the current core modules: 19 run, 0 failures, 1 skipped (as on main). # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [ ] 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). (The ticket is drafted and not filed yet; CAMEL-25684 is a placeholder until it is.) # 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 the affected module, including the formatter and import-sort plugins. 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]
