Merge "Move GRPC management api to designer api."
[ccsdk/cds.git] / ms / blueprintsprocessor / functions / config-snapshots / src / test / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / functions / config / snapshots / ComponentConfigSnapshotsExecutorTest.kt
1 /*
2  *  Copyright © 2019 Bell Canada.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 package org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots
18
19 import com.fasterxml.jackson.databind.JsonNode
20 import kotlinx.coroutines.runBlocking
21 import org.junit.Assert.assertEquals
22 import org.junit.Assert.assertTrue
23 import org.junit.Before
24 import org.junit.Test
25 import org.junit.runner.RunWith
26 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
27 import org.onap.ccsdk.cds.blueprintsprocessor.core.BlueprintPropertyConfiguration
28 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
29 import org.onap.ccsdk.cds.blueprintsprocessor.db.BluePrintDBLibConfiguration
30 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor
31 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.DIFF_JSON
32 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.DIFF_XML
33 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_DIFF
34 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_FETCH
35 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.ComponentConfigSnapshotsExecutor.Companion.OPERATION_STORE
36 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshot
37 import org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots.db.ResourceConfigSnapshotService
38 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
39 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
40 import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
41 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
42 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
43 import org.springframework.beans.factory.annotation.Autowired
44 import org.springframework.boot.autoconfigure.EnableAutoConfiguration
45 import org.springframework.context.annotation.ComponentScan
46 import org.springframework.test.context.ContextConfiguration
47 import org.springframework.test.context.TestPropertySource
48 import org.springframework.test.context.junit4.SpringRunner
49
50 @RunWith(SpringRunner::class)
51 @ContextConfiguration(classes = [ResourceConfigSnapshotService::class,
52     BlueprintPropertyConfiguration::class, BluePrintProperties::class,
53     BluePrintDBLibConfiguration::class, BluePrintLoadConfiguration::class])
54 @TestPropertySource(locations = ["classpath:application-test.properties"])
55 @ComponentScan(basePackages = ["org.onap.ccsdk.cds.blueprintsprocessor", "org.onap.ccsdk.cds.controllerblueprints"])
56 @EnableAutoConfiguration
57 @Suppress("SameParameterValue")
58 class ComponentConfigSnapshotsExecutorTest {
59
60     @Autowired
61     lateinit var cfgSnapshotService : ResourceConfigSnapshotService
62     lateinit var cfgSnapshotComponent : ComponentConfigSnapshotsExecutor
63     private var bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("123456-1000",
64             "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_scripts")
65
66     private val resourceId = "1"
67     private val resourceType = "ServiceInstance"
68     private val props = mutableMapOf<String, JsonNode>()
69     private val nodeTemplateName = "nodeTemplateName"
70
71     private val executionRequest = ExecutionServiceInput()
72
73     @Before
74     fun setup() {
75         cfgSnapshotComponent = ComponentConfigSnapshotsExecutor(cfgSnapshotService)
76         props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_ID] = resourceId.asJsonPrimitive()
77         props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_TYPE] = resourceType.asJsonPrimitive()
78
79
80         cfgSnapshotComponent.operationInputs = props
81         cfgSnapshotComponent.bluePrintRuntimeService = bluePrintRuntimeService
82         cfgSnapshotComponent.nodeTemplateName = nodeTemplateName
83
84         cfgSnapshotComponent.executionServiceInput = executionRequest
85         cfgSnapshotComponent.processId = "12"
86         cfgSnapshotComponent.workflowName = "workflow"
87         cfgSnapshotComponent.stepName = "step"
88         cfgSnapshotComponent.interfaceName = "interfaceName"
89         cfgSnapshotComponent.operationName = "operationName"
90     }
91
92     @Test
93     fun processNBFetchWithResourceIdAndResourceTypeSingleFind() {
94         val snapshot = ResourceConfigSnapshot()
95         val snapshotConfig = "TEST1"
96         snapshot.config_snapshot = snapshotConfig
97
98         runBlocking {
99             try {
100                 val resId = "121111"
101                 val resType = "PNF"
102                 cfgSnapshotService.write(snapshotConfig, resId, resType)
103                 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.RUNNING.name)
104
105                 cfgSnapshotComponent.processNB(executionRequest)
106             } catch (e: BluePrintProcessorException) {
107                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
108                         e.message)
109                 return@runBlocking
110             }
111             // then; we should get success and the TEST1 payload in our output properties
112             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
113                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
114                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
115             assertEquals(snapshotConfig.asJsonPrimitive(),
116                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
117                             ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT))
118         }
119     }
120
121     @Test
122     fun processNBFetchCandidateWithResourceIdAndResourceTypeSingleFind() {
123         val snapshot = ResourceConfigSnapshot()
124         val snapshotConfig = "TEST"
125         snapshot.config_snapshot = snapshotConfig
126
127         runBlocking {
128             try {
129                 val resId = "121111"
130                 val resType = "PNF"
131                 cfgSnapshotService.write(snapshotConfig, resId, resType,  ResourceConfigSnapshot.Status.CANDIDATE)
132                 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.CANDIDATE.name)
133
134                 cfgSnapshotComponent.processNB(executionRequest)
135             } catch (e: BluePrintProcessorException) {
136                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
137                         e.message)
138                 return@runBlocking
139             }
140             // then; we should get success and the TEST payload in our output properties
141             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
142                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
143                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
144             assertEquals(snapshotConfig.asJsonPrimitive(),
145                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
146                             ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT))
147         }
148     }
149
150     @Test
151     fun processNBStoreWithResourceIdAndResourceType() {
152         val snapshot = ResourceConfigSnapshot()
153         val snapshotConfig = "PAYLOAD"
154         snapshot.config_snapshot = snapshotConfig
155
156         runBlocking {
157             try {
158                 val resId = "121111"
159                 val resType = "PNF"
160                 prepareRequestProperties(OPERATION_STORE, resId, resType, snapshotConfig)
161
162                 cfgSnapshotComponent.processNB(executionRequest)
163
164             } catch (e: BluePrintProcessorException) {
165                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
166                         e.message)
167                 return@runBlocking
168             }
169
170             // then; we should get success and the PAYLOAD payload in our output properties
171             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
172                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
173                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
174             assertEquals(snapshotConfig.asJsonPrimitive(),
175                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
176                             ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT))
177         }
178     }
179
180     @Test
181     fun processNBFetchNoneFound() {
182
183         runBlocking {
184             // when; asking for unknown resource Id/ resource Type combo; should get an error response
185             try {
186                 prepareRequestProperties(OPERATION_FETCH, "asdasd",  "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
187
188                 cfgSnapshotComponent.processNB(executionRequest)
189
190             } catch (e: BluePrintProcessorException) {
191                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
192                         e.message)
193                 return@runBlocking
194             }
195
196             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
197                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
198                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
199         }
200     }
201
202     @Test
203     fun processNBErrorOperationUnknown() {
204
205         runBlocking {
206             // when; asking for unknown operation update; should get an error response
207             try {
208                 prepareRequestProperties("update", "asdasd",  "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
209
210                 cfgSnapshotComponent.processNB(executionRequest)
211
212             } catch (e: BluePrintProcessorException) {
213                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
214                         e.message)
215                 return@runBlocking
216             }
217
218             // then; we should get error in our output properties
219             assertTrue( bluePrintRuntimeService.getBluePrintError().errors.size == 1 )
220             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_ERROR.asJsonPrimitive(),
221                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
222                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
223             val msg = "Operation parameter must be fetch, store or diff"
224             assertEquals(msg.asJsonPrimitive(),
225                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
226                             ComponentConfigSnapshotsExecutor.OUTPUT_MESSAGE))
227         }
228     }
229
230     @Test
231     fun processNBErrorDiffContentTypeUnknown() {
232
233         runBlocking {
234             // when; asking for unknown content type diff operation; should get an error response
235             try {
236                 val resId = "121111"
237                 val resType = "PNF"
238                 cfgSnapshotService.write("snapshotConfig", resId, resType,  ResourceConfigSnapshot.Status.CANDIDATE)
239                 prepareRequestProperties(OPERATION_DIFF, resId,  resType, "YANG")
240
241                 cfgSnapshotComponent.processNB(executionRequest)
242
243             } catch (e: BluePrintProcessorException) {
244                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
245                         e.message)
246                 return@runBlocking
247             }
248
249             // then; we should get error in our output properties
250             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_ERROR.asJsonPrimitive(),
251                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
252                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
253             val message = "Could not compare config snapshots for type YANG"
254             assertEquals(message.asJsonPrimitive(),
255                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
256                             ComponentConfigSnapshotsExecutor.OUTPUT_MESSAGE))
257         }
258     }
259
260     @Test
261     fun processNBCompareTwoJsonConfigSnapshots() {
262
263         runBlocking {
264
265             // when; comparing RUNNING vs CANDIDATE json configs; should get an success response; with differences
266             try {
267                 val resId = "131313"
268                 val resType = "PNF"
269                 preparePayload("config-payload-running.json", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
270                 preparePayload("config-payload-candidate.json", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
271
272                 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_JSON)
273                 cfgSnapshotComponent.processNB(executionRequest)
274
275             } catch (e: BluePrintProcessorException) {
276                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
277                         e.message)
278                 return@runBlocking
279             }
280
281             // then; we should get success
282             assertTrue( bluePrintRuntimeService.getBluePrintError().errors.size == 0 )
283             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
284                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
285                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
286
287             // then; we should get JSON-patches differences in our response property
288             val diffJson = "[{\"op\":\"add\",\"path\":\"/system-uptime-information/last-configured-time/new-child-object\",\"value\":{\"property\":\"value\"}}," +
289                     "{\"op\":\"replace\",\"path\":\"/system-uptime-information/system-booted-time/time-length\",\"value\":\"14:52:54\"}," +
290                     "{\"op\":\"replace\",\"path\":\"/system-uptime-information/time-source\",\"value\":\" DNS CLOCK \"}," +
291                     "{\"op\":\"add\",\"path\":\"/system-uptime-information/uptime-information/load-average-10\",\"value\":\"0.05\"}]"
292             assertEquals(diffJson.asJsonPrimitive(),
293                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
294                             ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT))
295         }
296     }
297
298     @Test
299     fun processNBCompareTwoXmlConfigSnapshots() {
300
301         runBlocking {
302
303             // when; comparing RUNNING vs CANDIDATE xml configs; should get an success response; with differences
304             try {
305                 val resId = "141414"
306                 val resType = "VNF"
307                 preparePayload("interface-running.xml", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
308                 preparePayload("interface-candidate.xml", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
309
310                 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_XML)
311
312                 cfgSnapshotComponent.processNB(executionRequest)
313
314             } catch (e: BluePrintProcessorException) {
315                 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
316                         e.message)
317                 return@runBlocking
318             }
319
320             // then; we should get success
321             assertTrue( bluePrintRuntimeService.getBluePrintError().errors.size == 0 )
322             assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
323                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
324                             ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
325
326             // then; we should get XML-patches differences in our response property
327             val diffXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
328                     "<diff>" +
329                     "<replace sel=\"/output[1]/interface-information[1]/interface-flapped[1]/@seconds\">2343</replace>" +
330                     "<replace sel=\"/output[1]/interface-information[1]/interface-flapped[1]/text()[1]\">34</replace>" +
331                     "<replace sel=\"/output[1]/interface-information[1]/traffic-statistics[1]/input-packets[1]/text()[1]\">09098789</replace>" +
332                     "<replace sel=\"/output[1]/interface-information[1]/traffic-statistics[1]/output-packets[1]/text()[1]\">2828828</replace>" +
333                     "<add sel=\"/output[1]/interface-information[1]/physical-interface[1]\"><interface-name>TEGig400-int01</interface-name></add>" +
334                     "</diff>"
335             assertEquals(diffXml.asJsonPrimitive(),
336                     bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
337                             ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT))        }
338     }
339
340     private fun preparePayload(filename : String, resId : String, resType : String, status: ResourceConfigSnapshot.Status) {
341         runBlocking {
342             cfgSnapshotService.write(JacksonUtils.getClassPathFileContent("payload/requests/$filename"), resId, resType, status)
343         }
344     }
345
346     private fun prepareRequestProperties (oper : String, resId : String, resType : String, optional: String = "") {
347         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_OPERATION] = oper.asJsonPrimitive()
348         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_ID] = resId.asJsonPrimitive()
349         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_TYPE] = resType.asJsonPrimitive()
350
351         // Optional inputs
352         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_DIFF_CONTENT_TYPE] = "".asJsonPrimitive()
353         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_SNAPSHOT] = "".asJsonPrimitive()
354         cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_STATUS] =
355                 ResourceConfigSnapshot.Status.RUNNING.name.asJsonPrimitive()
356
357         when (oper) {
358             OPERATION_DIFF ->
359                 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_DIFF_CONTENT_TYPE] = optional.asJsonPrimitive()
360             OPERATION_STORE ->
361                 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_SNAPSHOT] = optional.asJsonPrimitive()
362             OPERATION_FETCH ->
363                 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_STATUS] = optional.asJsonPrimitive()
364         }
365     }
366 }