allthingssecurity opened a new pull request, #27695: URL: https://github.com/apache/camel/pull/27695
# Description [CAMEL-25548](https://issues.apache.org/jira/browse/CAMEL-25548) Since Twitter4J 4.1 a `twitter4j.v1.Query` is immutable: `sinceId`, `maxId`, `lang`, `count` and `geoCode` return a new `Query`. When Camel 4.0.0 moved to Twitter4J 4.1.2 the setters in `SearchConsumerHandler` and `SearchProducer` were renamed, but the returned `Query` was not used, so the query sent to Twitter had only the keywords: - the `twitter-search` consumer ignored `filterOld` (default `true`) and routed the most recent tweets of the search again at every poll (default every 30 seconds); it also ignored `lang`, `count` and the geolocation options; - the producer ignored `sinceId`, `lang`, `count` and the headers `CamelTwitterSinceId`, `CamelTwitterMaxId`, `CamelTwitterSearchLanguage` and `CamelTwitterCount`. This change keeps the `Query` that each call returns, in both classes. It also corrects the blank check of `SearchConsumerHandler.directConsume`, which was inverted in a later cleanup, so that a consumer with `type=direct` returned nothing when keywords were given. The options now work as documented (and as in Camel 3.x). Users can notice it: a poll routes only the tweets newer than the last one consumed, and a page has `count` tweets (default 5, where Twitter's default of 15 applied). The 4.23 upgrade guide has a note that says so and suggests raising `count` and `numberOfPages` for a search that matches more tweets between two polls. This PR also fixes the double request of the timeline consumers, in the same module: `AbstractStatusConsumerHandler.pollConsume` (home, mentions, user and list timelines) called `doPoll()`, which is the request to Twitter, twice in every poll. The tweets of the first response were routed, and the second response was only used for the id of the last tweet (the `since_id` of the next poll). So every poll sent two requests where one is enough, and a tweet posted between the two requests was only in the second response and was skipped. Now a poll sends one request and takes the last id from the tweets it routes. There is no upgrade guide note for this part: the consumer routes the same tweets with half the requests. Tests: - New `TwitterSearchQueryOptionsTest`, without network: a mocked `Twitter` client is set on the endpoint (`TwitterConfiguration.setTwitter`); its search records the query and returns the tweets with an id above `since_id` and up to `max_id`. The consumer is created with `startScheduler=false` and polled directly. - On main five of its six tests fail, for example `The second poll must not route the same tweets again ==> expected: <[10, 11]> but was: <[10, 11, 10, 11]>` and `expected: <[11, 12]> but was: <[10, 11, 12, 13]>` for the producer headers. The sixth (`filterOld=false` polls the tweets again) passes on main too. - New `TwitterTimelinePollTest`, same setup (mocked client whose home timeline returns the tweets above `since_id`): one test counts the requests of a poll, the other posts a tweet right after the first request has been answered and expects the next poll to route it. On main both fail: `A poll must send one request to the timeline ==> expected: <1> but was: <2>` and `expected: <[10, 11]> but was: <[10]>`. - With the change: camel-twitter 14 unit tests, 0 failures. The integration tests need Twitter credentials and were not run. - `mockito-junit-jupiter` is added as a test dependency of camel-twitter; both new tests use it. Not changed here: in the producer `filterOld` is still overridden by `sinceId` (default 1), as in Camel 3.x; and `numberOfPages` of the timeline endpoints is passed to `Paging.ofPage`, so a value above 1 requests that page only (the default of 1 is not affected). Found with a search for calls whose result is dropped on immutable types and a small Lean 4 model of the poll: on main a second poll with no new tweet routes all the tweets again, for every list of tweets; with the fix it routes nothing, and a poll routes exactly the tweets above the last id. I then reproduced it with the consumer and the producer. # 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-twitter, 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]
