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.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
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 {
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")
66 private val resourceId = "1"
67 private val resourceType = "ServiceInstance"
68 private val props = mutableMapOf<String, JsonNode>()
69 private val nodeTemplateName = "nodeTemplateName"
71 private val executionRequest = ExecutionServiceInput()
75 cfgSnapshotComponent = ComponentConfigSnapshotsExecutor(cfgSnapshotService)
76 props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_ID] = resourceId.asJsonPrimitive()
77 props[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_TYPE] = resourceType.asJsonPrimitive()
80 cfgSnapshotComponent.operationInputs = props
81 cfgSnapshotComponent.bluePrintRuntimeService = bluePrintRuntimeService
82 cfgSnapshotComponent.nodeTemplateName = nodeTemplateName
84 cfgSnapshotComponent.executionServiceInput = executionRequest
85 cfgSnapshotComponent.processId = "12"
86 cfgSnapshotComponent.workflowName = "workflow"
87 cfgSnapshotComponent.stepName = "step"
88 cfgSnapshotComponent.interfaceName = "interfaceName"
89 cfgSnapshotComponent.operationName = "operationName"
93 fun processNBFetchWithResourceIdAndResourceTypeSingleFind() {
94 val snapshot = ResourceConfigSnapshot()
95 val snapshotConfig = "TEST1"
96 snapshot.config_snapshot = snapshotConfig
102 cfgSnapshotService.write(snapshotConfig, resId, resType)
103 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.RUNNING.name)
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.",
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))
122 fun processNBFetchCandidateWithResourceIdAndResourceTypeSingleFind() {
123 val snapshot = ResourceConfigSnapshot()
124 val snapshotConfig = "TEST"
125 snapshot.config_snapshot = snapshotConfig
131 cfgSnapshotService.write(snapshotConfig, resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
132 prepareRequestProperties(OPERATION_FETCH, resId, resType, ResourceConfigSnapshot.Status.CANDIDATE.name)
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.",
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))
151 fun processNBStoreWithResourceIdAndResourceType() {
152 val snapshot = ResourceConfigSnapshot()
153 val snapshotConfig = "PAYLOAD"
154 snapshot.config_snapshot = snapshotConfig
160 prepareRequestProperties(OPERATION_STORE, resId, resType, snapshotConfig)
162 cfgSnapshotComponent.processNB(executionRequest)
164 } catch (e: BluePrintProcessorException) {
165 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
181 fun processNBFetchNoneFound() {
184 // when; asking for unknown resource Id/ resource Type combo; should get an error response
186 prepareRequestProperties(OPERATION_FETCH, "asdasd", "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
188 cfgSnapshotComponent.processNB(executionRequest)
190 } catch (e: BluePrintProcessorException) {
191 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
196 assertEquals(ComponentConfigSnapshotsExecutor.OUTPUT_STATUS_SUCCESS.asJsonPrimitive(),
197 bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
198 ComponentConfigSnapshotsExecutor.OUTPUT_STATUS))
203 fun processNBErrorOperationUnknown() {
206 // when; asking for unknown operation update; should get an error response
208 prepareRequestProperties("update", "asdasd", "PNF", ResourceConfigSnapshot.Status.RUNNING.name)
210 cfgSnapshotComponent.processNB(executionRequest)
212 } catch (e: BluePrintProcessorException) {
213 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
231 fun processNBErrorDiffContentTypeUnknown() {
234 // when; asking for unknown content type diff operation; should get an error response
238 cfgSnapshotService.write("snapshotConfig", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
239 prepareRequestProperties(OPERATION_DIFF, resId, resType, "YANG")
241 cfgSnapshotComponent.processNB(executionRequest)
243 } catch (e: BluePrintProcessorException) {
244 kotlin.test.assertEquals("Can't proceed with the cfg snapshot lookup: provide resource-id and resource-type.",
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))
261 fun processNBCompareTwoJsonConfigSnapshots() {
265 // when; comparing RUNNING vs CANDIDATE json configs; should get an success response; with differences
269 preparePayload("config-payload-running.json", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
270 preparePayload("config-payload-candidate.json", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
272 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_JSON)
273 cfgSnapshotComponent.processNB(executionRequest)
275 } catch (e: BluePrintProcessorException) {
276 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
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))
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))
299 fun processNBCompareTwoXmlConfigSnapshots() {
303 // when; comparing RUNNING vs CANDIDATE xml configs; should get an success response; with differences
307 preparePayload("interface-running.xml", resId, resType, ResourceConfigSnapshot.Status.RUNNING)
308 preparePayload("interface-candidate.xml", resId, resType, ResourceConfigSnapshot.Status.CANDIDATE)
310 prepareRequestProperties(OPERATION_DIFF, resId, resType, DIFF_XML)
312 cfgSnapshotComponent.processNB(executionRequest)
314 } catch (e: BluePrintProcessorException) {
315 kotlin.test.assertEquals("Can't proceed with the cfg snapshot diff: provide resource-id and resource-type.",
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))
326 // then; we should get XML-patches differences in our response property
327 val diffXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
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>" +
335 assertEquals(diffXml.asJsonPrimitive(),
336 bluePrintRuntimeService.getNodeTemplateAttributeValue(nodeTemplateName,
337 ComponentConfigSnapshotsExecutor.OUTPUT_SNAPSHOT)) }
340 private fun preparePayload(filename : String, resId : String, resType : String, status: ResourceConfigSnapshot.Status) {
342 cfgSnapshotService.write(JacksonUtils.getClassPathFileContent("payload/requests/$filename"), resId, resType, status)
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()
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()
359 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_DIFF_CONTENT_TYPE] = optional.asJsonPrimitive()
361 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_SNAPSHOT] = optional.asJsonPrimitive()
363 cfgSnapshotComponent.operationInputs[ComponentConfigSnapshotsExecutor.INPUT_RESOURCE_STATUS] = optional.asJsonPrimitive()