[
https://issues.apache.org/jira/browse/CAMEL-26896?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-26896 started by Andrea Cosentino.
------------------------------------------------
> camel-openfga - preserve relationship condition on tuple write and read
> -----------------------------------------------------------------------
>
> Key: CAMEL-26896
> URL: https://issues.apache.org/jira/browse/CAMEL-26896
> Project: Camel
> Issue Type: Improvement
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
> Fix For: 4.24.0
>
>
> h3. Background
> {{camel-openfga}} lets a Camel route manage relationship tuples in an OpenFGA
> store through {{OpenFgaProducer}}. A relationship tuple has a {{user}}, a
> {{relation}} and an {{object}}. The OpenFGA SDK type {{ClientTupleKey}} can
> additionally carry a *relationship condition*: a condition name plus an
> optional context that OpenFGA evaluates to decide when the relationship
> holds. The SDK models this by having {{ClientTupleKey}} extend
> {{ClientTupleKeyWithoutCondition}}, with {{getCondition()}} present only on
> the {{ClientTupleKey}} subtype. On the read side the server returns the
> condition on {{dev.openfga.sdk.api.model.TupleKey}} via {{getCondition()}}.
> h3. Current behaviour
> On the write path {{OpenFgaProducer}} funnels every input through a private
> three-field holder {{Tuple}} that keeps only {{user}}, {{relation}} and
> {{object}}:
> * {{toTuple(Object)}} matches the input against the
> {{ClientTupleKeyWithoutCondition}} supertype, so a {{ClientTupleKey}} that
> carries a condition still matches, and only {{getUser()}}, {{getRelation()}}
> and {{getObject()}} are read. The condition is never looked at.
> * The {{Map}} branch of {{toTuple}} reads only the {{user}}, {{relation}} and
> {{object}} keys. A {{condition}} key on the map is ignored.
> * {{writeTuples}} then rebuilds a new {{ClientTupleKey}} from the three
> surviving fields ({{new
> ClientTupleKey().user(..).relation(..)._object(..)}}), with no
> {{.condition(..)}} call.
> The result is that when a route passes {{writeTuples}} a tuple that includes
> a relationship condition, the component writes an unconditioned tuple
> instead, and the caller gets no error and no sign that the condition was not
> applied.
> The read path drops the same information. {{readTuples}} projects each tuple
> into a {{Map}} of {{user}}, {{relation}}, {{object}} and {{timestamp}}.
> {{readChanges}} projects each change into a {{Map}} of {{user}},
> {{relation}}, {{object}}, {{operation}} and {{timestamp}}. Neither includes
> the condition that the server returned on the {{TupleKey}}, so a route cannot
> read it back or round-trip it.
> For reference, {{deleteTuples}} intentionally uses
> {{ClientTupleKeyWithoutCondition}}, because OpenFGA deletes by identity and a
> condition is not part of a delete key. That path is correct and should stay
> unchanged.
> h3. Proposed behaviour
> Carry the relationship condition through faithfully on both paths:
> * Capture the condition in {{toTuple}} when the input is a
> {{ClientTupleKey}}, and define explicit handling for a {{condition}} key (a
> map of {{name}} and {{context}}) in the {{Map}} branch.
> * Extend the internal {{Tuple}} holder with an optional condition, and have
> {{writeTuples}} set {{.condition(..)}} on the outgoing {{ClientTupleKey}}
> when one is present. An unconditioned input still produces an unconditioned
> write.
> * In {{readTuples}} and {{readChanges}}, add a {{condition}} entry to each
> result {{Map}} when the server-returned {{TupleKey}} carries one, projected
> as a map of {{name}} and {{context}} (mirroring how {{operation}} is
> projected as a {{String}} rather than an SDK enum).
> * Keep {{deleteTuples}} identity-only, and keep the existing rule that an
> endpoint-configured tuple wins over the message body.
> h3. Classes and files
> *
> {{components/camel-openfga/src/main/java/org/apache/camel/component/openfga/OpenFgaProducer.java}}:
> {{toTuple}}, {{writeTuples}}, {{readTuples}}, {{readChanges}} and the
> private {{Tuple}} holder.
> * {{components/camel-openfga/src/main/docs/openfga-component.adoc}}: document
> the condition on write and the new {{condition}} key in read and change
> results, then regenerate and commit the catalog doc mirror under
> {{catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/}}.
> * {{docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc}}: a
> short note that {{writeTuples}} now honours a relationship condition on a
> {{ClientTupleKey}} or {{Map}} input, and that {{readTuples}} and
> {{readChanges}} now include a {{condition}} key when present.
> h3. Tests
> A new package-private test class (for example {{OpenFgaTupleConditionTest}})
> covering:
> * {{writeTuples}} preserves a condition on a single {{ClientTupleKey}};
> * {{writeTuples}} preserves conditions across a collection of tuples;
> * {{writeTuples}} with a {{Map}} {{condition}} key preserves it;
> * an unconditioned write stays unconditioned (control);
> * {{deleteTuples}} stays identity-only (regression guard);
> * {{readTuples}} projects a server-returned condition;
> * {{readChanges}} projects a server-returned condition.
> Follow the module's existing assertion style (AssertJ is already a test
> dependency here) and do not use {{Thread.sleep}}.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)