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