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

   # Description
   
   [CAMEL-25883](https://issues.apache.org/jira/browse/CAMEL-25883)
   
   The `raftHandle` option of the JGroups Raft component is given to every 
endpoint of the component, but each `JGroupsRaftEndpoint` counted only its own 
producers and consumers: when those of one endpoint stopped, it disconnected 
the channel of the shared handle, so the node left the Raft cluster, and when 
the endpoint itself stopped (for example when its route was removed) it closed 
the channel and the Raft log. A route consuming from another endpoint of the 
same cluster (such as `jgroups-raft:orders?enableRoleChangeEvents=true` next to 
a producer to `jgroups-raft:orders`) then stayed started on a handle that was 
no longer connected; after the close, for good. Nothing was logged at WARN or 
ERROR.
   
   This is the same pattern, and the same fix, as CAMEL-25852 for the `channel` 
option of camel-jgroups.
   
   Changes:
   - `JGroupsRaftComponent` counts the producers and consumers of a handle that 
the endpoints did not create (`connectSharedHandle` / `disconnectSharedHandle`) 
and disconnects its channel when the last of them stops.
   - `JGroupsRaftEndpoint` closes only a handle it created (from 
`channelProperties` or the default). The `raftHandle` of the component is 
closed when the component stops (before, by the first endpoint that stopped). A 
handle given to one endpoint (`raftHandle=#bean` on the endpoint URI) is not 
created by the endpoint either: it is counted the same way and closed when the 
component stops. A handle an endpoint creates itself is handled as before.
   - `JGroupsRaftProducer` and `JGroupsRaftConsumer` disconnect only when they 
connected (as CAMEL-25852's camel-jgroups producer and consumer): Camel also 
stops a route whose consumer never started (`autoStartup(false)`, then 
`stopRoute` or `removeRoute`), and its `doStop` took away a use it never added, 
so the shared handle was disconnected under a running producer of another 
endpoint.
   - `JGroupsRaftComponent.doStop` closes the channel and the log of each 
handle in its own try (WARN on failure), so a failure to close one handle does 
not leave the others open.
   - The comments in `resolveHandle` said the channel the endpoint creates is 
closed by the component; it is closed by the endpoint, and they now say so.
   
   No option changed; the handles are still closed at shutdown, so no upgrade 
guide entry.
   
   Tests:
   - New `JGroupsRaftComponentHandleEndpointsTest` (component `raftHandle` on a 
single member cluster, a producer route to `jgroups-raft:<cluster>` and a 
consumer route from `jgroups-raft:<cluster>?enableRoleChangeEvents=true`, which 
share the handle): `stoppingTheProducerKeepsTheHandleConnected` fails without 
the change with `the consumer route still uses the handle ==> expected: <true> 
but was: <false>` (the channel was disconnected), and 
`removingTheProducerRouteKeepsTheHandleOpen` fails with `the consumer route 
still uses the handle ==> expected: <false> but was: <true>` (the channel was 
closed). With the change both pass, and the handle still commits a `set()` 
after the producer route stopped or was removed.
   - `stoppingTheCamelContextClosesTheHandles` is a control: it passes before 
and after the change and checks that the component handle and a handle given to 
an endpoint (`raftHandle=#endpointHandle`) are still closed when the 
CamelContext stops (now by the component).
   - New `JGroupsRaftNeverStartedConsumerTest` (found in review): a producer 
route and a consumer route with `autoStartup(false)` on the component handle; 
stopping and then removing the never started route must keep the handle 
connected. Without the connected flags it fails with `after stopRoute of the 
never started route ==> expected: <true> but was: <false>`; with them it passes.
   - camel-jgroups-raft unit tests with the change: 19 run, 0 failures.
   
   How it was found: variant analysis of CAMEL-25852 during the review of its 
pull request, then the JUnit test.
   
   What was not run: the full root build.
   
   # 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): 
[CAMEL-25883](https://issues.apache.org/jira/browse/CAMEL-25883).
   
   # 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-jgroups-raft. No option changed. 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