Background
Jira |
---|
server | ONAP Jira |
---|
columnIds | issuekey,summary,issuetype,created,updated,duedate,assignee,reporter,priority,status,resolution |
---|
columns | key,summary,type,created,updated,due,assignee,reporter,priority,status,resolution |
---|
serverId | 425b2b0a-557c-3c0c-b515-579789cceedb |
---|
key | CPS-1381 |
---|
|
Background : we want to include limit/depth/pagination in CPS-Core query APIs where output size is large. it will allow user to limit query outputs.
It was discussed on 11th Nov 2022 in weekly meeting to use 'depth' parameter to limit large outputs.
Implementation
...
Affected URLs
# | 'depthdescendants' query parameter added in below URLs | Notes | Decision |
---|
1 | URL: http://<IP:PORT>/v1v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/node?xpath=/&include-descendants=true&depth=1depth is an optional query parameter or mandatory how to handle include-descendants query parameter? can we remove this parameter and use only depth parameter. depth = -1 is same as include-descendants= true depth values treated as below-1 : all descendants 0 : no descendants1, 2, 3, ... : number or descendants {all | none | number} | descendants is optional query parameter with default value of "all". possible values of descendants is as below : - all : to get all descendants
- none: don't include descendants
- number : positive number 0 to n, to query nodes till nth descendant
| - we need to support different version for this query API for backward compatibility
|
2 | URL: http://<IP:PORT>/v1v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query?cps-path=/&include-descendents=true&depth=1 |
...
descendants={all | none | number} | descendants is optional query parameter with default value of "all". possible values of descendants is as below : - all : to get all descendants
- none: don't include descendants
- number : positive number 0 to n, to query nodes till nth descendant
| - we need to support different version for this query API for backward compatibility
|
Affected Methods
changes files | changes/notes | Decision | |
---|
openapi.yml | /v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/node: $ref: 'cpsDataV2.yml#/nodeByDataspaceAndAnchor'
/v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query: $ref: 'cpsQueryV2.yml#/nodesByDataspaceAndAnchorAndCpsPath' |
cpsDataV2cpsData.yml | nodeByDataspaceAndAnchor: get: description: Get a node with an option to retrieve all the children for a given anchor and dataspace tags: - cps-data summary: Get a node operationId: getNodeByDataspaceAndAnchorV2 parameters: - $ref: 'components.yml#/components/parameters/dataspaceNameInPath' - $ref: 'components.yml#/components/parameters/anchorNameInPath' - $ref: 'components.yml#/components/parameters/xpathInQuery' - $ref: 'components.yml#/components/parameters/ depthInQuerydescendantsInQuery' ... |
cpsQuerycpsQueryV2.yml | nodesByDataspaceAndAnchorAndCpsPath: get: description: Query data nodes for the given dataspace and anchor using CPS path tags: - cps-query summary: Query data nodes operationId: getNodesByDataspaceAndAnchorAndCpsPathV2 parameters: - $ref: 'components.yml#/components/parameters/dataspaceNameInPath' - $ref: 'components.yml#/components/parameters/anchorNameInPath' - $ref: 'components.yml#/components/parameters/cpsPathInQuery' - $ref: 'components.yml#/components/parameters/depthInQuerydescendantsInQuery' ... |
components.yml | depthInQuerydescendantsInQuery: name: depthdescendants in: query description: depthdescendants parameter for large query outputs to limit descendants. use "all", "none" or number required: false schema: type: string default: all example: 1 | FetchDescendantsOption.java | We Need to change this class to accept for any other depth values except -1, 0 and 1. Do we need to change FetchDescendantsOption to support multiple depths or add depth as separate argument along with FetchDescendantsOption | 3 pattern: <use pattern to validate accepted values for descendants> Notes : return error descendants value if less then -1 and invalid string values. |
DataRestController.java | @Override public ResponseEntity<Object> getNodeByDataspaceAndAnchorV2(final String dataspaceName, final String anchorName, final String xpath, final String descendants) { final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantOption(descendants); final DataNode dataNode = cpsDataService.getDataNode(dataspaceName, anchorName, xpath | FragmentRepository.java | @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId," + " CAST(attributes AS TEXT) AS attributes" + " FROM FRAGMENT WHERE anchor_id = :anchorId" + " AND ( xpath = :parentXpath OR xpath LIKE CONCAT(:parentXpath,'/%') )", nativeQuery = true) List<FragmentExtract> findByAnchorIdAndParentXpath(@Param("anchorId") int anchorId, fetchDescendantsOption); final String prefix = prefixResolver.getPrefix(dataspaceName, anchorName, xpath); return new ResponseEntity<>(DataMapUtils.toDataMapWithIdentifier(dataNode, prefix), HttpStatus.OK); } private FetchDescendantsOption getFetchDescendantOption(final String descendants) { if (null == descendants || descendants.trim().isEmpty() @Param("parentXpath") String parentXpath, || "-1".equals(descendants) || "all".equals(descendants)) { return FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; } else if ("0".equals(descendants) || "none".equals(descendants)) { return FetchDescendantsOption.OMIT_DESCENDANTS; } else { final Integer depth = Integer.valueOf(descendants); return new @ParamFetchDescendantsOption("depth"); Integer depth); } } |
QueryRestController.java | @Override public ResponseEntity<Object> getNodesByDataspaceAndAnchorAndCpsPathV2(final String dataspaceName, | we need to change query to support depth or we can query all fragments and then select fragment data till given depth value(in below code). | FragmentEntityArranger.java | private static FragmentEntity reuniteChildrenWithTheirParents(final Map<Long, final String anchorName, final String cpsPath, final String descendants) { final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantOption(descendants); final Collection<DataNode> dataNodes = FragmentEntity> fragmentEntityPerIdcpsQueryService.queryDataNodes(dataspaceName, anchorName, IntegercpsPath, depthfetchDescendantsOption) {; final Collection<FragmentEntity> fragmentEntitiesWithoutParentInResultSetList<Map<String, Object>> dataMaps = new HashSet<>ArrayList<>(dataNodes.size()); forString (finalprefix FragmentEntity fragmentEntity : fragmentEntityPerId.values()) {= null; for (final FragmentEntityDataNode parentFragmentEntitydataNode = fragmentEntityPerId.get(fragmentEntity.getParentId());: dataNodes) { if (parentFragmentEntityprefix == null) { fragmentEntitiesWithoutParentInResultSet.add(fragmentEntityprefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); } else { final Map<String, Object> dataMap = parentFragmentEntityDataMapUtils.getChildFragments().add(fragmentEntitytoDataMapWithIdentifier(dataNode, prefix); }dataMaps.add(dataMap); } return fragmentEntitiesWithoutParentInResultSet.stream().findFirst().orElse(nullnew ResponseEntity<>(jsonObjectMapper.asJsonString(dataMaps), HttpStatus.OK); } we can reunite children as per given depth value.
|