...
# | Issue | Notes | Decision |
---|---|---|---|
1 | Add or Delete leaves handle as UPDATE or ADD/DELETE? | The delta report proposed follows the Json Patch format of representing the differences between 2 JSON data. Apart from this the delta is dependent on individual data nodes of the JSON data, this is because the delta report will contain the action, xpath and the source/target data. And since the xpaths are unique to data nodes and not leaf data, every delta entity in delta report will be between 2 data nodes. Going by the general convention and referring RFC-6902:
| Updated as per notes. |
2 | How to handle multiple changes at different levels? | Since the delta report will contain the xpaths of data nodes changed, so for changes at multiple levels i.e., parent and child data nodes, the approach will be to handle each data node individually and report them in the delta report. | |
3 | More scenarios need to be explored and documented in detail. Such as handling arrays within a json, handling child/grandchild changes. | scenarios such as data nodes at multiple levels, arrays and lists are covered. |
...
# | Sub Interface | Method | Scenario | HTTP Response codes to be implemented | Notes |
---|---|---|---|---|---|
1 | Data | Proposed API: GET-/v2/dataspaces/{dataspace-name}/anchors/{source-anchor-name}/delta?anchor2target-anchor-name={target-anchor-name}?xpath={xpath}&descendants={descendants} Proposed method name: getDeltaByDataspaceAndAnchors() | Generate a delta report between 2 anchors in a given dataspace. |
| AnchorNotFoundException should provide the name of missing anchor from the given two anchor names. |
...
Code Block | ||||
---|---|---|---|---|
| ||||
[ { "action": "ADDcreate", "xpath": "/bookstore/categories/[@code=3]", "target-data": { "code": 3, "name": "kidz" } }, { "action": "REMOVEremove", "xpath": "/bookstore/categories/[@code=1]", "source-data": { "code": 1, "name": "Fiction" } }, { "action": "UPDATEreplace", "xpath": "/bookstore/categories/[@code=2]", "source-data": { "name": "Funny" }, "target-data": { "name": "Comic" } } ] |
Mechanism for Delta generation between Anchors
Gliffy | |||||||
---|---|---|---|---|---|---|---|
|
...
|
Additional Details
Format/Conventions to be used for Delta Report
The delta report format is based on two RFCs namely RFC 6902 and RFC 9144 . A detailed comparison of the RFCs can be found here.
RFC 6902 JSON Patch
JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JavaScript Object Notation(JSON) document; it is suitable for use with the HTTP PATCH method.
...
Operation | Description | Delta report equivalent |
---|---|---|
add | Adds the value at the target location; if the value exists in the given location, it’s replaced | if the value is not present in the source json, but was found in the comparand target json, then it should be considered an a "addcreate" action. |
remove | Removes the value at the target location | if a value was present at the source json, but was not found in the comparand target json, then it should be considered as "deleteremove" action. |
replace | Replaces the value at the target location | if a value is present in the source json, but an updated value is present in the comparand target json, then it will be considered as "updatereplace" action. |
move | Removes the value at a specified location and adds it to the target location | N/A |
copy | Copies the value at a specified location to the target location | N/A |
test | Tests that a value at the target location is equal to a specified value | N/A |
...
The format of Delta report has following key take aways from the above-mentioned RFCs:
- The "op" field from RFC 6902 is replaced with "action" field because in CPS we want to report the action that was performed on the data. And this field can have 3 predefined values: ADDcreate, REMOVE remove and UPDATEreplace.
- The xpath is used in CPS to uniquely identify individual data nodes and is used in place of JSON path as defined in the two RFCs
- The source-data and target-data fields are used from RFC9144 to report the data that has been added, removed or updated. This approach properly categorizes the data instead of grouping it under the one "value" field as in RFC6902.
Code Block | ||||
---|---|---|---|---|
| ||||
[ { "action": "ADDcreate", "xpath": "/bookstore/categories/[@code=3]", "target-data": { "code": "3,", "name": "kidz" } }, { "action": "REMOVEremove", "xpath": "/bookstore/categories/[@code=1]", "source-data": { "code": "1,", "name": "Fiction" } }, { "action": "UPDATEreplace", "xpath": "/bookstore/categories/[@code=2]", "source-data": { "name": "Funny" }, "target-data": { "name": "Comic" } } ] |
...
- Create an empty JSON Array, to store the result
- The JSON array will contain the following: action, xpath, payload as individual JSON objects each object representing a singular operation.
- Fetch the data from two anchors and store in two separate Maps
- Iterate over the entries of first map
- For each entry of first map, check if the key is present in second map.
- If the key is not found in second map, it means that the key-value pair has been removed from the second map. Create a JSON Object with DELETE 'remove' action, the xpath to deleted node and payload. Add the Object to the JSON Array.
- If the key is present in the second map, compare the values associated with the keys in both maps.
- If the values are instance of Map, recursively call the comparision algorithm to compare all nested maps. Add all the necessary fields into a JSON object and put the object into the JSON Array
- If the values are not equal, it means the key-value pair was updated. Create a JSON Object with UPDATE 'replace' action, the xpath to updated nodes and payload. Add the Object to the JSON Array.
- Iterate over the keys of second map and find the keys not present in first map. These keys were added as new entries. Create a JSON Object with ADD 'create' action, the xpath to added node and payload. Add the Object to the JSON Array.
- Return the JSON Array and the updates to Kafka events