shashank created CAMEL-25844:
--------------------------------
Summary: camel-dapr - the configuration consumer never subscribes
again after its stream to the sidecar ends, and receives no further
configuration change
Key: CAMEL-25844
URL: https://issues.apache.org/jira/browse/CAMEL-25844
Project: Camel
Issue Type: Bug
Components: camel-dapr
Reporter: shashank
Assignee: shashank
{{DaprConfigurationConsumer}} (main 20cdb309f7d0, {{doStart}}) subscribes once
to the {{Flux}} returned by {{DaprClient.subscribeConfiguration}}:
{code:java}
Flux<SubscribeConfigurationResponse> responses =
client.subscribeConfiguration(configRequest);
subscription = responses.subscribe((response) -> { ... });
{code}
The {{Flux}} is one server-streaming gRPC call to the Dapr sidecar. It ends
with an error when that call fails (the sidecar restarts, which is routine in
Kubernetes, or the connection to it drops), or completes when the sidecar ends
the call. The Dapr Java SDK does not open the call again:
{{DaprClientImpl.createFlux}} applies the client's {{RetryPolicy}}, and
{{dapr.api.maxRetries}} is 0 by default (SDK 1.18.1, read with javap). The
consumer passes no error or completion handler, so Reactor logs the error once
as dropped ({{onErrorDropped}}), and a completion is not logged at all. From
then on the consumer stays started, the route reports as started, and no
further configuration change is delivered until the route is restarted. The
pub/sub consumer of the same component does not have this problem: the SDK's
{{Subscription}} opens its stream again after an error.
*Fix*: the consumer subscribes again when the stream fails or completes, after
one second and then with a growing delay of up to 30 seconds while the sidecar
cannot be reached (Reactor
{{retryWhen(Retry.backoff(...).transientErrors(true))}} and {{repeatWhen}} over
a deferred {{subscribeConfiguration}}), for as long as it runs, with a WARN
each time. Stopping the consumer still disposes the subscription and
unsubscribes the current subscription id. The component page says that a change
made while the consumer is not subscribed is not delivered (the first response
of a new subscription carries no items).
*Tests*: two new tests in {{DaprConfigurationConsumerTest}} (mocked
{{DaprClient}}, as the existing test).
{{testConfigurationConsumerSubscribesAgainWhenTheStreamFails}}: the first
stream sends its subscription response and then fails, the next one carries an
update. It fails on main ({{Wanted 2 times ... But was 1 time}}:
{{subscribeConfiguration}} is never called again) and passes with the fix,
where the update is routed and the consumer unsubscribes the new subscription
id when it stops.
{{testConfigurationConsumerSubscribesAgainWhenTheStreamCompletes}}: the same
with a stream that completes; fails on main ({{Wanted but not invoked}}: no
exchange), passes with the fix. camel-dapr unit tests with the fix: 66 run, 0
failures.
*How it was found*: variant analysis of CAMEL-25843 (pattern: a library
subscription that ends on a recoverable condition while Camel never notices, so
the consumer stays started and receives nothing), then the JUnit tests. Not run
against a real sidecar.
*Affected*: main, camel-4.23.x, camel-4.18.x and camel-4.14.x (the same single
subscribe without error handling; read, not run).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)