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

   # Description
   
   [CAMEL-25841](https://issues.apache.org/jira/browse/CAMEL-25841)
   
   `XmppComponent` kept the endpoints it created in a map keyed by scheme, 
host, port and query, and returned the cached endpoint for any URI with the 
same key. The participant (the path) and the user are not part of the key, so 
`xmpp://alice@host/bob@host?password=x` and 
`xmpp://alice@host/carol@host?password=x` were the same endpoint: messages for 
carol went to bob. Two users on the same server shared an endpoint too, so 
messages went out from the first user's account. This happens with static 
endpoints in two routes as well as with toD.
   
   Separate endpoints alone are not enough: each endpoint opened its own 
connection, and the endpoints of one account (`xmpp://bot@host/alice`, 
`xmpp://bot@host/bob`) log in with the same JID and the same resource (`Camel` 
by default). An XMPP server keeps one session per account and resource and 
closes the older one with a `conflict` stream error, and Smack 4.4.8's 
`ReconnectionManager` does not reconnect after `conflict`, so the usual "one 
account, several participants" setup would lose an endpoint for good. A 
distinct resource per endpoint is not a fix either: a message to the bare JID 
goes to one resource only.
   
   Changes:
   - `XmppComponent`: remove the endpoint cache. The component creates a new 
endpoint for each URI, like other components. The CamelContext already reuses 
the endpoint of the same URI and stops the endpoints it holds.
   - `XmppComponent`: keep one connection per account instead, keyed by the 
settings that make up the connection (host, port, service name, user, password, 
resource, login, connection configuration), shared by the consumers and 
producers of all endpoints of that account, and closed when the last of them 
stops (and at component stop). As before, a connection that is no longer 
connected is replaced by a new one when a consumer or producer starts.
   - `XmppEndpoint.acquireConnection(user)` / `releaseConnection(user)`: what 
the consumers and producers now use instead of `createConnection()`, which only 
creates a new connection. Each endpoint keeps its own participant, room, 
nickname and other settings.
   - `XmppConsumer` and the producers release the connection when they stop 
instead of disconnecting it (it may serve other endpoints). The consumer also 
removes its listeners from the connection, so a restarted consumer does not 
receive each message twice. The direct and pubsub producers now release their 
connection on stop too (before, only the endpoint's stop closed it).
   
   The connection of an account is still closed when its last route stops, as 
before for a single endpoint. No option or default changes.
   
   Tests:
   - New `XmppComponentEndpointPerUriTest` (3 tests, no XMPP server needed). 
`endpointPerParticipant` and `endpointPerUser` fail without the change 
(`expected: <carol@localhost> but was: <bob@localhost>`, `expected: <dave> but 
was: <alice>`). `sameUriSameEndpoint` passes before and after.
   - New `XmppSharedConnectionTest` (3 tests) with `FakeXmppServer`, a small 
in-process XMPP server (plain TCP, SASL PLAIN and ANONYMOUS, resource binding, 
room presence) that, like a real server, closes the older session with a 
`conflict` stream error when another session binds the same JID and resource. 
The real Smack client connects to it.
     - `endpointsOfOneAccountShareItsConnection`: two endpoints of `bot` with 
participants alice and carol each send to their own participant over one 
session. On main carol's message goes to alice (`expected: <[hello alice]> but 
was: <[hello alice, hello carol]>`); with a connection per endpoint, the second 
login closes the first session (`expected: <[hello alice]> but was: <[]>`).
     - `stoppingOneEndpointKeepsTheConnectionOfTheOther`: stopping and removing 
alice's endpoint keeps the session for carol's; the session is closed when the 
last route of the account stops. With a connection per endpoint it fails (`The 
account logged in more than once ==> expected: <1> but was: <2>`).
     - `consumerRestartedOnASharedConnectionReceivesEachMessageOnce`: a 
consumer restarted while a producer keeps the connection receives each message 
once (without removing its listener on stop: `expected: <2> but was: <3>`).
   - camel-xmpp unit tests with the change: 15 run, 0 failures, 5 skipped (the 
tests that need an XMPP server container). The integration tests were not run.
   
   Unchanged: a consumer receives every chat message of its account, whatever 
its participant, as before; a group chat producer and a consumer of the same 
room on one account share Smack's `MultiUserChat` of that room, as they did 
before when they used the same endpoint.
   
   How it was found: a sweep for components that keep endpoints or clients in 
their own maps, then the test above.
   
   # 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-25841](https://issues.apache.org/jira/browse/CAMEL-25841).
   
   # 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-xmpp. No option or generated metadata 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