[ 
https://issues.apache.org/jira/browse/CAMEL-25883?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

shashank updated CAMEL-25883:
-----------------------------
    Description: 
The {{raftHandle}} option of the JGroups Raft component (a {{RaftHandle}} with 
its {{JChannel}}, Raft log and state machine) is given to every endpoint the 
component creates ({{JGroupsRaftComponent.createEndpoint}}). Each 
{{JGroupsRaftEndpoint}} (main 20cdb309f7d0) counts only its own producers and 
consumers in {{connectCount}}, and closes the channel and the Raft log when it 
stops:

{code:java}
public void disconnect() {
    if (connectCount.decrementAndGet() == 0) {
        resolvedRaftHandle.channel().disconnect();
    }
}

protected void doStop() throws Exception {
    if (resolvedRaftHandle != null && resolvedRaftHandle.channel() != null) {
        resolvedRaftHandle.channel().close();
    }
    if (resolvedRaftHandle != null && resolvedRaftHandle.log() != null) {
        resolvedRaftHandle.log().close();
    }
    ...
{code}

With the component {{raftHandle}}, two endpoints of the same cluster that 
differ in their options (for example a producer to {{jgroups-raft:orders}} and 
a consumer from {{jgroups-raft:orders?enableRoleChangeEvents=true}}) share the 
handle but not the count. When the producer route stops, its endpoint 
disconnects the shared channel, so the node leaves the Raft cluster while the 
consumer route stays started. When the producer route is removed, its endpoint 
is stopped and closes the channel and the Raft log of the shared handle, and 
the other endpoints cannot use the handle again. Nothing is logged at WARN or 
ERROR.

This is the same pattern as CAMEL-25852 (camel-jgroups, the {{channel}} option 
of the component); it was left out of that fix to keep it to one component.

*Fix*: as in CAMEL-25852, the component counts the producers and consumers of a 
handle that the endpoints did not create (the component {{raftHandle}}, or a 
handle given to one endpoint with {{raftHandle=#bean}}) and disconnects its 
channel when the last of them stops; an endpoint closes only a handle it 
created itself (from {{channelProperties}} or the default), and the component 
closes the other handles when it stops. A handle an endpoint creates itself is 
unchanged.

*How it was found*: variant analysis of CAMEL-25852 during the review of its 
pull request, reading {{JGroupsRaftEndpoint}} and {{JGroupsRaftComponent}}, 
then a JUnit test ({{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}}). On main, after 
stopping the producer route the shared channel is no longer connected ({{the 
consumer route still uses the handle ==> expected: <true> but was: <false>}}), 
and after removing the producer route it is closed ({{the consumer route still 
uses the handle ==> expected: <false> but was: <true>}}).

*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
(the same per-endpoint {{connectCount}} and {{close}} in {{doStop}}; read, not 
run).

_Filed with Claude Code on behalf of allthingssecurity._


  was:
The {{raftHandle}} option of the JGroups Raft component (a {{RaftHandle}} with 
its {{JChannel}}, Raft log and state machine) is given to every endpoint the 
component creates ({{JGroupsRaftComponent.createEndpoint}}). Each 
{{JGroupsRaftEndpoint}} (main 20cdb309f7d0) counts only its own producers and 
consumers in {{connectCount}}, and closes the channel and the Raft log when it 
stops:

{code:java}
public void disconnect() {
    if (connectCount.decrementAndGet() == 0) {
        resolvedRaftHandle.channel().disconnect();
    }
}

protected void doStop() throws Exception {
    if (resolvedRaftHandle != null && resolvedRaftHandle.channel() != null) {
        resolvedRaftHandle.channel().close();
    }
    if (resolvedRaftHandle != null && resolvedRaftHandle.log() != null) {
        resolvedRaftHandle.log().close();
    }
    ...
{code}

With the component {{raftHandle}}, two endpoints of the same cluster that 
differ in their options (for example a producer to {{jgroups-raft:orders}} and 
a consumer from {{jgroups-raft:orders?enableRoleChangeEvents=true}}) share the 
handle but not the count. When the producer route stops, its endpoint 
disconnects the shared channel, so the node leaves the Raft cluster while the 
consumer route stays started. When the producer route is removed, its endpoint 
is stopped and closes the channel and the Raft log of the shared handle, and 
the other endpoints cannot use the handle again. Nothing is logged at WARN or 
ERROR.

This is the same pattern as CAMEL-25852 (camel-jgroups, the {{channel}} option 
of the component); it was left out of that fix to keep it to one component.

*Fix (to follow in a pull request)*: as in CAMEL-25852, the component counts 
the producers and consumers of a handle that the endpoints did not create (the 
component {{raftHandle}}) and disconnects its channel when the last of them 
stops; an endpoint closes only a handle it created itself (from 
{{channelProperties}} or the default), and the component closes its handle when 
it stops. A handle an endpoint creates itself is unchanged.

*How it was found*: variant analysis of CAMEL-25852 during the review of its 
pull request, reading {{JGroupsRaftEndpoint}} and {{JGroupsRaftComponent}}. A 
JUnit test that shows it will come with the pull request.

*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
(the same per-endpoint {{connectCount}} and {{close}} in {{doStop}}; read, not 
run).

_Filed with Claude Code on behalf of allthingssecurity._



> camel-jgroups-raft - with the raftHandle option of the component, an endpoint 
> whose producer stops, or whose route is removed, disconnects or closes the 
> RaftHandle under the other endpoints
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25883
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25883
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-jgroups
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> The {{raftHandle}} option of the JGroups Raft component (a {{RaftHandle}} 
> with its {{JChannel}}, Raft log and state machine) is given to every endpoint 
> the component creates ({{JGroupsRaftComponent.createEndpoint}}). Each 
> {{JGroupsRaftEndpoint}} (main 20cdb309f7d0) counts only its own producers and 
> consumers in {{connectCount}}, and closes the channel and the Raft log when 
> it stops:
> {code:java}
> public void disconnect() {
>     if (connectCount.decrementAndGet() == 0) {
>         resolvedRaftHandle.channel().disconnect();
>     }
> }
> protected void doStop() throws Exception {
>     if (resolvedRaftHandle != null && resolvedRaftHandle.channel() != null) {
>         resolvedRaftHandle.channel().close();
>     }
>     if (resolvedRaftHandle != null && resolvedRaftHandle.log() != null) {
>         resolvedRaftHandle.log().close();
>     }
>     ...
> {code}
> With the component {{raftHandle}}, two endpoints of the same cluster that 
> differ in their options (for example a producer to {{jgroups-raft:orders}} 
> and a consumer from {{jgroups-raft:orders?enableRoleChangeEvents=true}}) 
> share the handle but not the count. When the producer route stops, its 
> endpoint disconnects the shared channel, so the node leaves the Raft cluster 
> while the consumer route stays started. When the producer route is removed, 
> its endpoint is stopped and closes the channel and the Raft log of the shared 
> handle, and the other endpoints cannot use the handle again. Nothing is 
> logged at WARN or ERROR.
> This is the same pattern as CAMEL-25852 (camel-jgroups, the {{channel}} 
> option of the component); it was left out of that fix to keep it to one 
> component.
> *Fix*: as in CAMEL-25852, the component counts the producers and consumers of 
> a handle that the endpoints did not create (the component {{raftHandle}}, or 
> a handle given to one endpoint with {{raftHandle=#bean}}) and disconnects its 
> channel when the last of them stops; an endpoint closes only a handle it 
> created itself (from {{channelProperties}} or the default), and the component 
> closes the other handles when it stops. A handle an endpoint creates itself 
> is unchanged.
> *How it was found*: variant analysis of CAMEL-25852 during the review of its 
> pull request, reading {{JGroupsRaftEndpoint}} and {{JGroupsRaftComponent}}, 
> then a JUnit test ({{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}}). On main, after 
> stopping the producer route the shared channel is no longer connected ({{the 
> consumer route still uses the handle ==> expected: <true> but was: 
> <false>}}), and after removing the producer route it is closed ({{the 
> consumer route still uses the handle ==> expected: <false> but was: <true>}}).
> *Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
> (the same per-endpoint {{connectCount}} and {{close}} in {{doStop}}; read, 
> not run).
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to