Andrea Cosentino created CAMEL-26408:
----------------------------------------

             Summary: camel-openfga - batchCheck applies the single-request 
await timeout to the whole fan-out
                 Key: CAMEL-26408
                 URL: https://issues.apache.org/jira/browse/CAMEL-26408
             Project: Camel
          Issue Type: Bug
            Reporter: Andrea Cosentino


Found during a camel-openfga quality review (reading {{main}} on 
4.24.0-SNAPSHOT).

h4. What happens

{{OpenFgaAuthorizer.awaitTimeout()}} 
(components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaAuthorizer.java,
 lines 163-167) computes the per-exchange wait bound as {{(connectTimeout + 
readTimeout) * (maxRetries + 1) + AWAIT_SAFETY_MARGIN_MILLIS}} — about 85s with 
the 10000 / 10000 / 3 defaults. That is the right bound for a single 
{{check()}}: one connect + one request per attempt, across the first attempt 
and every retry, plus a margin.

{{OpenFgaProducer.batchCheck()}} (OpenFgaProducer.java, lines 192-194) hands 
that same {{awaitTimeoutMillis}} to {{authorizer.await(() -> 
client.clientBatchCheck(requests, options))}}. {{clientBatchCheck}} issues one 
check request per object with at most {{maxParallelRequests}} (default 10) in 
flight, i.e. {{ceil(n / maxParallelRequests)}} serialized waves for n objects. 
The whole batch is one future, so {{await}}'s 
{{future.get(awaitTimeoutMillis)}} bounds the *entire* fan-out by a budget 
sized for a *single* request.

h4. Impact

Under high per-check latency (a slow or degraded OpenFGA server) and a large 
body, the batch's wall-clock can exceed the single-request bound; the 
Camel-level {{future.get}} then cancels an in-progress batch and the exchange 
fails with a misleading {{"Timed out after 85000ms ..."}}. It fails *closed* 
({{batchCheck}} has no {{failOpen}} — returning the objects it never managed to 
filter would be the leak the filtering prevents), so this is a robustness / 
diagnostics bug, not a security issue. The default timeouts make it latent: it 
only bites when individual checks are slow and the batch is large.

h4. Proposed fix

Scale the await bound for the batch path by the number of waves — multiply by 
{{ceil(requests.size() / maxParallelRequests)}} when awaiting a 
{{clientBatchCheck}} — so the batch is given the budget its fan-out actually 
needs. At minimum, document that {{batchCheck}}'s effective bound is the 
single-request bound regardless of size, and make the timeout message name the 
knob to raise. Include a unit test (a mocked client whose future completes 
after the single-request bound but within the scaled bound).

Related but distinct: CAMEL-26197 (other {{batchCheck}} bugs in the same 
method).

_Claude Code on behalf of oscerd_



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to