[ 
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)

Reply via email to