allthingssecurity opened a new pull request, #27320: URL: https://github.com/apache/camel/pull/27320
# Description [CAMEL-25288](https://issues.apache.org/jira/browse/CAMEL-25288) The `client` / `previewClient` options are autowired, so one `DaprClient` / `DaprPreviewClient` bean (for example from the Dapr Spring Boot starter) is shared by every dapr endpoint. The consumers closed clients they do not own when they stopped: - `DaprPubSubConsumer` closed a configured or autowired `previewClient`: every other dapr endpoint using it broke, and the route could not subscribe again after a restart (the new consumer gets the same closed client). - `DaprConfigurationConsumer` closed `endpoint.getClient()` (the shared client, or the one the endpoint created for its producers and consumers). Its `unsubscribeConfiguration` Mono was never subscribed (a no-op) and its `Flux` subscription was never disposed. `DaprConfigurationConsumer` also took `endpoint.getClient()` in its constructor, but a route creates its consumer before it starts the endpoint, which creates or takes the client in `doStart`. So in a route the consumer failed to start with `NullPointerException ... because "this.client" is null` (the unit test used a mocked endpoint with the client already set). This change follows the ownership rule of the other components (for example the AWS endpoints close only the clients they created): - `DaprPubSubConsumer` closes only a preview client that it created (none configured), and forgets it so that a restart creates a new one. - `DaprConfigurationConsumer` takes the endpoint's client in `doStart`, records the subscription id from every response, and on stop disposes its subscription and unsubscribes (`block` up to 10 seconds, a failure is logged as WARN), without closing the client. Both are needed with Dapr Java SDK 1.18.1: its `Flux` does not cancel the gRPC stream on dispose, so the explicit `unsubscribeConfiguration` ends the subscription at the sidecar (which logs that this call is deprecated in favour of disconnecting). - `DaprEndpoint` closes the `DaprClient`, `DaprPreviewClient` and `DaprWorkflowClient` that it created in `doStart` when it stops (as `Sqs2Endpoint` does), never configured or autowired ones; a restart creates new ones. Before, nothing closed them (the configuration consumer closed the endpoint's `DaprClient` only when it could start at all, i.e. in a route added to a running context). Points a reviewer may question: - No upgrade note: Camel no longer closes a client it does not own; the owner (Spring, the application) closes it. - The pub/sub listener lines are untouched; this merges cleanly with #27303 (CAMEL-25274). Tests: - `DaprConsumerSharedClientTest` (new, `CamelTestSupport`, mocked clients autowired from the registry): restarting the pub/sub route must not close the preview client and must subscribe again; the configuration route must start, and stopping it must dispose the subscription, unsubscribe with the subscription id and not close the client, and it must consume again after a restart. - Without the change: `NeverWantedButInvoked: daprPreviewClient.close()` and `FailedToStartRoute ... "this.client" is null`; with only the client taken in `doStart`, the configuration test fails because the subscription is not ended (`expected: <true> but was: <false>`). - `DaprPubSubConsumerTest` / `DaprConfigurationConsumerTest` asserted `close()` on the configured / endpoint client; they now assert it is not closed (and the unsubscribe with `mySubId`). - `DaprEndpointClientOwnershipTest` (new): the endpoint closes the clients it created (Mockito `mockConstruction`) and not the configured ones, which it uses again after a restart. Without the endpoint change: `Wanted but not invoked: daprClient.close()`. - With the change all camel-dapr unit tests pass: 56 tests, 0 failures. # 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 module, 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]
