Get resource data from pass through running (Ncmp impl.)
[cps.git] / cps-ncmp-service / src / test / groovy / org / onap / cps / ncmp / api / impl / NetworkCmProxyDataServiceImplSpec.groovy
1 /*
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
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.onap.cps.ncmp.api.impl
23
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
37
38 class NetworkCmProxyDataServiceImplSpec extends Specification {
39
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())
44
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()
56     }
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'
65             scenario           | xpath
66             'no xpath'         | ''
67             'root level xpath' | '/'
68     }
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)
77     }
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)
86     }
87     def 'Update data node leaves.'() {
88         given: 'a cm Handle and a cps path'
89             def xpath = '/xpath'
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)
95     }
96     def 'Replace data node tree.'() {
97         given: 'a cm Handle and a cps path'
98             def xpath = '/xpath'
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)
104     }
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)
118     }
119     def 'Get resource data for pass-through operational from dmi.'() {
120         given: 'xpath'
121             def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
122         and: 'data node'
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',
130             'testResourceId',
131             'testAcceptParam',
132             'testFieldQuery',
133             5)
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',
139                     'testCmHandle',
140                     'testResourceId',
141                     'testFieldQuery',
142                     5,
143                     'testAcceptParam',
144             '{"operation":"read","cmHandleProperties":{"testName":"testValue"}}') >> new ResponseEntity<>('result-json', HttpStatus.OK)
145         and: 'dmi returns ok response'
146             response == 'result-json'
147     }
148     def 'Get resource data for pass-through operational from dmi threw parsing exception.'() {
149         given: 'xpath'
150             def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
151         and: 'data node'
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',
165                     'testResourceId',
166                     'testAcceptParam',
167                     'testFieldQuery',
168                     5)
169         then: 'exception is thrown'
170             thrown(NcmpException.class)
171     }
172     def 'Get resource data for pass-through operational from dmi return NOK response.'() {
173         given: 'xpath'
174             def xpath = "/dmi-registry/cm-handles[@id='testCmHandle']"
175         and: 'data node'
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',
185                     'testCmHandle',
186                     'testResourceId',
187                     'testFieldQuery',
188                     5,
189                     'testAcceptParam',
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',
194                     'testResourceId',
195                     'testAcceptParam',
196                     'testFieldQuery',
197                     5)
198         then: 'exception is thrown'
199             thrown(NcmpException.class)
200     }
201     def 'Get resource data for pass-through running from dmi.'() {
202         given: 'xpath'
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',
215                     'testCmHandle',
216                     'testResourceId',
217                     'testFieldQuery',
218                     5,
219                     'testAcceptParam',
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',
223                     'testResourceId',
224                     'testAcceptParam',
225                     'testFieldQuery',
226                     5)
227         then: 'get resource data returns expected response'
228             response == '{result-json}'
229     }
230     def 'Get resource data for pass-through running from dmi threw parsing exception.'() {
231         given: 'xpath'
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',
248                     'testResourceId',
249                     'testAcceptParam',
250                     'testFieldQuery',
251                     5)
252         then: 'exception is thrown'
253             thrown(NcmpException.class)
254     }
255     def 'Get resource data for pass-through running from dmi return NOK response.'() {
256         given: 'xpath'
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',
269                     'testCmHandle',
270                     'testResourceId',
271                     'testFieldQuery',
272                     5,
273                     'testAcceptParam',
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',
278                     'testResourceId',
279                     'testAcceptParam',
280                     'testFieldQuery',
281                     5)
282         then: 'exception is thrown'
283             thrown(NcmpException.class)
284     }
285 }