P2 - Get module names and revisions rest layer
[cps.git] / cps-ncmp-rest / src / test / groovy / org / onap / cps / ncmp / rest / controller / NetworkCmProxyControllerSpec.groovy
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  Modification Copyright (C) 2021 highstreet technologies GmbH
5  *  Modification Copyright (C) 2021 Nordix Foundation
6  *  Modification Copyright (C) 2021 Bell Canada.
7  *  ================================================================================
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  *
19  *  SPDX-License-Identifier: Apache-2.0
20  *  ============LICENSE_END=========================================================
21  */
22
23 package org.onap.cps.ncmp.rest.controller
24
25 import org.onap.cps.spi.model.ModuleReference
26
27 import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
28 import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
29 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
30 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch
31 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
32 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
33
34 import com.fasterxml.jackson.databind.ObjectMapper
35 import com.google.gson.Gson
36 import org.onap.cps.TestUtils
37 import org.onap.cps.ncmp.api.NetworkCmProxyDataService
38 import org.onap.cps.spi.model.DataNodeBuilder
39 import org.spockframework.spring.SpringBean
40 import org.springframework.beans.factory.annotation.Autowired
41 import org.springframework.beans.factory.annotation.Value
42 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
43 import org.springframework.http.HttpStatus
44 import org.springframework.http.MediaType
45 import org.springframework.test.web.servlet.MockMvc
46 import spock.lang.Specification
47
48 @WebMvcTest(NetworkCmProxyController)
49 class NetworkCmProxyControllerSpec extends Specification {
50
51     @Autowired
52     MockMvc mvc
53
54     @SpringBean
55     NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
56
57     @SpringBean
58     ObjectMapper objectMapper = new ObjectMapper()
59
60     @Value('${rest.api.ncmp-base-path}/v1')
61     def ncmpBasePathV1
62
63     def cmHandle = 'some handle'
64     def xpath = 'some xpath'
65
66     def 'Query data node by cps path for the given cm handle with #scenario.'() {
67         given: 'service method returns a list containing a data node'
68             def dataNode = new DataNodeBuilder().withXpath('/xpath').build()
69             def cpsPath = 'some cps-path'
70             mockNetworkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, expectedCpsDataServiceOption) >> [dataNode]
71         and: 'the query endpoint'
72             def dataNodeEndpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes/query"
73         when: 'query data nodes API is invoked'
74             def response = mvc.perform(get(dataNodeEndpoint)
75                     .param('cps-path', cpsPath)
76                     .param('include-descendants', includeDescendantsOption))
77                     .andReturn().response
78         then: 'the response contains the the datanode in json format'
79             response.status == HttpStatus.OK.value()
80             def expectedJsonContent = new Gson().toJson(dataNode)
81             response.getContentAsString().contains(expectedJsonContent)
82         where: 'the following options for include descendants are provided in the request'
83             scenario                    | includeDescendantsOption || expectedCpsDataServiceOption
84             'no descendants by default' | ''                       || OMIT_DESCENDANTS
85             'no descendant explicitly'  | 'false'                  || OMIT_DESCENDANTS
86             'descendants'               | 'true'                   || INCLUDE_ALL_DESCENDANTS
87     }
88
89     def 'Create data node: #scenario.'() {
90         given: 'json data'
91             def jsonData = 'json data'
92         when: 'post request is performed'
93             def response = mvc.perform(
94                     post("$ncmpBasePathV1/cm-handles/$cmHandle/nodes")
95                             .contentType(MediaType.APPLICATION_JSON)
96                             .content(jsonData)
97                             .param('xpath', reqXpath)
98             ).andReturn().response
99         then: 'the service method is invoked once with expected parameters'
100             1 * mockNetworkCmProxyDataService.createDataNode(cmHandle, usedXpath, jsonData)
101         and: 'response status indicates success'
102             response.status == HttpStatus.CREATED.value()
103         where: 'following parameters were used'
104             scenario             | reqXpath || usedXpath
105             'no xpath parameter' | ''       || '/'
106             'root xpath'         | '/'      || '/'
107             'parent node xpath'  | '/xpath' || '/xpath'
108     }
109
110     def 'Add list-node elements.'() {
111         given: 'json data and parent node xpath'
112             def jsonData = 'json data'
113             def parentNodeXpath = 'parent node xpath'
114         when: 'post request is performed'
115             def response = mvc.perform(
116                     post("$ncmpBasePathV1/cm-handles/$cmHandle/list-node")
117                             .contentType(MediaType.APPLICATION_JSON)
118                             .content(jsonData)
119                             .param('xpath', parentNodeXpath)
120             ).andReturn().response
121         then: 'the service method is invoked once with expected parameters'
122             1 * mockNetworkCmProxyDataService.addListNodeElements(cmHandle, parentNodeXpath, jsonData)
123         and: 'response status indicates success'
124             response.status == HttpStatus.CREATED.value()
125     }
126
127     def 'Update data node leaves.'() {
128         given: 'json data'
129             def jsonData = 'json data'
130         and: 'the query endpoint'
131             def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes"
132         when: 'patch request is performed'
133             def response = mvc.perform(
134                     patch(endpoint)
135                             .contentType(MediaType.APPLICATION_JSON)
136                             .content(jsonData)
137                             .param('xpath', xpath)
138             ).andReturn().response
139         then: 'the service method is invoked once with expected parameters'
140             1 * mockNetworkCmProxyDataService.updateNodeLeaves(cmHandle, xpath, jsonData)
141         and: 'response status indicates success'
142             response.status == HttpStatus.OK.value()
143     }
144
145     def 'Replace data node tree.'() {
146         given: 'json data'
147             def jsonData = 'json data'
148         and: 'the query endpoint'
149             def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/nodes"
150         when: 'put request is performed'
151             def response = mvc.perform(
152                     put(endpoint)
153                             .contentType(MediaType.APPLICATION_JSON)
154                             .content(jsonData)
155                             .param('xpath', xpath)
156             ).andReturn().response
157         then: 'the service method is invoked once with expected parameters'
158             1 * mockNetworkCmProxyDataService.replaceNodeTree(cmHandle, xpath, jsonData)
159         and: 'response status indicates success'
160             response.status == HttpStatus.OK.value()
161     }
162
163     def 'Get data node.'() {
164         given: 'the service returns a data node'
165             def xpath = 'some xpath'
166             def dataNode = new DataNodeBuilder().withXpath(xpath).withLeaves(["leaf": "value"]).build()
167             mockNetworkCmProxyDataService.getDataNode(cmHandle, xpath, OMIT_DESCENDANTS) >> dataNode
168         and: 'the query endpoint'
169             def endpoint = "$ncmpBasePathV1/cm-handles/$cmHandle/node"
170         when: 'get request is performed through REST API'
171             def response = mvc.perform(get(endpoint).param('xpath', xpath)).andReturn().response
172         then: 'a success response is returned'
173             response.status == HttpStatus.OK.value()
174         and: 'response contains expected leaf and value'
175             response.contentAsString.contains('"leaf":"value"')
176     }
177
178     def 'Register CM Handle Event' () {
179         given: 'jsonData'
180             def jsonData = TestUtils.getResourceFileContent('dmi-registration.json')
181         when: 'post request is performed'
182             def response = mvc.perform(
183                 post("$ncmpBasePathV1/ch")
184                 .contentType(MediaType.APPLICATION_JSON)
185                 .content(jsonData)
186             ).andReturn().response
187         then: 'the cm handles are registered with the service'
188             1 * mockNetworkCmProxyDataService.updateDmiRegistrationAndSyncModule(_)
189         and: 'response status is created'
190             response.status == HttpStatus.CREATED.value()
191     }
192
193     def 'Get Resource Data from pass-through operational.' () {
194         given: 'resource data url'
195             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" +
196                     "/testResourceIdentifier?fields=testFields&depth=5"
197         when: 'get data resource request is performed'
198             def response = mvc.perform(
199                     get(getUrl)
200                             .contentType(MediaType.APPLICATION_JSON)
201                     .accept(MediaType.APPLICATION_JSON_VALUE)
202             ).andReturn().response
203         then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle'
204             1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle',
205                     'testResourceIdentifier',
206                     'application/json',
207                     'testFields',
208                     5)
209         and: 'response status is Ok'
210             response.status == HttpStatus.OK.value()
211     }
212
213     def 'Get Resource Data from pass-through running.' () {
214         given: 'resource data url'
215             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
216                     "/testResourceIdentifier?fields=testFields&depth=5"
217         and: 'ncmp service returns json object'
218             mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle',
219                 'testResourceIdentifier',
220                 'application/json',
221                 'testFields',
222                 5) >> '{valid-json}'
223         when: 'get data resource request is performed'
224             def response = mvc.perform(
225                     get(getUrl)
226                             .contentType(MediaType.APPLICATION_JSON)
227                             .accept(MediaType.APPLICATION_JSON_VALUE)
228             ).andReturn().response
229         then: 'response status is Ok'
230             response.status == HttpStatus.OK.value()
231         and: 'response contains valid object body'
232             response.getContentAsString() == '{valid-json}'
233     }
234
235     def 'Create Resource Data from pass-through running using POST.' () {
236         given: 'resource data url'
237             def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" +
238                     "/testResourceIdentifier"
239         when: 'get data resource request is performed'
240             def response = mvc.perform(
241                     post(getUrl)
242                             .contentType(MediaType.APPLICATION_JSON_VALUE)
243                             .accept(MediaType.APPLICATION_JSON_VALUE).content('{"some-json":"value"}')
244             ).andReturn().response
245         then: 'ncmp service method to create resource called'
246             1 * mockNetworkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle('testCmHandle',
247                     'testResourceIdentifier', ['some-json':'value'], 'application/json;charset=UTF-8')
248         and: 'resource is created'
249             response.status == HttpStatus.CREATED.value()
250     }
251
252     def 'Get module references for the given dataspace and cm handle.' () {
253         given: 'get module references url'
254             def getUrl = "$ncmpBasePathV1/ch/some-cmhandle/modules"
255         when: 'get module resource request is performed'
256             def response =mvc.perform(get(getUrl)).andReturn().response
257         then: 'ncmp service method to get yang resource module references is called'
258             mockNetworkCmProxyDataService.getYangResourcesModuleReferences('some-cmhandle')
259                     >> [new ModuleReference(moduleName: 'some-name1',revision: 'some-revision1')]
260         and: 'response contains an array with the module name and revision'
261             response.getContentAsString() == '[{"moduleName":"some-name1","revision":"some-revision1"}]'
262         and: 'response returns an OK http code'
263             response.status == HttpStatus.OK.value()
264     }
265 }
266