summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcps-ncmp-rest/docs/openapi/ncmp.yml177
-rwxr-xr-xcps-ncmp-rest/docs/openapi/openapi.yml14
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java88
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy113
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy18
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java71
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java54
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy2
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy79
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java31
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java14
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/NotificationService.java20
-rw-r--r--cps-service/src/main/java/org/onap/cps/notification/Operation.java27
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy23
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy10
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy61
-rw-r--r--docs/api/swagger/ncmp/openapi.yaml356
18 files changed, 149 insertions, 1011 deletions
diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml
index 7845a34ad..71b4f1c45 100755
--- a/cps-ncmp-rest/docs/openapi/ncmp.yml
+++ b/cps-ncmp-rest/docs/openapi/ncmp.yml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (C) 2021 Nordix Foundation
+# Copyright (C) 2021-2022 Nordix Foundation
# Modifications Copyright (C) 2021 Pantheon.tech
# Modifications Copyright (C) 2021 Bell Canada
# ================================================================================
@@ -17,181 +17,6 @@
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=========================================================
-
-nodeByCmHandleAndXpath:
- get:
- description: Get a node with an option to retrieve all the children for a given cm Handle
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Get a node given a cm Handle and xpath
- operationId: getNodeByCmHandleAndXpath
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/xpathInQuery'
- - $ref: 'components.yaml#/components/parameters/includeDescendantsOptionInQuery'
- responses:
- 200:
- $ref: 'components.yaml#/components/responses/Ok'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
-nodesByCmHandleAndCpsPath:
- get:
- description: Query nodes for the given cps path and cm Handle
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Query data nodes
- operationId: queryNodesByCmHandleAndCpsPath
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/cpsPathInQuery'
- - $ref: 'components.yaml#/components/parameters/includeDescendantsOptionInQuery'
- responses:
- 200:
- $ref: 'components.yaml#/components/responses/Ok'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
-nodesByCmHandleAndXpath:
- post:
- description: Create a node with descendants for the given CM Handle; top level or under existing node (requires xpath)
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Create a node with descendants
- operationId: createNode
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/xpathInQuery'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- examples:
- dataSampleRequest:
- $ref: 'components.yaml#/components/examples/dataSampleRequest'
- responses:
- 201:
- $ref: 'components.yaml#/components/responses/Created'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
- patch:
- description: Update node leaves for the given cps path and cm Handle
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Update node leaves
- operationId: updateNodeLeaves
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/xpathInQuery'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- examples:
- dataSampleRequest:
- $ref: 'components.yaml#/components/examples/dataSampleRequest'
- responses:
- 200:
- $ref: 'components.yaml#/components/responses/Ok'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
- put:
- description: Replace a node with descendants for the given cps path and cm Handle
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Replace a node with descendants
- operationId: replaceNode
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/xpathInQuery'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- examples:
- dataSampleRequest:
- $ref: 'components.yaml#/components/examples/dataSampleRequest'
- responses:
- 200:
- $ref: 'components.yaml#/components/responses/Ok'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
-listNodeByCmHandleAndXpath:
- post:
- description: Add one or more list-node child elements under existing node for the given CM Handle
- deprecated: true
- tags:
- - network-cm-proxy
- summary: Add list-node child element(s)
- operationId: addListNodeElements
- parameters:
- - $ref: 'components.yaml#/components/parameters/cmHandleInPath'
- - $ref: 'components.yaml#/components/parameters/requiredXpathInQuery'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- examples:
- dataSampleRequest:
- $ref: 'components.yaml#/components/examples/dataSampleRequest'
- responses:
- 201:
- $ref: 'components.yaml#/components/responses/Created'
- 400:
- $ref: 'components.yaml#/components/responses/BadRequest'
- 401:
- $ref: 'components.yaml#/components/responses/Unauthorized'
- 403:
- $ref: 'components.yaml#/components/responses/Forbidden'
- 404:
- $ref: 'components.yaml#/components/responses/NotFound'
-
getResourceDataForPassthroughOperational:
get:
tags:
diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml
index 64a74c593..838a0d08e 100755
--- a/cps-ncmp-rest/docs/openapi/openapi.yml
+++ b/cps-ncmp-rest/docs/openapi/openapi.yml
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (C) 2021 Nordix Foundation
+# Copyright (C) 2021-2022 Nordix Foundation
# Modifications Copyright (C) 2021 Pantheon.tech
# Modifications Copyright (C) 2021 Bell Canada
# ================================================================================
@@ -26,18 +26,6 @@ info:
servers:
- url: /ncmp
paths:
- /v1/cm-handles/{cm-handle}/node:
- $ref: 'ncmp.yml#/nodeByCmHandleAndXpath'
-
- /v1/cm-handles/{cm-handle}/list-node:
- $ref: 'ncmp.yml#/listNodeByCmHandleAndXpath'
-
- /v1/cm-handles/{cm-handle}/nodes/query:
- $ref: 'ncmp.yml#/nodesByCmHandleAndCpsPath'
-
- /v1/cm-handles/{cm-handle}/nodes:
- $ref: 'ncmp.yml#/nodesByCmHandleAndXpath'
-
/v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
$ref: 'ncmp.yml#/getResourceDataForPassthroughOperational'
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
index e3c457eaf..a97852fe2 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Pantheon.tech
- * Modifications (C) 2021 Nordix Foundation
+ * Modifications (C) 2021-2022 Nordix Foundation
* Modification Copyright (C) 2021 highstreet technologies GmbH
* Modifications (C) 2021 Bell Canada
* ================================================================================
@@ -48,9 +48,6 @@ import org.onap.cps.ncmp.rest.model.Conditions;
import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
import org.onap.cps.ncmp.rest.model.ModuleReference;
-import org.onap.cps.spi.FetchDescendantsOption;
-import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.utils.DataMapUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -76,89 +73,6 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
}
/**
- * Create Node.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Void> createNode(final String cmHandle, @Valid final Object jsonData,
- @Valid final String parentNodeXpath) {
- networkCmProxyDataService.createDataNode(cmHandle, parentNodeXpath, GSON.toJson(jsonData));
- return new ResponseEntity<>(HttpStatus.CREATED);
- }
-
- /**
- * Add List-node Child Element.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Void> addListNodeElements(@NotNull @Valid final String parentNodeXpath,
- final String cmHandle, @Valid final Object jsonData) {
- networkCmProxyDataService.addListNodeElements(cmHandle, parentNodeXpath, GSON.toJson(jsonData));
- return new ResponseEntity<>(HttpStatus.CREATED);
- }
-
- /**
- * Get Node By CM Handle and X-Path.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Object> getNodeByCmHandleAndXpath(final String cmHandle, @Valid final String xpath,
- @Valid final Boolean includeDescendants) {
- final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants)
- ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS;
- final var dataNode = networkCmProxyDataService.getDataNode(cmHandle, xpath, fetchDescendantsOption);
- return new ResponseEntity<>(DataMapUtils.toDataMap(dataNode), HttpStatus.OK);
- }
-
- /**
- * Query Data Nodes.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Object> queryNodesByCmHandleAndCpsPath(final String cmHandle, @Valid final String cpsPath,
- @Valid final Boolean includeDescendants) {
- final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants)
- ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS;
- final Collection<DataNode> dataNodes =
- networkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption);
- return new ResponseEntity<>(GSON.toJson(dataNodes), HttpStatus.OK);
- }
-
- /**
- * Replace Node With Descendants.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Object> replaceNode(final String cmHandle, @Valid final Object jsonData,
- @Valid final String parentNodeXpath) {
- networkCmProxyDataService.replaceNodeTree(cmHandle, parentNodeXpath, GSON.toJson(jsonData));
- return new ResponseEntity<>(HttpStatus.OK);
- }
-
- /**
- * Update Node Leaves.
- * @deprecated This Method is no longer used as part of NCMP.
- */
- // All deprecated APIs methods will be address into https://jira.onap.org/browse/CPS-642
- @Override
- @Deprecated(forRemoval = false)
- public ResponseEntity<Object> updateNodeLeaves(final String cmHandle, @Valid final Object jsonData,
- @Valid final String parentNodeXpath) {
- networkCmProxyDataService.updateNodeLeaves(cmHandle, parentNodeXpath, GSON.toJson(jsonData));
- return new ResponseEntity<>(HttpStatus.OK);
- }
-
- /**
* Get resource data from operational datastore.
*
* @param cmHandle cm handle identifier
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
index a3d8afaf2..b5dc2eabb 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Pantheon.tech
* Modification Copyright (C) 2021 highstreet technologies GmbH
- * Modification Copyright (C) 2021 Nordix Foundation
+ * Modification Copyright (C) 2021-2022 Nordix Foundation
* Modification Copyright (C) 2021 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,8 +26,6 @@ import org.onap.cps.TestUtils
import org.onap.cps.spi.model.ModuleReference
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
-import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
-import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
@@ -37,9 +35,7 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE
-import com.google.gson.Gson
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
-import org.onap.cps.spi.model.DataNodeBuilder
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -61,115 +57,8 @@ class NetworkCmProxyControllerSpec extends Specification {
@Value('${rest.api.ncmp-base-path}/v1')
def ncmpBasePathV1
- def cmHandle = 'some handle'
- def xpath = 'some xpath'
def jsonString = '{"some-key":"some-value"}'
- def 'Query data node by cps path for the given cm handle with #scenario.'() {
- given: 'service method returns a list containing a data node'
- def dataNode = new DataNodeBuilder().withXpath('/xpath').build()
- def cpsPath = 'some cps-path'
- mockNetworkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, expectedCpsDataServiceOption) >> [dataNode]
- and: 'the query endpoint'
- def dataNodeEndpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes/query"
- when: 'query data nodes API is invoked'
- def response = mvc.perform(get(dataNodeEndpoint)
- .param('cps-path', cpsPath)
- .param('include-descendants', includeDescendantsOption))
- .andReturn().response
- then: 'the response contains the the datanode in json format'
- response.status == HttpStatus.OK.value()
- def expectedJsonContent = new Gson().toJson(dataNode)
- response.getContentAsString().contains(expectedJsonContent)
- where: 'the following options for include descendants are provided in the request'
- scenario | includeDescendantsOption || expectedCpsDataServiceOption
- 'no descendants by default' | '' || OMIT_DESCENDANTS
- 'no descendant explicitly' | 'false' || OMIT_DESCENDANTS
- 'descendants' | 'true' || INCLUDE_ALL_DESCENDANTS
- }
-
- def 'Create data node: #scenario.'() {
- when: 'post request is performed'
- def response = mvc.perform(
- post("$ncmpBasePathV1/cm-handles/$cmHandle/nodes")
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonString)
- .param('xpath', reqXpath)
- ).andReturn().response
- then: 'the service method is invoked once with expected parameters'
- 1 * mockNetworkCmProxyDataService.createDataNode(cmHandle, usedXpath, jsonString)
- and: 'response status indicates success'
- response.status == HttpStatus.CREATED.value()
- where: 'following parameters were used'
- scenario | reqXpath || usedXpath
- 'no xpath parameter' | '' || '/'
- 'root xpath' | '/' || '/'
- 'parent node xpath' | '/xpath' || '/xpath'
- }
-
- def 'Add list-node elements.'() {
- given: ' parent node xpath'
- def parentNodeXpath = 'parent node xpath'
- when: 'post request is performed'
- def response = mvc.perform(
- post("$ncmpBasePathV1/cm-handles/$cmHandle/list-node")
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonString)
- .param('xpath', parentNodeXpath)
- ).andReturn().response
- then: 'the service method is invoked once with expected parameters'
- 1 * mockNetworkCmProxyDataService.addListNodeElements(cmHandle, parentNodeXpath, jsonString)
- and: 'response status indicates success'
- response.status == HttpStatus.CREATED.value()
- }
-
- def 'Update data node leaves.'() {
- given: 'the query endpoint'
- def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes"
- when: 'patch request is performed'
- def response = mvc.perform(
- patch(endpoint)
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonString)
- .param('xpath', xpath)
- ).andReturn().response
- then: 'the service method is invoked once with expected parameters'
- 1 * mockNetworkCmProxyDataService.updateNodeLeaves(cmHandle, xpath, jsonString)
- and: 'response status indicates success'
- response.status == HttpStatus.OK.value()
- }
-
- def 'Replace data node tree.'() {
- given: 'the query endpoint'
- def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes"
- when: 'put request is performed'
- def response = mvc.perform(
- put(endpoint)
- .contentType(MediaType.APPLICATION_JSON)
- .content(jsonString)
- .param('xpath', xpath)
- ).andReturn().response
- then: 'the service method is invoked once with expected parameters'
- 1 * mockNetworkCmProxyDataService.replaceNodeTree(cmHandle, xpath, jsonString)
- and: 'response status indicates success'
- response.status == HttpStatus.OK.value()
- }
-
- def 'Get data node.'() {
- given: 'the service returns a data node'
- def xpath = 'some xpath'
- def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(["leaf": "value"]).build()
- mockNetworkCmProxyDataService.getDataNode(cmHandle, xpath, OMIT_DESCENDANTS) >> dataNode
- and: 'the query endpoint'
- def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/node"
- when: 'get request is performed through REST API'
- def response = mvc.perform(get(endpoint).param('xpath', xpath)).andReturn().response
- then: 'a success response is returned'
- response.status == HttpStatus.OK.value()
- and: 'response contains expected leaf and value'
- response.contentAsString.contains('"leaf":"value"')
- }
-
def 'Get Resource Data from pass-through operational.' () {
given: 'resource data url'
def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
index 3fcf818af..f36a70693 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 highstreet technologies GmbH
- * Modification Copyright (C) 2021 Nordix Foundation
+ * Modification Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ package org.onap.cps.ncmp.rest.exceptions
import groovy.json.JsonSlurper
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.impl.exception.NcmpException
-import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.CpsException
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
@@ -55,9 +54,6 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@Shared
def errorDetails = 'some error details'
- def cmHandle = 'some handle'
- def xpath = 'some xpath'
-
def setup() {
dataNodeBaseEndpoint = "$basePath/v1"
}
@@ -75,18 +71,16 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
'other' | new IllegalStateException(errorMessage) || null
}
- def setupTestException(exception) {
- mockNetworkCmProxyDataService.getDataNode(cmHandle, xpath, FetchDescendantsOption.OMIT_DESCENDANTS) >>
+ def setupTestException(exception){
+ mockNetworkCmProxyDataService.getYangResourcesModuleReferences('testCmHandle')>>
{ throw exception}
}
- def performTestRequest() {
- return mvc.perform(get("$dataNodeBaseEndpoint/cm-handles/$cmHandle/node").param('xpath', xpath))
- .andReturn().response
+ def performTestRequest(){
+ return mvc.perform(get("$dataNodeBaseEndpoint/ch/testCmHandle/modules")).andReturn().response
}
- static void assertTestResponse(response, expectedStatus,expectedErrorMessage,
- expectedErrorDetails) {
+ static void assertTestResponse(response, expectedStatus , expectedErrorMessage , expectedErrorDetails) {
assert response.status == expectedStatus.value()
def content = new JsonSlurper().parseText(response.contentAsString)
assert content['status'] == expectedStatus.toString()
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
index ec816ed73..dddf08910 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,10 +25,7 @@ package org.onap.cps.ncmp.api;
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
import java.util.Collection;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
-import org.onap.cps.spi.FetchDescendantsOption;
-import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleReference;
/*
@@ -37,72 +34,6 @@ import org.onap.cps.spi.model.ModuleReference;
public interface NetworkCmProxyDataService {
/**
- * Retrieves datanode by XPath for a given cm handle.
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm
- * object by managed Network CM Proxy
- * @param xpath xpath
- * @param fetchDescendantsOption defines the scope of data to fetch: either single node or all the descendant nodes
- * (recursively) as well
- * @return data node object
- */
- DataNode getDataNode(@NonNull String cmHandle, @NonNull String xpath,
- @NonNull FetchDescendantsOption fetchDescendantsOption);
-
- /**
- * Get datanodes for the given cm handle by cps path.
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm
- * object by managed Network CM Proxy
- * @param cpsPath cps path
- * @param fetchDescendantsOption defines whether the descendants of the node(s) found by the query should be
- * included in the output
- * @return a collection of datanodes
- */
- Collection<DataNode> queryDataNodes(@NonNull String cmHandle, @NonNull String cpsPath,
- @NonNull FetchDescendantsOption fetchDescendantsOption);
-
- /**
- * Creates data node with descendants at root level or under existing node (if parent node xpath is provided).
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm
- * object managed by Network CM Proxy
- * @param parentNodeXpath xpath to parent node or '/' for root level
- * @param jsonData data as JSON string
- */
- void createDataNode(@NonNull String cmHandle, @NonNull String parentNodeXpath, @NonNull String jsonData);
-
- /**
- * Creates one or more child node elements with descendants under existing node from list-node data fragment.
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm
- * object managed by Network CM Proxy
- * @param parentNodeXpath xpath to parent node
- * @param jsonData data as JSON string
- */
- void addListNodeElements(@NonNull String cmHandle, @NonNull String parentNodeXpath, @NonNull String jsonData);
-
- /**
- * Updates data node for given cm handle using xpath to parent node.
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm object
- * by managed Network CM Proxy
- * @param parentNodeXpath xpath to parent node
- * @param jsonData json data
- */
- void updateNodeLeaves(@NonNull String cmHandle, @NonNull String parentNodeXpath, @NonNull String jsonData);
-
- /**
- * Replaces existing data node content including descendants.
- *
- * @param cmHandle The identifier for a network function, network element, subnetwork or any other cm object
- * by managed Network CM Proxy
- * @param parentNodeXpath xpath to parent node
- * @param jsonData json data
- */
- void replaceNodeTree(@NonNull String cmHandle, @NonNull String parentNodeXpath, @NonNull String jsonData);
-
- /**
* Registration of New CM Handles.
*
* @param dmiPluginRegistration Dmi Plugin Registration
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 7ded95fa0..eeb004ad5 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 highstreet technologies GmbH
- * Modifications Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
@@ -38,7 +38,6 @@ import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
-import org.onap.cps.api.CpsQueryService;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
import org.onap.cps.ncmp.api.impl.exception.NcmpException;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
@@ -48,14 +47,11 @@ import org.onap.cps.ncmp.api.models.CmHandle;
import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
import org.onap.cps.ncmp.api.models.PersistenceCmHandlesList;
-import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
-import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.ModuleReference;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
@Slf4j
@Service
@@ -73,8 +69,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private ObjectMapper objectMapper;
- private CpsQueryService cpsQueryService;
-
private DmiDataOperations dmiDataOperations;
private DmiModelOperations dmiModelOperations;
@@ -87,69 +81,23 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
* Constructor Injection for Dependencies.
* @param dmiDataOperations DMI operation
* @param cpsDataService Data Service Interface
- * @param cpsQueryService Query Service Interface
* @param objectMapper Object Mapper
*/
public NetworkCmProxyDataServiceImpl(final DmiDataOperations dmiDataOperations,
final DmiModelOperations dmiModelOperations,
final CpsModuleService cpsModuleService,
final CpsDataService cpsDataService,
- final CpsQueryService cpsQueryService,
final CpsAdminService cpsAdminService,
final ObjectMapper objectMapper) {
this.dmiDataOperations = dmiDataOperations;
this.dmiModelOperations = dmiModelOperations;
this.cpsModuleService = cpsModuleService;
this.cpsDataService = cpsDataService;
- this.cpsQueryService = cpsQueryService;
this.cpsAdminService = cpsAdminService;
this.objectMapper = objectMapper;
}
@Override
- public DataNode getDataNode(final String cmHandle, final String xpath,
- final FetchDescendantsOption fetchDescendantsOption) {
- return cpsDataService
- .getDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, xpath, fetchDescendantsOption);
- }
-
- @Override
- public Collection<DataNode> queryDataNodes(final String cmHandle, final String cpsPath,
- final FetchDescendantsOption fetchDescendantsOption) {
- return cpsQueryService
- .queryDataNodes(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, cpsPath, fetchDescendantsOption);
- }
-
- @Override
- public void createDataNode(final String cmHandle, final String parentNodeXpath, final String jsonData) {
- if (!StringUtils.hasText(parentNodeXpath) || "/".equals(parentNodeXpath)) {
- cpsDataService.saveData(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, jsonData, NO_TIMESTAMP);
- } else {
- cpsDataService
- .saveData(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, parentNodeXpath, jsonData, NO_TIMESTAMP);
- }
- }
-
- @Override
- public void addListNodeElements(final String cmHandle, final String parentNodeXpath, final String jsonData) {
- cpsDataService.saveListElements(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, parentNodeXpath, jsonData,
- NO_TIMESTAMP);
- }
-
- @Override
- public void updateNodeLeaves(final String cmHandle, final String parentNodeXpath, final String jsonData) {
- cpsDataService
- .updateNodeLeaves(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, parentNodeXpath, jsonData,
- NO_TIMESTAMP);
- }
-
- @Override
- public void replaceNodeTree(final String cmHandle, final String parentNodeXpath, final String jsonData) {
- cpsDataService.replaceNodeTree(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandle, parentNodeXpath, jsonData,
- NO_TIMESTAMP);
- }
-
- @Override
public void updateDmiRegistrationAndSyncModule(final DmiPluginRegistration dmiPluginRegistration) {
dmiPluginRegistration.validateDmiPluginRegistration();
try {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
index de60a0193..b7f059a7c 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
@@ -35,7 +35,7 @@ class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
def mockDmiModelOperations = Mock(DmiModelOperations)
def objectUnderTest = new NetworkCmProxyDataServiceImpl(null, mockDmiModelOperations,
- mockCpsModuleService, null, null, mockCpsAdminService, new ObjectMapper())
+ mockCpsModuleService, null, mockCpsAdminService, new ObjectMapper())
def expectedDataspaceName = 'NFP-Operational'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
index 304c08ae8..90fcbfc61 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
@@ -183,7 +183,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def getObjectUnderTestWithModelSyncDisabled() {
def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(null, null, mockCpsModuleService,
- mockCpsDataService, null, null, spyObjectMapper))
+ mockCpsDataService, null, spyObjectMapper))
objectUnderTest.syncModulesAndCreateAnchor(*_) >> null
return objectUnderTest
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 62492710e..5753d7b67 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021 Bell Canada
* ================================================================================
@@ -33,7 +33,6 @@ import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsModuleService
-import org.onap.cps.api.CpsQueryService
import org.onap.cps.ncmp.api.impl.exception.NcmpException
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.spi.FetchDescendantsOption
@@ -45,52 +44,16 @@ import spock.lang.Specification
class NetworkCmProxyDataServiceImplSpec extends Specification {
def mockCpsDataService = Mock(CpsDataService)
- def mockCpsQueryService = Mock(CpsQueryService)
def mockCpsModuleService = Mock(CpsModuleService)
def mockCpsAdminService = Mock(CpsAdminService)
def spyObjectMapper = Spy(ObjectMapper)
def mockDmiDataOperations = Mock(DmiDataOperations)
def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiDataOperations, null,
- mockCpsModuleService, mockCpsDataService, mockCpsQueryService, mockCpsAdminService, spyObjectMapper)
+ mockCpsModuleService, mockCpsDataService, mockCpsAdminService, spyObjectMapper)
- def cmHandle = 'some handle'
- def noTimestamp = null
def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
- def expectedDataspaceName = 'NFP-Operational'
- def 'Create full data node: #scenario.'() {
- given: 'json data'
- def jsonData = 'some json'
- when: 'createDataNode is invoked'
- objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
- then: 'save data is invoked once with the expected parameters'
- 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, jsonData, noTimestamp)
- where: 'following parameters were used'
- scenario | xpath
- 'no xpath' | ''
- 'root level xpath' | '/'
- }
-
- def 'Create child data node.'() {
- given: 'json data and xpath'
- def jsonData = 'some json'
- def xpath = '/test-node'
- when: 'create data node is invoked'
- objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
- then: 'save data is invoked once with the expected parameters'
- 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
- }
-
- def 'Add list-node elements.'() {
- given: 'json data and xpath'
- def jsonData = 'some json'
- def xpath = '/test-node'
- when: 'add list node element is invoked'
- objectUnderTest.addListNodeElements(cmHandle, xpath, jsonData)
- then: 'the save list elements is invoked once with the expected parameters'
- 1 * mockCpsDataService.saveListElements(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
- }
def 'Write resource data for pass-through running from dmi using POST #scenario cm handle properties.'() {
given: 'a data node'
@@ -133,14 +96,6 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
exceptionThrown.details.contains('404')
}
- def 'Get data node.'() {
- when: 'get data node is invoked'
- objectUnderTest.getDataNode(cmHandle, 'some xpath', fetchDescendantsOption)
- then: 'the persistence data service is called once with the correct parameters'
- 1 * mockCpsDataService.getDataNode(expectedDataspaceName, cmHandle, 'some xpath', fetchDescendantsOption)
- where: 'all fetch descendants options are supported'
- fetchDescendantsOption << FetchDescendantsOption.values()
- }
def 'Get resource data for pass-through operational from dmi.'() {
given: 'a data node'
@@ -270,25 +225,6 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
1 * mockCpsAdminService.queryAnchorNames('NFP-Operational', ['some-module-name'])
}
- def 'Update data node leaves.'() {
- given: 'json data and xpath'
- def jsonData = 'some json'
- def xpath = '/xpath'
- when: 'update node leaves is invoked'
- objectUnderTest.updateNodeLeaves(cmHandle, xpath, jsonData)
- then: 'the persistence service is called once with the correct parameters'
- 1 * mockCpsDataService.updateNodeLeaves(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
- }
-
- def 'Replace data node tree.'() {
- given: 'json data and xpath'
- def jsonData = 'some json'
- def xpath = '/xpath'
- when: 'replace node tree is invoked'
- objectUnderTest.replaceNodeTree(cmHandle, xpath, jsonData)
- then: 'the persistence service is called once with the correct parameters'
- 1 * mockCpsDataService.replaceNodeTree(expectedDataspaceName, cmHandle, xpath, jsonData, noTimestamp)
- }
def 'Update resource data for pass-through running from dmi using POST #scenario cm handle properties.'() {
given: 'a data node'
@@ -331,17 +267,6 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
'UPDATE' | UPDATE || 'Not able to update resource data.'
}
- def 'Query data nodes by cps path with #fetchDescendantsOption.'() {
- given: 'a cps path'
- def cpsPath = '/cps-path'
- when: 'query data nodes is invoked'
- objectUnderTest.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption)
- then: 'the persistence query service is called once with the correct parameters'
- 1 * mockCpsQueryService.queryDataNodes(expectedDataspaceName, cmHandle, cpsPath, fetchDescendantsOption)
- where: 'all fetch descendants options are supported'
- fetchDescendantsOption << FetchDescendantsOption.values()
- }
-
def getDataNode(boolean includeCmHandleProperties) {
def dataNode = new DataNode()
dataNode.leaves = ['dmi-service-name': 'testDmiService']
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index 1445ccadf..a23bc95f3 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
- * Modifications Copyright (C) 2020-2021 Bell Canada.
+ * Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,8 +27,8 @@ import java.util.Collection;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsDataService;
-import org.onap.cps.api.CpsModuleService;
import org.onap.cps.notification.NotificationService;
+import org.onap.cps.notification.Operation;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.exceptions.DataValidationException;
@@ -53,9 +53,6 @@ public class CpsDataServiceImpl implements CpsDataService {
private CpsAdminService cpsAdminService;
@Autowired
- private CpsModuleService cpsModuleService;
-
- @Autowired
private YangTextSchemaSourceSetCache yangTextSchemaSourceSetCache;
@Autowired
@@ -66,7 +63,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final OffsetDateTime observedTimestamp) {
final var dataNode = buildDataNode(dataspaceName, anchorName, ROOT_NODE_XPATH, jsonData);
cpsDataPersistenceService.storeDataNode(dataspaceName, anchorName, dataNode);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, ROOT_NODE_XPATH, Operation.CREATE);
}
@Override
@@ -74,7 +71,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final String jsonData, final OffsetDateTime observedTimestamp) {
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, parentNodeXpath, dataNode);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.CREATE);
}
@Override
@@ -84,7 +81,7 @@ public class CpsDataServiceImpl implements CpsDataService {
buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath,
listElementDataNodeCollection);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@Override
@@ -99,7 +96,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService
.updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(), dataNode.getLeaves());
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@Override
@@ -113,7 +110,7 @@ public class CpsDataServiceImpl implements CpsDataService {
for (final DataNode dataNodeUpdate : dataNodeUpdates) {
processDataNodeUpdate(dataspaceName, anchorName, dataNodeUpdate);
}
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@Override
@@ -121,7 +118,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final String jsonData, final OffsetDateTime observedTimestamp) {
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName, dataNode);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@Override
@@ -130,21 +127,21 @@ public class CpsDataServiceImpl implements CpsDataService {
final Collection<DataNode> newListElements =
buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, newListElements);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@Override
public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath,
final OffsetDateTime observedTimestamp) {
cpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, dataNodeXpath, Operation.DELETE);
}
@Override
public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath,
final OffsetDateTime observedTimestamp) {
cpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, listNodeXpath);
- processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp);
+ processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, listNodeXpath, Operation.DELETE);
}
private DataNode buildDataNode(final String dataspaceName, final String anchorName,
@@ -186,9 +183,10 @@ public class CpsDataServiceImpl implements CpsDataService {
}
private void processDataUpdatedEventAsync(final String dataspaceName, final String anchorName,
- final OffsetDateTime observedTimestamp) {
+ final OffsetDateTime observedTimestamp, final String xpath,
+ final Operation operation) {
try {
- notificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp);
+ notificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, xpath, operation);
} catch (final Exception exception) {
log.error("Failed to send message to notification service", exception);
}
@@ -210,4 +208,5 @@ public class CpsDataServiceImpl implements CpsDataService {
processDataNodeUpdate(dataspaceName, anchorName, childDataNodeUpdate);
}
}
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java b/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java
index 2985ed53b..6054ce5d7 100644
--- a/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java
+++ b/cps-service/src/main/java/org/onap/cps/notification/CpsDataUpdatedEventFactory.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,20 +71,21 @@ public class CpsDataUpdatedEventFactory {
* @param dataspaceName dataspaceName
* @param anchorName anchorName
* @param observedTimestamp observedTimestamp
+ * @param operation operation
* @return CpsDataUpdatedEvent
*/
public CpsDataUpdatedEvent createCpsDataUpdatedEvent(final String dataspaceName, final String anchorName,
- final OffsetDateTime observedTimestamp) {
+ final OffsetDateTime observedTimestamp, final Operation operation) {
final var dataNode = cpsDataService
.getDataNode(dataspaceName, anchorName, "/", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
- return toCpsDataUpdatedEvent(anchor, dataNode, observedTimestamp);
+ return toCpsDataUpdatedEvent(anchor, dataNode, observedTimestamp, operation);
}
private CpsDataUpdatedEvent toCpsDataUpdatedEvent(final Anchor anchor, final DataNode dataNode,
- final OffsetDateTime observedTimestamp) {
+ final OffsetDateTime observedTimestamp, final Operation operation) {
final var cpsDataUpdatedEvent = new CpsDataUpdatedEvent();
- cpsDataUpdatedEvent.withContent(createContent(anchor, dataNode, observedTimestamp));
+ cpsDataUpdatedEvent.withContent(createContent(anchor, dataNode, observedTimestamp, operation));
cpsDataUpdatedEvent.withId(UUID.randomUUID().toString());
cpsDataUpdatedEvent.withSchema(EVENT_SCHEMA);
cpsDataUpdatedEvent.withSource(EVENT_SOURCE);
@@ -99,12 +100,13 @@ public class CpsDataUpdatedEventFactory {
}
private Content createContent(final Anchor anchor, final DataNode dataNode,
- final OffsetDateTime observedTimestamp) {
+ final OffsetDateTime observedTimestamp, final Operation operation) {
final var content = new Content();
content.withAnchorName(anchor.getName());
content.withDataspaceName(anchor.getDataspaceName());
content.withSchemaSetName(anchor.getSchemaSetName());
content.withData(createData(dataNode));
+ content.withOperation(Content.Operation.fromValue(operation.name()));
content.withObservedTimestamp(
DATE_TIME_FORMATTER.format(observedTimestamp == null ? OffsetDateTime.now() : observedTimestamp));
return content;
diff --git a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java b/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
index 029efbe79..97a14797b 100644
--- a/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
+++ b/cps-service/src/main/java/org/onap/cps/notification/NotificationService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,8 @@ import org.springframework.stereotype.Service;
@Slf4j
public class NotificationService {
+ private static final String ROOT_NODE_XPATH = "/";
+
private NotificationProperties notificationProperties;
private NotificationPublisher notificationPublisher;
private CpsDataUpdatedEventFactory cpsDataUpdatedEventFactory;
@@ -78,19 +80,23 @@ public class NotificationService {
/**
* Process Data Updated Event and publishes the notification.
*
- * @param dataspaceName dataspace name
- * @param anchorName anchor name
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
* @param observedTimestamp observedTimestamp
+ * @param xpath xpath of changed data node
+ * @param operation operation
* @return future
*/
@Async("notificationExecutor")
public Future<Void> processDataUpdatedEvent(final String dataspaceName, final String anchorName,
- final OffsetDateTime observedTimestamp) {
+ final OffsetDateTime observedTimestamp,
+ final String xpath, final Operation operation) {
log.debug("process data updated event for dataspace '{}' & anchor '{}'", dataspaceName, anchorName);
try {
if (shouldSendNotification(dataspaceName)) {
final var cpsDataUpdatedEvent =
- cpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp);
+ cpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, anchorName,
+ observedTimestamp, getRootNodeOperation(xpath, operation));
log.debug("data updated event to be published {}", cpsDataUpdatedEvent);
notificationPublisher.sendNotification(cpsDataUpdatedEvent);
}
@@ -114,4 +120,8 @@ public class NotificationService {
.anyMatch(pattern -> pattern.matcher(dataspaceName).find());
}
+ private Operation getRootNodeOperation(final String xpath, final Operation operation) {
+ return ROOT_NODE_XPATH.equals(xpath) ? operation : Operation.UPDATE;
+ }
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/notification/Operation.java b/cps-service/src/main/java/org/onap/cps/notification/Operation.java
new file mode 100644
index 000000000..83e1ccf79
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/notification/Operation.java
@@ -0,0 +1,27 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2022 Bell Canada.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.notification;
+
+public enum Operation {
+ CREATE,
+ UPDATE,
+ DELETE
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index ba9c156d7..6c899c793 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2021 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2021 Bell Canada.
+ * Modifications Copyright (C) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.onap.cps.TestUtils
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.notification.NotificationService
+import org.onap.cps.notification.Operation
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.exceptions.DataValidationException
@@ -40,7 +41,6 @@ import java.time.OffsetDateTime
class CpsDataServiceImplSpec extends Specification {
def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService)
def mockCpsAdminService = Mock(CpsAdminService)
- def mockCpsModuleService = Mock(CpsModuleService)
def mockYangTextSchemaSourceSetCache = Mock(YangTextSchemaSourceSetCache)
def mockNotificationService = Mock(NotificationService)
@@ -49,7 +49,6 @@ class CpsDataServiceImplSpec extends Specification {
def setup() {
objectUnderTest.cpsDataPersistenceService = mockCpsDataPersistenceService
objectUnderTest.cpsAdminService = mockCpsAdminService
- objectUnderTest.cpsModuleService = mockCpsModuleService
objectUnderTest.yangTextSchemaSourceSetCache = mockYangTextSchemaSourceSetCache
objectUnderTest.notificationService = mockNotificationService
}
@@ -69,7 +68,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.storeDataNode(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == '/test-tree' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/', Operation.CREATE)
}
def 'Saving child data fragment under existing node.'() {
@@ -82,7 +81,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, '/test-tree',
{ dataNode -> dataNode.xpath == '/test-tree/branch[@name=\'New\']' })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.CREATE)
}
def 'Saving list element data fragment under existing node.'() {
@@ -102,7 +101,7 @@ class CpsDataServiceImplSpec extends Specification {
}
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.UPDATE)
}
def 'Saving empty list element data fragment.'() {
@@ -134,7 +133,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, expectedNodeXpath, leaves)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath | leaves
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree' | Collections.emptyMap()
@@ -167,7 +166,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName,
"/dmi-registry/cm-handles[@id='cmHandle001']", ['id': 'cmHandle001'])
and: 'the data updated event is sent to the notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/dmi-registry', Operation.UPDATE)
}
def 'Replace data node: #scenario.'() {
@@ -179,7 +178,7 @@ class CpsDataServiceImplSpec extends Specification {
1 * mockCpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName,
{ dataNode -> dataNode.xpath == expectedNodeXpath })
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE)
where: 'following parameters were used'
scenario | parentNodeXpath | jsonData || expectedNodeXpath
'top level node' | '/' | '{"test-tree": {"branch": []}}' || '/test-tree'
@@ -203,7 +202,7 @@ class CpsDataServiceImplSpec extends Specification {
}
)
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree', Operation.UPDATE)
}
def 'Replace whole list content with empty list element.'() {
@@ -224,7 +223,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with correct parameters'
1 * mockCpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, '/test-tree/branch')
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/test-tree/branch', Operation.DELETE)
}
def 'Delete data node under anchor and dataspace.'() {
@@ -235,7 +234,7 @@ class CpsDataServiceImplSpec extends Specification {
then: 'the persistence service method is invoked with the correct parameters'
1 * mockCpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, '/data-node')
and: 'data updated event is sent to notification service'
- 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp)
+ 1 * mockNotificationService.processDataUpdatedEvent(dataspaceName, anchorName, observedTimestamp, '/data-node', Operation.DELETE)
}
def setupSchemaSetMocks(String... yangResources) {
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
index aa0c7c0b3..67ed3d90f 100644
--- a/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/notification/CpsDataUpdateEventFactorySpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter
import org.onap.cps.utils.DateTimeUtility
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
+import org.onap.cps.event.model.Content
import org.onap.cps.event.model.Data
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.Anchor
@@ -45,7 +46,6 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def dateTimeFormat = 'yyyy-MM-dd\'T\'HH:mm:ss.SSSZ'
def 'Create a CPS data updated event successfully: #scenario'() {
-
given: 'cps admin service is able to return anchor details'
mockCpsAdminService.getAnchor(myDataspaceName, myAnchorName) >>
new Anchor(myAnchorName, myDataspaceName, mySchemasetName)
@@ -54,13 +54,10 @@ class CpsDataUpdateEventFactorySpec extends Specification {
def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(['leafName': 'leafValue']).build()
mockCpsDataService.getDataNode(
myDataspaceName, myAnchorName, xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
-
when: 'CPS data updated event is created'
def cpsDataUpdatedEvent = objectUnderTest.createCpsDataUpdatedEvent(myDataspaceName,
- myAnchorName, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp))
-
+ myAnchorName, DateTimeUtility.toOffsetDateTime(inputObservedTimestamp), Operation.CREATE)
then: 'CPS data updated event is created with correct envelope'
-
with(cpsDataUpdatedEvent) {
type == 'org.onap.cps.data-updated-event'
source == new URI('urn:cps:org.onap.cps')
@@ -79,6 +76,7 @@ class CpsDataUpdateEventFactorySpec extends Specification {
assert anchorName == myAnchorName
assert dataspaceName == myDataspaceName
assert schemaSetName == mySchemasetName
+ assert operation == Content.Operation.CREATE
assert data == new Data().withAdditionalProperty('leafName', 'leafValue')
}
where:
diff --git a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
index ca704edb4..306e187a0 100644
--- a/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/notification/NotificationServiceSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (c) 2021 Bell Canada.
+ * Copyright (c) 2021-2022 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,7 +61,7 @@ class NotificationServiceSpec extends Specification {
given: 'notification is disabled'
spyNotificationProperties.isEnabled() >> false
when: 'dataUpdatedEvent is received'
- objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
+ objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/', Operation.CREATE)
then: 'the notification is not sent'
0 * mockNotificationPublisher.sendNotification(_)
}
@@ -71,10 +71,12 @@ class NotificationServiceSpec extends Specification {
spyNotificationProperties.isEnabled() >> true
and: 'event factory can create event successfully'
def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp) >>
- cpsDataUpdatedEvent
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp,
+ Operation.CREATE) >>
+ cpsDataUpdatedEvent
when: 'dataUpdatedEvent is received'
- def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp)
+ def future = objectUnderTest.processDataUpdatedEvent(dataspaceName, myAnchorName, myObservedTimestamp,
+ '/', Operation.CREATE)
and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
@@ -87,14 +89,57 @@ class NotificationServiceSpec extends Specification {
'dataspace name matches filter' | myDataspacePublishedName || 1
}
+ def 'Send UPDATE operation when non-root data nodes are changed.'() {
+ given: 'notification is enabled'
+ spyNotificationProperties.isEnabled() >> true
+ and: 'event factory creates event if operation is UPDATE'
+ def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp,
+ Operation.UPDATE) >> cpsDataUpdatedEvent
+ when: 'dataUpdatedEvent is received for non-root xpath'
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/non-root-node',
+ operation)
+ and: 'wait for async processing to complete'
+ future.get(10, TimeUnit.SECONDS)
+ then: 'async process completed successfully'
+ future.isDone()
+ and: 'notification is sent'
+ 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
+ where:
+ operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
+ }
+
+ def 'Send same operation when root nodes are changed.'() {
+ given: 'notification is enabled'
+ spyNotificationProperties.isEnabled() >> true
+ and: 'event factory creates event if operation is #operation'
+ def cpsDataUpdatedEvent = new CpsDataUpdatedEvent()
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp,
+ operation) >> cpsDataUpdatedEvent
+ when: 'dataUpdatedEvent is received for root xpath'
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp, '/',
+ operation)
+ and: 'wait for async processing to complete'
+ future.get(10, TimeUnit.SECONDS)
+ then: 'async process completed successfully'
+ future.isDone()
+ and: 'notification is sent'
+ 1 * mockNotificationPublisher.sendNotification(cpsDataUpdatedEvent)
+ where:
+ operation << [Operation.CREATE, Operation.UPDATE, Operation.DELETE]
+ }
+
+
def 'Error handling in notification service.'() {
given: 'notification is enabled'
spyNotificationProperties.isEnabled() >> true
and: 'event factory can not create event successfully'
- mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp) >>
- { throw new Exception("Could not create event") }
+ mockCpsDataUpdatedEventFactory.createCpsDataUpdatedEvent(myDataspacePublishedName, myAnchorName,
+ myObservedTimestamp, Operation.CREATE) >>
+ { throw new Exception("Could not create event") }
when: 'event is sent for processing'
- def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName, myObservedTimestamp)
+ def future = objectUnderTest.processDataUpdatedEvent(myDataspacePublishedName, myAnchorName,
+ myObservedTimestamp, '/', Operation.CREATE)
and: 'wait for async processing to complete'
future.get(10, TimeUnit.SECONDS)
then: 'async process completed successfully'
diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml
index 509adf469..a3b9dc750 100644
--- a/docs/api/swagger/ncmp/openapi.yaml
+++ b/docs/api/swagger/ncmp/openapi.yaml
@@ -6,362 +6,6 @@ info:
servers:
- url: /ncmp
paths:
- /v1/cm-handles/{cm-handle}/node:
- get:
- tags:
- - network-cm-proxy
- summary: Get a node given a cm Handle and xpath
- description: Get a node with an option to retrieve all the children for a given
- cm Handle
- operationId: getNodeByCmHandleAndXpath
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: xpath
- in: query
- description: xpath
- required: false
- schema:
- type: string
- default: /
- - name: include-descendants
- in: query
- description: include-descendants
- required: false
- schema:
- type: boolean
- default: false
- responses:
- "200":
- description: OK
- content:
- application/json:
- schema:
- type: object
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
- /v1/cm-handles/{cm-handle}/list-node:
- post:
- tags:
- - network-cm-proxy
- summary: Add list-node child element(s)
- description: Add one or more list-node child elements under existing node for
- the given CM Handle
- operationId: addListNodeElements
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: xpath
- in: query
- description: xpath
- required: true
- schema:
- type: string
- requestBody:
- content:
- application/json:
- schema:
- type: string
- required: true
- responses:
- "201":
- description: Created
- content: {}
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
- /v1/cm-handles/{cm-handle}/nodes/query:
- get:
- tags:
- - network-cm-proxy
- summary: Query data nodes
- description: Query nodes for the given cps path and cm Handle
- operationId: queryNodesByCmHandleAndCpsPath
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: cps-path
- in: query
- description: cps-path
- required: false
- schema:
- type: string
- default: /
- - name: include-descendants
- in: query
- description: include-descendants
- required: false
- schema:
- type: boolean
- default: false
- responses:
- "200":
- description: OK
- content:
- application/json:
- schema:
- type: object
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
- /v1/cm-handles/{cm-handle}/nodes:
- put:
- tags:
- - network-cm-proxy
- summary: Replace a node with descendants
- description: Replace a node with descendants for the given cps path and cm Handle
- operationId: replaceNode
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: xpath
- in: query
- description: xpath
- required: false
- schema:
- type: string
- default: /
- requestBody:
- content:
- application/json:
- schema:
- type: string
- required: true
- responses:
- "200":
- description: OK
- content:
- application/json:
- schema:
- type: object
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
- post:
- tags:
- - network-cm-proxy
- summary: Create a node with descendants
- description: Create a node with descendants for the given CM Handle; top level
- or under existing node (requires xpath)
- operationId: createNode
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: xpath
- in: query
- description: xpath
- required: false
- schema:
- type: string
- default: /
- requestBody:
- content:
- application/json:
- schema:
- type: string
- required: true
- responses:
- "201":
- description: Created
- content: {}
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
- patch:
- tags:
- - network-cm-proxy
- summary: Update node leaves
- description: Update node leaves for the given cps path and cm Handle
- operationId: updateNodeLeaves
- parameters:
- - name: cm-handle
- in: path
- description: "The identifier for a network function, network element, subnetwork\
- \ or any other cm object by managed Network CM Proxy"
- required: true
- schema:
- type: string
- - name: xpath
- in: query
- description: xpath
- required: false
- schema:
- type: string
- default: /
- requestBody:
- content:
- application/json:
- schema:
- type: string
- required: true
- responses:
- "200":
- description: OK
- content:
- application/json:
- schema:
- type: object
- "400":
- description: Bad Request
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "401":
- description: Unauthorized
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "403":
- description: Forbidden
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- "404":
- description: The specified resource was not found
- content:
- application/json:
- schema:
- $ref: '#/components/schemas/ErrorMessage'
- deprecated: true
/v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational:
get:
tags: