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

Claus Ibsen resolved CAMEL-25543.
---------------------------------
    Resolution: Fixed

Fixed by https://github.com/apache/camel/pull/27691 (merged to main as 
03deff1be5d0, 4.24.0).

_Claude Code on behalf of Claus Ibsen_

> camel-dapr - the saveBulk and executeTransaction state operations never send 
> their request to Dapr, so nothing is stored and the exchange completes 
> without an error
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25543
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25543
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-dapr
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> {{DaprClient}} returns a Reactor {{Mono}} for every request, and the request 
> is sent when the {{Mono}} is subscribed to. {{DaprStateHandler}} (at main 
> 9432ba16d026) blocks on it for {{save}} (line 78), {{get}}, {{getBulk}} and 
> {{delete}} (line 135), but drops it for the two other operations:
> {code:java}
> private DaprOperationResponse saveBulkState(Exchange exchange, DaprClient 
> client) {
>     ...
>     client.saveBulkState(stateRequest);              // line 90: the Mono is 
> never subscribed to
>     return DaprOperationResponse.create(stateRequest);
> }
> private DaprOperationResponse executeStateTransaction(Exchange exchange, 
> DaprClient client) {
>     ...
>     client.executeStateTransaction(stateRequest);    // line 149: the same
>     return DaprOperationResponse.create(stateRequest);
> }
> {code}
> So {{dapr:state?stateOperation=saveBulk}} and 
> {{dapr:state?stateOperation=executeTransaction}} do nothing: no request 
> reaches the sidecar, no state is stored, updated or deleted, and the exchange 
> completes successfully with the request object as the body. Nothing is 
> logged. The component documentation describes both operations ("Store or 
> update multiple key-value pairs in the state store in a single operation", 
> "Execute a batch of operations (save or delete) atomically within a 
> transaction").
> A probe with the real Dapr client and no sidecar shows the behaviour of the 
> {{Mono}}: {{client.saveBulkState(request)}} returns without an error, and 
> {{block()}} on the same {{Mono}} fails with {{DaprException: UNAVAILABLE: io 
> exception}}.
> h3. Reproduction
> Four new tests in {{DaprStateTest}} (mocked {{DaprClient}} as in the existing 
> tests; the mocked {{Mono}} stores the states or operations of the request 
> when it is subscribed to, or fails). On main, twice:
> {noformat}
> testSaveBulkSendsTheStates:               expected: <[StateKeyValue{key='k1', 
> ...}, StateKeyValue{key='k2', ...}]> but was: <[]>
> testSaveBulkFailure:                      Expected 
> java.lang.IllegalStateException to be thrown, but nothing was thrown.
> testExecuteTransactionSendsTheOperations: expected: 
> <[TransactionalStateOperation{operationType='UPSERT', ...}]> but was: <[]>
> testExecuteTransactionFailure:            Expected 
> java.lang.IllegalStateException to be thrown, but nothing was thrown.
> {noformat}
> The existing {{testSaveBulk}} and {{testExecuteTransaction}} return 
> {{Mono.empty()}} and only check the response object, so they do not notice it.
> h3. Proposed fix
> {{saveBulkState}} and {{executeStateTransaction}} block on the {{Mono}}, as 
> the other four state operations do. The request is sent, and a request that 
> Dapr rejects (or a sidecar that cannot be reached) fails the exchange. 4.23 
> upgrade guide note added next to the existing camel-dapr note. camel-dapr 
> with the fix: 64 tests, 0 failures.
> Found with a search for calls on asynchronous clients whose result is 
> dropped, and a small Lean 4 model of the handler (the store as key/value 
> pairs, a Mono as a deferred function that may fail): main is proved to leave 
> the store unchanged and to report success for every request, so it is wrong 
> whenever the request would change the store or would be rejected; the fix is 
> proved equal to "apply the operations or fail the exchange". Confirmed with 
> the real handler, and the laziness of the Mono with the real client.
> Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same two lines, 
> GitHub contents API); the component was added in 4.12.
> Duplicate check (2026-10-11): JIRA text "dapr" with "saveBulk", 
> "executeTransaction" or "state" (1: CAMEL-23630, header filter); GitHub open 
> pull requests for camel-dapr: none. No open pull request changes 
> {{DaprStateHandler}}.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to