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

   # Description
   
   [CAMEL-25122](https://issues.apache.org/jira/browse/CAMEL-25122)
   
   camel-sjms still has the bug that CAMEL-24073 fixed in camel-jms: when the 
send of an InOut message fails, the request timeout completes the exchange a 
second time.
   
   `SjmsProducer.processInOut` registers the reply handler in the correlation 
map inside `MessageCreator.createMessage`, before the message is sent. When the 
send fails, the producer sets the exception and calls `callback.done(true)`, 
but the handler stays registered. When the request timeout expires, 
`ReplyManagerSupport.processReply` completes the same exchange again: it 
replaces the exception with an `ExchangeTimedOutException` and calls 
`callback.done(false)`. The sjms `ReplyManager` has no way to cancel a pending 
reply.
   
   The other way around is also possible, as in CAMEL-25095 for camel-jms: a 
send that blocks longer than `requestTimeout` and then fails (the timeout 
completes the exchange first), or a request that is delivered and answered 
before the send reports a failure (the reply completes it first). In both cases 
the send failure then completes the exchange a second time.
   
   This change, as in camel-jms:
   - `ReplyManager` gets `boolean cancelCorrelationId(String correlationId)`, 
implemented by `ReplyManagerSupport`: it removes the pending reply and returns 
whether it was still pending.
   - `processInOut` keeps the correlation id that `registerReply` returned. 
When the send fails, it cancels it. If it was still pending, the exchange fails 
with the send failure as before, and the timeout no longer fires. If the 
request timeout or the reply has already removed it, they complete the 
exchange, so the send failure is only logged at WARN and `processInOut` returns 
without completing the exchange. A failure before the reply was registered 
fails the exchange as before.
   - Upgrade guide note for 4.23: the outcome of a late send failure, and the 
new `ReplyManager` method (a custom `ReplyManager` has to implement it).
   
   camel-sjms2 uses the camel-sjms producer and gets the fix too.
   
   Tests:
   - New `InOutSendFailureCallbackTest` (camel-sjms, embedded Artemis). The 
connection factory is wrapped in dynamic proxies so that 
`MessageProducer.send()` to a given queue fails; no Camel code is changed for 
the test. `requestTimeoutCheckerInterval=50`. Each test counts the on 
completions of the exchange and checks the inflight count is 0 at the end.
     - The send fails at once (`requestTimeout=500`): the exchange fails with 
the send failure, which stays unchanged for 1.5 s, and the on completion runs 
`onFailure` once.
     - The send blocks until the request timeout (100 ms) has completed the 
exchange, then fails: the exchange fails with the `ExchangeTimedOutException`, 
`onFailure` once.
     - The request is sent and answered, then the send fails: the exchange has 
the reply, `onComplete` once.
   - Without the change, all 3 fail: the first one's exception is replaced by 
`ExchangeTimedOutException` after 500 ms, and the other two return the send 
failure instead of the timeout or the reply that completed the exchange.
   - With the change: camel-sjms, all tests: 126 tests, 0 failures, 0 errors, 5 
skipped.
   
   This merges cleanly with main.
   
   Found in a review of CAMEL-25095 (camel-jms), which noted that camel-sjms 
has the code from before CAMEL-24073. I confirmed it with the test above before 
changing anything.
   
   # 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 the affected modules, 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