oscerd commented on code in PR #27195:
URL: https://github.com/apache/camel/pull/27195#discussion_r4155852412
##########
components/camel-openfga/src/main/docs/openfga-component.adoc:
##########
@@ -320,12 +320,68 @@ No check is registered for an injected `openFgaClient`,
which can point anywhere
about. Set `healthCheckProducerEnabled=false` on the component, or
`healthCheckEnabled=false` on the policy, to
turn them off.
+=== Reading the graph
+
+`readTuples` answers "what access exists", as opposed to `check`'s "may this
subject do this". Here `user`, `relation`
+and `object` are a *filter* rather than a subject, and the body comes back as
a list of maps keyed `user`, `relation`,
+`object` and `timestamp` — deliberately the keys `writeTuples` and
`deleteTuples` accept, so a route can revoke what
+it just read without reshaping anything:
+
+[source,java]
+------------------------------------------------------------
+from("direct:revokeEverythingBobHas")
+
.to("openfga:readTuples?storeId={{fga.store}}&object=document:&user=user:bob")
+ .to("openfga:deleteTuples?storeId={{fga.store}}");
+------------------------------------------------------------
+
+[NOTE]
+.What OpenFGA accepts as a read filter
+====
+The filter is narrower than "every part is optional". Measured against OpenFGA
1.21.0:
+
+* no filter at all — reads the whole store, a page at a time;
+* `object=document:` *plus* a `user` — reads that user's tuples of that object
type;
+* `object=document:budget` — reads that object's tuples, with or without a
user or relation;
+* `user` alone, `relation` alone, or `object=document:` alone — **rejected**,
because OpenFGA requires an object type
+ as soon as any filter is given and will not accept an empty object id and an
empty user together.
+
+The component checks this before the call and names the option to change,
rather than letting an opaque HTTP 400
+through. Note this is also why a type-only `document:` is accepted here but
not as an `object` anywhere else: a read
+filter and an identifier have different rules.
+====
+
+`readChanges` reads the change log, which is the building block for keeping a
cache or a projection in step with the
+graph. Each entry adds an `operation` of `WRITE` or `DELETE`.
+
+Both are paged. `pageSize` bounds one request, and the token the page returns
arrives on
+`CamelOpenFgaContinuationToken`; feed it back through `continuationToken` for
the next page:
+
+[source,java]
+------------------------------------------------------------
+from("timer:sync?period=30000")
+ .to("openfga:readChanges?storeId={{fga.store}}&type=document"
+ + "&continuationToken=${exchangeProperty.fgaToken}")
+ .setProperty("fgaToken", header("CamelOpenFgaContinuationToken"))
+ .split(body()).to("direct:applyChange");
+------------------------------------------------------------
+
+The header is *removed* rather than left in place on the last page, so a route
looping on it stops instead of
Review Comment:
Agreed, and split by operation as you suggested. The sentence is now an
IMPORTANT block that states the asymmetry explicitly instead of giving one rule
that only holds for one of the two operations:
- `readTuples` returns no token on its last page, so the header really is
absent and looping until it disappears is the right way to drain it.
- `readChanges` returns a token every time, empty page included, so that
loop would never end. The signal is an empty body, and the token it keeps
handing back is the bookmark for the next poll.
Both bullets are labelled as measured against OpenFGA 1.21.0, with the probe
output in my reply on the `OpenFgaConstants` thread, so the next person to read
this does not have to re-derive it — and so a change in server behaviour has a
stated version to be compared against rather than an unattributed claim.
_Claude Code on behalf of oscerd_
--
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]