Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

It has been noted that the json content for read and write requests in CPS-Core is inconsistent

DescriptionResponse for getDataNode root nodeResponse for getDataNode non root node body when writing (root) DataNode
OperationGETGETPOST/PUT
xPath//bookstore/categories[@code='01']/

Response

/Body

{
   "bookstore-name":"Chapters",
   "categories":[ ... ]
}


{
    "code": "01",
    "name": "SciFi",
     ...

}

{
   "bookstore":{
     "bookstore-name":"Chapters",
      "categories":[ ... ]
  }
}

NotesThe response includes the 'value' of the bookstore node ie. the leaves and children<= Same the body needs to include the whole container object.


Solution

#SolutionsIssues
1
Obtain the  container from the xpath of the queried node. Node xpath will be
Use the parent node xpath in order to wrap the queried leaves. eg query xpath = /bookstore/categories[@code='01']
where bookstore is the container name given in the module info.
=> categoriesThis should be reasonably straightforward as the
top level
node is named after the container name given by the module yang file
.2Create a query to obtain the schema node directly from the database using and propagate through persistence and service layers.Would need to create a new query which would parse the json data from the yang_resource content and find the container name which is very memory intensive for its use case. Also would need to pass a new schema node object to the toDataMap method which would not be used every time which it is called
.


For the JSON output of Get DataNode we need to alter the DataMapUtils class. The function toDataMap translates a datanode object to a JSON output. We only want this to occur on the parent node and as such we can create a new method which is called before toDataMap:


public static Map<String, Object> toDataMaptoDataMapParentNode(final DataNode dataNode) {
final booleanString isTopLevelNodenodeName = dataNode.getXpath().lastIndexOf('/') == 0;
if (isTopLevelNode) {
String containerName = substring(dataNode.getXpath().substringlastIndexOf(1'/');
return ImmutableMap.<String, Object>builder().put(containerName,
+ 1)
ImmutableMap.<String, Object>builder()
.putAll(dataNode.getLeaves())
.putAll(listElementsAsMap(dataNode.getChildDataNodes()))
.putAll(containerElementsAsMap(dataNode.getChildDataNodes()))
.build()
).build();
} else {
.replaceAll("\\[.*?\\]", "");
return ImmutableMap.<String, Object>builder()
.putAll(dataNode.getLeaves()).put(nodeName,
.putAll(listElementsAsMap(dataNode.getChildDataNodes()))
toDataMap(dataNode)
.putAll(containerElementsAsMap(dataNode.getChildDataNodes()))
.build();
}}

We only want the container name on the top highest parent level of the JSON output and as such have to distinguish between a top parent level node and non top parent level node. We create an outer map to wrap the inner map which creates the appropriate levels in the JSON output. 

This produces the following response in the Post Request output:

DescriptionResponse for getDataNode root nodeResponse for getDataNode non root nodeResponse for queryDataNode root nodeResponse for queryDataNode non root node
OperationGETGETGETGET
xPath/

...

/bookstore/categories[@code='01']/bookstore/bookstore/categories[@code='01']

Response

/Body

{
    "bookstore": {
        "bookstore-name": "Easons",
        "categories":

...

[...]

    }

}

{
    "categories": {
        "code": "01",

...

        "name": "SciFi"

...

,
        "books": [...] 

     }

}

{
    "bookstore": {
        "bookstore-name": "Easons",
        "categories": [...]

    }

}

{
    "categories": {
        "code": "01",
        "name": "SciFi",
        "books": [...] 

     }

}

NotesResponse includes the container bookstoreThe response includes the list categoriesResponse includes the container bookstoreThe response includes the list categories

Tests would need to be updated to accept the new JSON output which is returned. Examples would need to be updated in openapi

Backwards Compatibility 

Queries which use toDataMap:


Effected ComponentsEffected ClientsQuery/ServiceClassNotesResponse nowResponse AfterDecision
1CPS CoreCPS TBDMTGet Data Node (as above)DataRestController.javaThis change is given in the example above. The JSON output for Get Node will be updated.

{
   "bookstore-name":"Chapters",
   "categories":[ ... ]
}

{
   "bookstore":{
     "bookstore-name":"Chapters",
      "categories":[ ... ]
  }
}
Don't update version, check with tbdmt about impact of new JSON output for getNode/queryNode.
2CPS CoreCPS TemporalNotification ServiceCpsDataUpdatedEventFactory.javaNotification Service response should be the same as CPS Core for consistency. CPS Temporal

cpsDataUpdatedEvent Object content.data.additionalProperties.toString():

[[bookstore-name:Chapters]]


cpsDataUpdatedEvent Object content.data.additionalProperties.toString():

[bookstore:[bookstore-name:Chapters]]

CPS Temporal only recording and not processing this data. Therefore change (response after) is OK
3CPS CoreCPS TBDMTQuery data nodesQueryRestController.java

Query DataNodes will produce a datanode within an array with the container ID

and then the relevant data:

http://localhost:8883/cps/api/v1/dataspaces/test/anchors/bookstore-anchor-test2/nodes/query?cps-path=/bookstore/categories[@code='01']&include-descendants=true

[

     {

        "code": "01",
        "name": "SciFi",
        "books": [
            ...
        ]
    }
]

[

     "categories": {

        "code": "01",
        "name": "SciFi",
        "books": [
            ...
        ]
    }
]

Don't update version, check with tbdmt about impact of new JSON output for getNode/queryNode.
4CPS CoreNoneget Node by CMHandle and Xpath (NCMP)NetworkCmProxyController.javaThis method is deprecated and is no longer used as part of NCMP.


Backwards Incompatibility:


Keep versionNew versionNew endpoints
Action

Keep the current version of the interface and alert effected client TBDMT of the changes.

Release version 2 of the interface with changes while retaining v1 endpoints and output.Create new endpoints and deprecate the old endpoints sometime in the future. Keep the endpoints for get and query which we currently have and release new endpoints that have container context.
Preference/Impact

Current preferred option as long as TBDMT agree. 

Impacts TBDMT.

Would need its own spike to analyze the impact. CPS Temporal would need the context of if request is coming from v1 or v2 for notification service.A lot of duplicated code which will need to be depracated in the future. CPS Temporal would need the context of if request is coming from new or old endpoints.