allthingssecurity opened a new pull request, #27694:
URL: https://github.com/apache/camel/pull/27694

   # Description
   
   [CAMEL-25546](https://issues.apache.org/jira/browse/CAMEL-25546)
   
   `WhatsAppProducer.process` is asynchronous and returns `false`; the exchange 
is completed by `WhatsAppServiceRestAPIAdapter`, which sent the request with 
`HttpClient.sendAsync` and handled the result with `thenAccept(response -> { 
... finally { callback.done(false); } })`. `thenAccept` only runs for a 
response. When the request failed without one (connection refused or reset, DNS 
failure, the 10 second connect timeout), the future completed exceptionally, 
the function was skipped and the callback was never called. The exchange was 
never completed: a caller waiting for it blocked forever, the exchange stayed 
in flight, and a graceful shutdown waited for its timeout.
   
   Now the result is handled with `whenComplete`: a failure without a response 
fails the exchange with that exception (for example 
`java.net.ConnectException`) and the callback is called. The handling of a 
response is unchanged; the two `throw` statements that followed 
`exchange.setException` are removed, since nothing observed them.
   
   The response handling also caught only `JsonProcessingException`; any other 
exception thrown there was lost in the future, and the exchange completed as a 
success. It now catches `Exception` and sets it on the exchange. The callback 
is called once, in the `finally` of the one `whenComplete` function. I found no 
way to make the response handling throw something other than a 
`JsonProcessingException` from a test, so this catch has no test of its own.
   
   Known follow-up, not fixed here: there is no request timeout. The 
`HttpClient` has a connect timeout of 10 seconds, but the `HttpRequest` has no 
`timeout(...)`, so a server that accepts the connection and never answers still 
leaves the exchange waiting forever. That needs a new option (or a default) and 
I can do it separately.
   
   There is no upgrade guide note, because the only change is that an exchange 
that waited forever now fails.
   
   Tests:
   - New `WhatsAppProducerFailureTest`: with `baseUri` pointing to a local port 
nothing listens on, an asynchronous send must complete within 30 seconds with 
an `IOException` on the exchange. Without the change the test fails with a 
`TimeoutException`.
   - Only `failsTheExchangeWhenTheConnectionFails` fails on main. The other two 
tests of the class, `failsTheExchangeForAnErrorResponse` (a 400 from a local 
HTTP server fails the exchange with the status and the body) and 
`returnsTheResponse` (a 200 returns a `MessageResponse`), pass on main too; 
they cover the response handling that the change restructures and do not show 
the bug.
   - With the change: camel-whatsapp 11 tests, 0 failures. `WhatsAppServiceIT` 
needs a WhatsApp account and was not run.
   
   Found by a review of producers that complete an exchange from a 
`CompletableFuture`, with a small TLA+ model (send, outcome, callback): on main 
TLC reports a deadlock when the request fails without a response; with the fix 
every behaviour completes the exchange. I then reproduced it with 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-whatsapp, 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]

Reply via email to