2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * Modifications Copyright (C) 2021 Pantheon.tech
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.cps.ncmp.api.impl
24 import com.fasterxml.jackson.core.JsonProcessingException
25 import com.fasterxml.jackson.databind.ObjectMapper
26 import org.onap.cps.api.CpsDataService
27 import org.onap.cps.api.CpsQueryService
28 import org.onap.cps.ncmp.api.impl.exception.NcmpException
29 import org.onap.cps.ncmp.api.impl.operation.DmiOperations
30 import org.onap.cps.ncmp.api.models.CmHandle
31 import org.onap.cps.ncmp.api.models.DmiPluginRegistration
32 import org.onap.cps.spi.FetchDescendantsOption
33 import org.onap.cps.spi.model.DataNode
34 import org.springframework.http.HttpStatus
35 import org.springframework.http.ResponseEntity
36 import spock.lang.Specification
38 class NetworkCmProxyDataServiceImplSpec extends Specification {
40 def mockCpsDataService = Mock(CpsDataService)
41 def mockCpsQueryService = Mock(CpsQueryService)
42 def mockDmiOperations = Mock(DmiOperations)
43 def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiOperations, mockCpsDataService, mockCpsQueryService, new ObjectMapper())
45 def cmHandle = 'some handle'
46 def expectedDataspaceName = 'NFP-Operational'
47 def 'Query data nodes by cps path with #fetchDescendantsOption.'() {
48 given: 'a cm Handle and a cps path'
49 def cpsPath = '/cps-path'
50 when: 'queryDataNodes is invoked'
51 objectUnderTest.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption)
52 then: 'the persistence service is called once with the correct parameters'
53 1 * mockCpsQueryService.queryDataNodes(expectedDataspaceName, cmHandle, cpsPath, fetchDescendantsOption)
54 where: 'all fetch descendants options are supported'
55 fetchDescendantsOption << FetchDescendantsOption.values()
57 def 'Create full data node: #scenario.'() {
58 given: 'a cm handle and root xpath'
59 def jsonData = 'some json'
60 when: 'createDataNode is invoked'
61 objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
62 then: 'the CPS service method is invoked once with the expected parameters'
63 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, jsonData)
64 where: 'following parameters were used'
67 'root level xpath' | '/'
69 def 'Create child data node.'() {
70 given: 'a cm handle and parent node xpath'
71 def jsonData = 'some json'
72 def xpath = '/test-node'
73 when: 'createDataNode is invoked'
74 objectUnderTest.createDataNode(cmHandle, xpath, jsonData)
75 then: 'the CPS service method is invoked once with the expected parameters'
76 1 * mockCpsDataService.saveData(expectedDataspaceName, cmHandle, xpath, jsonData)
78 def 'Add list-node elements.'() {
79 given: 'a cm handle and parent node xpath'
80 def jsonData = 'some json'
81 def xpath = '/test-node'
82 when: 'addListNodeElements is invoked'
83 objectUnderTest.addListNodeElements(cmHandle, xpath, jsonData)
84 then: 'the CPS service method is invoked once with the expected parameters'
85 1 * mockCpsDataService.saveListNodeData(expectedDataspaceName, cmHandle, xpath, jsonData)
87 def 'Update data node leaves.'() {
88 given: 'a cm Handle and a cps path'
90 def jsonData = 'some json'
91 when: 'updateNodeLeaves is invoked'
92 objectUnderTest.updateNodeLeaves(cmHandle, xpath, jsonData)
93 then: 'the persistence service is called once with the correct parameters'
94 1 * mockCpsDataService.updateNodeLeaves(expectedDataspaceName, cmHandle, xpath, jsonData)
96 def 'Replace data node tree.'() {
97 given: 'a cm Handle and a cps path'
99 def jsonData = 'some json'
100 when: 'replaceNodeTree is invoked'
101 objectUnderTest.replaceNodeTree(cmHandle, xpath, jsonData)
102 then: 'the persistence service is called once with the correct parameters'
103 1 * mockCpsDataService.replaceNodeTree(expectedDataspaceName, cmHandle, xpath, jsonData)
105 def 'Register CM Handle Event.'() {
106 given: 'a registration '
107 def dmiPluginRegistration = new DmiPluginRegistration()
108 dmiPluginRegistration.dmiPlugin = 'my-server'
109 def cmHandle = new CmHandle()
110 cmHandle.cmHandleID = '123'
111 cmHandle.cmHandleProperties = [ name1: 'value1', name2: 'value2']
112 dmiPluginRegistration.createdCmHandles = [ cmHandle ]
113 def expectedJsonData = '{"cm-handles":[{"id":"123","dmi-service-name":"my-server","additional-properties":[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}]}]}'
114 when: 'registration is updated'
115 objectUnderTest.updateDmiPluginRegistration(dmiPluginRegistration)
116 then: 'the CPS service method is invoked once with the expected parameters'
117 1 * mockCpsDataService.saveListNodeData('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData)
119 def 'Get resource data for pass-through operational from dmi.'() {
121 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
123 def dataNode = new DataNode()
124 dataNode.leaves = ['dmi-service-name':'testDmiService']
125 def childDataNode = new DataNode()
126 childDataNode.leaves = ['name':'testName','value':'testValue']
127 dataNode.childDataNodes = [childDataNode]
128 when: 'get resource data is called'
129 def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
134 then: 'cps data service is being called once to get data node'
135 1 * mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
136 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
137 and: 'dmi operation is being called to get resource data'
138 1 * mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService',
144 '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('result-json', HttpStatus.OK)
145 and: 'dmi returns ok response'
146 response == 'result-json'
148 def 'Get resource data for pass-through operational from dmi threw parsing exception.'() {
150 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
152 def dataNode = new DataNode()
153 dataNode.leaves = ['dmi-service-name':'testDmiService']
154 def childDataNode = new DataNode()
155 childDataNode.leaves = ['name':'testName','value':'testValue']
156 dataNode.childDataNodes = [childDataNode]
157 mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
158 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
159 and: 'objectMapper not able to parse object'
160 def mockObjectMapper = Mock(ObjectMapper)
161 objectUnderTest.objectMapper = mockObjectMapper
162 mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException("testException") }
163 when: 'get resource data is called'
164 def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
169 then: 'exception is thrown'
170 thrown(NcmpException.class)
172 def 'Get resource data for pass-through operational from dmi return NOK response.'() {
174 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
176 def dataNode = new DataNode()
177 dataNode.leaves = ['dmi-service-name':'testDmiService']
178 def childDataNode = new DataNode()
179 childDataNode.leaves = ['name':'testName','value':'testValue']
180 dataNode.childDataNodes = [childDataNode]
181 mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
182 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
183 and: 'dmi returns NOK response'
184 mockDmiOperations.getResouceDataOperationalFromDmi('testDmiService',
190 '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}')
191 >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
192 when: 'get resource data is called'
193 def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle',
198 then: 'exception is thrown'
199 thrown(NcmpException.class)
201 def 'Get resource data for pass-through running from dmi.'() {
203 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
204 and: 'data node representing cmhandle and its properties'
205 def dataNode = new DataNode()
206 dataNode.leaves = ['dmi-service-name':'testDmiService']
207 def childDataNode = new DataNode()
208 childDataNode.leaves = ['name':'testName','value':'testValue']
209 dataNode.childDataNodes = [childDataNode]
210 and: 'cpsDataService returns valid dataNode'
211 mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
212 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
213 and: 'dmi returns valid response and data'
214 mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService',
220 '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('{result-json}', HttpStatus.OK)
221 when: 'get resource data is called'
222 def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
227 then: 'get resource data returns expected response'
228 response == '{result-json}'
230 def 'Get resource data for pass-through running from dmi threw parsing exception.'() {
232 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
233 and: 'data node representing cmhandle and its properties'
234 def dataNode = new DataNode()
235 dataNode.leaves = ['dmi-service-name':'testDmiService']
236 def childDataNode = new DataNode()
237 childDataNode.leaves = ['name':'testName','value':'testValue']
238 dataNode.childDataNodes = [childDataNode]
239 and: 'cpsDataService returns valid dataNode'
240 mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
241 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
242 and: 'objectMapper not able to parse object'
243 def mockObjectMapper = Mock(ObjectMapper)
244 objectUnderTest.objectMapper = mockObjectMapper
245 mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException("testException") }
246 when: 'get resource data is called'
247 def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
252 then: 'exception is thrown'
253 thrown(NcmpException.class)
255 def 'Get resource data for pass-through running from dmi return NOK response.'() {
257 def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
258 and: 'data node representing cmhandle and its properties'
259 def dataNode = new DataNode()
260 dataNode.leaves = ['dmi-service-name':'testDmiService']
261 def childDataNode = new DataNode()
262 childDataNode.leaves = ['name':'testName','value':'testValue']
263 dataNode.childDataNodes = [childDataNode]
264 and: 'cpsDataService returns valid dataNode'
265 mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
266 xpath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
267 and: 'dmi returns NOK response'
268 mockDmiOperations.getResouceDataPassThroughRunningFromDmi('testDmiService',
274 '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}')
275 >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
276 when: 'get resource data is called'
277 def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
282 then: 'exception is thrown'
283 thrown(NcmpException.class)