2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 Nordix Foundation.
4 * Modifications Copyright (c) 2019 IBM, Bell Canada.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
24 import com.fasterxml.jackson.databind.JsonNode
25 import com.fasterxml.jackson.databind.node.NullNode
26 import com.fasterxml.jackson.databind.node.TextNode
29 import org.junit.Before
31 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
32 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
33 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
34 import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
35 import org.onap.ccsdk.cds.controllerblueprints.core.data.EntrySchema
36 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
37 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
38 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
39 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
40 import kotlin.test.assertEquals
42 data class IpAddress(val port: String, val ip: String)
43 data class Host(val name: String, val ipAddress: IpAddress)
44 data class ExpectedResponseIp(val ip: String)
45 data class ExpectedResponsePort(val port: String)
47 class ResourceAssignmentUtilsTest {
48 private lateinit var resourceAssignmentRuntimeService: ResourceAssignmentRuntimeService
53 val bluePrintContext = BluePrintMetadataUtils.getBluePrintContext(
54 "./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
56 resourceAssignmentRuntimeService = spyk(ResourceAssignmentRuntimeService("1234", bluePrintContext))
58 val propertiesDefinition1 = PropertyDefinition().apply {
63 val propertiesDefinition2 = PropertyDefinition().apply {
68 val propertiesDefinition3 = PropertyDefinition().apply {
73 val propertiesDefinition4 = PropertyDefinition().apply {
78 var mapOfPropertiesIpAddress = mutableMapOf<String, PropertyDefinition>()
79 mapOfPropertiesIpAddress["port"] = propertiesDefinition1
80 mapOfPropertiesIpAddress["ip"] = propertiesDefinition2
82 var mapOfPropertiesHost = mutableMapOf<String, PropertyDefinition>()
83 mapOfPropertiesHost["name"] = propertiesDefinition3
84 mapOfPropertiesHost["ipAddress"] = propertiesDefinition4
86 val myDataTypeIpaddress = DataType().apply {
88 properties = mapOfPropertiesIpAddress
91 val myDataTypeHost = DataType().apply {
93 properties = mapOfPropertiesHost
96 every { resourceAssignmentRuntimeService.bluePrintContext().dataTypeByName("ip-address") } returns myDataTypeIpaddress
98 every { resourceAssignmentRuntimeService.bluePrintContext().dataTypeByName("host") } returns myDataTypeHost
100 every { resourceAssignmentRuntimeService.setNodeTemplateAttributeValue(any(), any(), any()) } returns Unit
104 fun `generateResourceDataForAssignments - positive test`() {
105 //given a valid resource assignment
106 val validResourceAssignment = createResourceAssignmentForTest("valid_value")
108 //and a list containing that resource assignment
109 val resourceAssignmentList = listOf<ResourceAssignment>(validResourceAssignment)
111 //when the values of the resources are evaluated
112 val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList)
114 //then the assignment should produce a valid result
115 val expected = "{\n" + " \"pnf-id\" : \"valid_value\"\n" + "}"
116 assertEquals(expected, outcome, "unexpected outcome generated")
120 fun `generateResourceDataForAssignments - resource without value is not resolved as null`() {
121 //given a valid resource assignment
122 val resourceAssignmentWithNullValue = createResourceAssignmentForTest(null)
124 //and a list containing that resource assignment
125 val resourceAssignmentList = listOf<ResourceAssignment>(resourceAssignmentWithNullValue)
127 //when the values of the resources are evaluated
128 val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList)
130 //then the assignment should produce a valid result
131 val expected = "{\n" + " \"pnf-id\" : \"\${pnf-id}\"\n" + "}"
132 assertEquals(expected, outcome, "unexpected outcome generated")
136 private fun createResourceAssignmentForTest(resourceValue: String?): ResourceAssignment {
137 val valueForTest = if (resourceValue == null) null else TextNode(resourceValue)
138 val resourceAssignmentForTest = ResourceAssignment().apply {
140 dictionaryName = "pnf-id"
141 dictionarySource = "input"
142 property = PropertyDefinition().apply {
147 return resourceAssignmentForTest
151 fun parseResponseNodeTestForPrimitivesTypes(){
152 // Input values for primitive type
153 val keyValue = mutableMapOf<String, String>()
154 keyValue["value"]= "1.2.3.1"
155 val expectedPrimitiveType = TextNode("1.2.3.1")
157 var outcome = prepareResponseNodeForTest("sample-value", "string",
158 "", "1.2.3.1".asJsonPrimitive())
159 assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of simple String")
160 outcome = prepareResponseNodeForTest("sample-key-value", "string", "", keyValue)
161 assertEquals(expectedPrimitiveType, outcome, "Unexpected outcome returned for primitive type of key-value String")
165 fun parseResponseNodeTestForCollectionsOfString(){
166 // Input values for collection type
167 val mapOfString = mutableMapOf<String, String>()
168 mapOfString["value1"] = "1.2.3.1"
169 mapOfString["port"] = "8888"
170 mapOfString["value2"] = "1.2.3.2"
171 val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"),
172 ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2"))
174 val mutableMapKeyValue = mutableMapOf<String, String>()
175 mutableMapKeyValue["value1"] = "1.2.3.1"
176 mutableMapKeyValue["port"] = "8888"
179 val expectedListOfString = arrayOfKeyValue.asJsonType()
180 var outcome = prepareResponseNodeForTest("listOfString", "list",
181 "string", mapOfString.asJsonType())
182 assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String")
185 val expectedMapOfString = mutableMapOf<String, JsonNode>()
186 expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive()
187 expectedMapOfString["port"] = "8888".asJsonPrimitive()
189 val arrayNode = JacksonUtils.objectMapper.createArrayNode()
190 expectedMapOfString.map {
191 val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
192 arrayChildNode.set(it.key, it.value)
193 arrayNode.add(arrayChildNode)
195 val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode()
196 arrayChildNode1.set("ip", NullNode.getInstance())
197 arrayNode.add(arrayChildNode1)
198 outcome = prepareResponseNodeForTest("mapOfString", "map", "string",
199 mutableMapKeyValue.asJsonType())
200 assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String")
204 fun parseResponseNodeTestForCollectionsOfJsonNode(){
205 // Input values for collection type
206 val mapOfString = mutableMapOf<String, JsonNode>()
207 mapOfString["value1"] = "1.2.3.1".asJsonPrimitive()
208 mapOfString["port"] = "8888".asJsonPrimitive()
209 mapOfString["value2"] = "1.2.3.2".asJsonPrimitive()
210 val arrayOfKeyValue = arrayListOf(ExpectedResponseIp("1.2.3.1"),
211 ExpectedResponsePort( "8888"), ExpectedResponseIp("1.2.3.2"))
213 val mutableMapKeyValue = mutableMapOf<String, JsonNode>()
214 mutableMapKeyValue["value1"] = "1.2.3.1".asJsonPrimitive()
215 mutableMapKeyValue["port"] = "8888".asJsonPrimitive()
218 val expectedListOfString = arrayOfKeyValue.asJsonType()
219 var outcome = prepareResponseNodeForTest("listOfString", "list",
220 "string", mapOfString.asJsonType())
221 assertEquals(expectedListOfString, outcome, "unexpected outcome returned for list of String")
224 val expectedMapOfString = mutableMapOf<String, JsonNode>()
225 expectedMapOfString["ip"] = "1.2.3.1".asJsonPrimitive()
226 expectedMapOfString["port"] = "8888".asJsonPrimitive()
227 val arrayNode = JacksonUtils.objectMapper.createArrayNode()
228 expectedMapOfString.map {
229 val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
230 arrayChildNode.set(it.key, it.value)
231 arrayNode.add(arrayChildNode)
233 val arrayChildNode1 = JacksonUtils.objectMapper.createObjectNode()
234 arrayChildNode1.set("ip", NullNode.getInstance())
235 arrayNode.add(arrayChildNode1)
236 outcome = prepareResponseNodeForTest("mapOfString", "map",
237 "string", mutableMapKeyValue.asJsonType())
238 assertEquals(arrayNode, outcome, "unexpected outcome returned for map of String")
242 fun parseResponseNodeTestForCollectionsOfComplexType(){
243 // Input values for collection type
244 val mapOfComplexType = mutableMapOf<String, JsonNode>()
245 mapOfComplexType["value1"] = IpAddress("1111", "1.2.3.1").asJsonType()
246 mapOfComplexType["value2"] = IpAddress("2222", "1.2.3.2").asJsonType()
247 mapOfComplexType["value3"] = IpAddress("3333", "1.2.3.3").asJsonType()
250 val arrayNode = JacksonUtils.objectMapper.createArrayNode()
251 mapOfComplexType.map {
252 val arrayChildNode = JacksonUtils.objectMapper.createObjectNode()
253 arrayChildNode.set("ipAddress", it.value)
254 arrayNode.add(arrayChildNode)
256 var outcome = prepareResponseNodeForTest("listOfMyDataType", "list",
257 "ip-address", mapOfComplexType.asJsonType())
258 assertEquals(arrayNode, outcome, "unexpected outcome returned for list of String")
262 fun `parseResponseNodeTestForComplexType find one output key mapping`(){
263 // Input values for complex type
264 val objectNode = JacksonUtils.objectMapper.createObjectNode()
266 // Input values for collection type
267 val mapOfComplexType = mutableMapOf<String, JsonNode>()
268 mapOfComplexType["value"] = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()
269 mapOfComplexType["port"] = "8888".asJsonType()
270 mapOfComplexType["something"] = "1.2.3.2".asJsonType()
272 val expectedComplexType = objectNode.set("ipAddress", Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType())
273 val outcome = prepareResponseNodeForTest("complexTypeOneKeys", "host",
274 "", mapOfComplexType.asJsonType())
275 assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type")
279 fun `parseResponseNodeTestForComplexType find all output key mapping`(){
280 // Input values for complex type
281 val objectNode = JacksonUtils.objectMapper.createObjectNode()
283 // Input values for collection type
284 val mapOfComplexType = mutableMapOf<String, JsonNode>()
285 mapOfComplexType["name"] = "my-ipAddress".asJsonType()
286 mapOfComplexType["ipAddress"] = IpAddress("1111", "1.2.3.1").asJsonType()
288 val expectedComplexType = Host("my-ipAddress", IpAddress("1111", "1.2.3.1")).asJsonType()
289 val outcome = prepareResponseNodeForTest("complexTypeAllKeys", "host",
290 "", mapOfComplexType.asJsonType())
291 assertEquals(expectedComplexType, outcome, "Unexpected outcome returned for complex type")
294 private fun prepareResponseNodeForTest(dictionary_source: String, sourceType: String, entrySchema: String,
295 response: Any): JsonNode {
297 val resourceAssignment = when (sourceType) {
299 prepareRADataDictionaryCollection(dictionary_source, sourceType, entrySchema)
302 prepareRADataDictionaryOfPrimaryType(dictionary_source)
305 prepareRADataDictionaryComplexType(dictionary_source, sourceType, entrySchema)
309 val responseNode = checkNotNull(JacksonUtils.getJsonNode(response)) {
310 "Failed to get database query result into Json node."
313 val outputKeyMapping = prepareOutputKeyMapping(dictionary_source)
315 return ResourceAssignmentUtils.parseResponseNode(responseNode, resourceAssignment, resourceAssignmentRuntimeService, outputKeyMapping)
318 private fun prepareRADataDictionaryOfPrimaryType(dictionary_source: String): ResourceAssignment {
319 return ResourceAssignment().apply {
321 dictionaryName = "sample-ip"
322 dictionarySource = "$dictionary_source"
323 property = PropertyDefinition().apply {
329 private fun prepareRADataDictionaryCollection(dictionary_source: String, sourceType: String, schema: String): ResourceAssignment {
330 return ResourceAssignment().apply {
331 name = "ipAddress-list"
332 dictionaryName = "sample-licenses"
333 dictionarySource = "$dictionary_source"
334 property = PropertyDefinition().apply {
336 entrySchema = EntrySchema().apply {
343 private fun prepareRADataDictionaryComplexType(dictionary_source: String, sourceType: String, schema: String): ResourceAssignment {
344 return ResourceAssignment().apply {
345 name = "ipAddress-complexType"
346 dictionaryName = "sample-licenses"
347 dictionarySource = "$dictionary_source"
348 property = PropertyDefinition().apply {
354 private fun prepareOutputKeyMapping(dictionary_source: String): MutableMap<String, String> {
355 val outputMapping = mutableMapOf<String, String>()
357 when (dictionary_source) {
358 "listOfString", "mapOfString" -> {
360 outputMapping["value1"] = "ip"
361 outputMapping["port"] = "port"
362 outputMapping["value2"] = "ip"
364 "listOfMyDataType", "mapOfMyDataType" -> {
365 //List or map of complex Type
366 outputMapping["value1"] = "ipAddress"
367 outputMapping["value2"] = "ipAddress"
368 outputMapping["value3"] = "ipAddress"
370 "sample-key-value", "sample-value" -> {
372 if (dictionary_source=="sample-key-value")
373 outputMapping["sample-ip"] = "value"
377 if (dictionary_source == "complexTypeOneKeys")
378 outputMapping["value"] = "ipAddress"
380 outputMapping["name"] = "name"
381 outputMapping["ipAddress"] = "ipAddress"