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