2 * Copyright © 2019 Bell Canada.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onap.ccsdk.cds.blueprintsprocessor.functions.config.snapshots
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
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
49 @RunWith(SpringRunner::class)
50 @ContextConfiguration(classes = [ResourceConfigSnapshotService::class,
51 BluePrintPropertyConfiguration::class, BluePrintPropertiesService::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 {
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")
65 private val resourceId = "1"
66 private val resourceType = "ServiceInstance"
67 private val props = mutableMapOf<String, JsonNode>()
68 private val nodeTemplateName = "nodeTemplateName"
70 private val executionRequest = ExecutionServiceInput()
74 cfgSnapshotComponent = ComponentConfigSnapshotsExecutor(cfgSnapshotService)
75 props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_ID] = resourceId.asJsonPrimitive()
76 props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_TYPE] = resourceType.asJsonPrimitive()
79 cfgSnapshotComponent.operationInputs = props
80 cfgSnapshotComponent.bluePrintRuntimeService = bluePrintRuntimeService
81 cfgSnapshotComponent.nodeTemplateName = nodeTemplateName
83 cfgSnapshotComponent.executionServiceInput = executionRequest
84 cfgSnapshotComponent.processId = "12"
85 cfgSnapshotComponent.workflowName = "workflow"
86 cfgSnapshotComponent.stepName = "step"
87 cfgSnapshotComponent.interfaceName = "interfaceName"
88 cfgSnapshotComponent.operationName = "operationName"
92 fun processNBFetchWithResourceIdAndResourceTypeSingleFind() {
93 val snapshot = ResourceConfigSnapshot()
94 val snapshotConfig = "TEST1"
95 snapshot.config_snapshot = snapshotConfig
101 cfgSnapshotService.write(snapshotConfig, resId, resType)
102 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.RUNNING.name)
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.",
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))
121 fun processNBFetchCandidateWithResourceIdAndResourceTypeSingleFind() {
122 val snapshot = ResourceConfigSnapshot()
123 val snapshotConfig = "TEST"
124 snapshot.config_snapshot = snapshotConfig
130 cfgSnapshotService.write(snapshotConfig, resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
131 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.CANDIDATE.name)
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.",
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))
150 fun processNBStoreWithResourceIdAndResourceType() {
151 val snapshot = ResourceConfigSnapshot()
152 val snapshotConfig = "PAYLOAD"
153 snapshot.config_snapshot = snapshotConfig
159 prepareRequestProperties(OPERATION_STORE, resId, resType, snapshotConfig)
161 cfgSnapshotComponent.processNB(executionRequest)
163 } catch (e: BluePrintProcessorException) {
164 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
180 fun processNBFetchNoneFound() {
183 // when; asking for unknown resource Id/ resource Type combo; should get an error response
185 prepareRequestProperties(OPERATION_FETCH, "asdasd", "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
187 cfgSnapshotComponent.processNB(executionRequest)
189 } catch (e: BluePrintProcessorException) {
190 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
195 assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
196 bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
197 ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
202 fun processNBErrorOperationUnknown() {
205 // when; asking for unknown operation update; should get an error response
207 prepareRequestProperties("update", "asdasd", "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
209 cfgSnapshotComponent.processNB(executionRequest)
211 } catch (e: BluePrintProcessorException) {
212 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
230 fun processNBErrorDiffContentTypeUnknown() {
233 // when; asking for unknown content type diff operation; should get an error response
237 cfgSnapshotService.write("snapshotConfig", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
238 prepareRequestProperties(OPERATION_DIFF, resId, resType, "YANG")
240 cfgSnapshotComponent.processNB(executionRequest)
242 } catch (e: BluePrintProcessorException) {
243 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
260 fun processNBCompareTwoJsonConfigSnapshots() {
264 // when; comparing RUNNING vs CANDIDATE json configs; should get an success response; with differences
268 preparePayload("config-payload-running.json", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
269 preparePayload("config-payload-candidate.json", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
271 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_JSON)
272 cfgSnapshotComponent.processNB(executionRequest)
274 } catch (e: BluePrintProcessorException) {
275 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
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))
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))
298 fun processNBCompareTwoXmlConfigSnapshots() {
302 // when; comparing RUNNING vs CANDIDATE xml configs; should get an success response; with differences
306 preparePayload("interface-running.xml", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
307 preparePayload("interface-candidate.xml", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
309 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_XML)
311 cfgSnapshotComponent.processNB(executionRequest)
313 } catch (e: BluePrintProcessorException) {
314 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
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))
325 // then; we should get XML-patches differences in our response property
326 val diffXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
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>" +
334 assertEquals(diffXml.asJsonPrimitive(),
335 bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
336 ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT)) }
339 private fun preparePayload(filename : String, resId : String, resType : String, status: ResourceConfigSnapshot.Status) {
341 cfgSnapshotService.write(JacksonUtils.getClassPathFileContent("payload/requests/$filename"), resId, resType, status)
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()
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()
358 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_DIFF_CONTENT_TYPE] = optional.asJsonPrimitive()
360 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_SNAPSHOT] = optional.asJsonPrimitive()
362 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_STATUS] = optional.asJsonPrimitive()