Returning null for unresolved variables 19/88419/6
authorottero <rodrigo.ottero@est.tech>
Tue, 28 May 2019 09:25:45 +0000 (09:25 +0000)
committerottero <rodrigo.ottero@est.tech>
Tue, 28 May 2019 09:25:45 +0000 (09:25 +0000)
When Blueprints Processor was not able to evaluate a variable, it would
set its value to null.

The expected behaviour would be to set the value to the default repres-
entation in the formal notation as defined by Apache Velocity, which is
a dollar followed by the name of the variable between curly braces. For
example, if the value of the variable pnf-id could not be evaluated in
runtime, its value would be defined as the string "${pnf-id}".

The problem happened during evaluation of the variables that would be
later sent to the template-meshing code for processing.

The fix was to add a check before the value was assigned to the varia-
ble; if the was not null, the assignment will happen normally. Otherwi-
se, if the evaluation resolves to null, the variable receives the defa-
ult value (string "${<variable name>}").

Besides the tests that were put in place to test the code changed for
this fix, two tests were added to the existing test case of the templa-
te meshing code, to act as regression test.

Change-Id: I635afb1eba4c0d45b821811f0119fa6c87ea9542
Issue-ID: CCSDK-1358
Signed-off-by: ottero <rodrigo.ottero@est.tech>
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtils.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt
ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json [new file with mode: 0755]
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl [new file with mode: 0755]

index 656e861..1a943d1 100644 (file)
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.node.NullNode
 import com.fasterxml.jackson.databind.node.ObjectNode
+import com.fasterxml.jackson.databind.node.TextNode
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.*
@@ -122,7 +123,7 @@ class ResourceAssignmentUtils {
                     if (isNotEmpty(it.name) && it.property != null) {
                         val rName = it.name
                         val type = nullToEmpty(it.property?.type).toLowerCase()
-                        val value = it.property?.value
+                        val value = useDefaultValueIfNull(it, rName)
                         logger.info("Generating Resource name ($rName), type ($type), value ($value)")
                         root.set(rName, value)
                     }
@@ -136,6 +137,15 @@ class ResourceAssignmentUtils {
             return result
         }
 
+        private fun useDefaultValueIfNull(resourceAssignment: ResourceAssignment, resourceAssignmentName: String): JsonNode {
+            if (resourceAssignment.property?.value == null) {
+                val defaultValue = "\${$resourceAssignmentName}"
+                return TextNode(defaultValue)
+            } else {
+                return resourceAssignment.property!!.value!!
+            }
+        }
+
         fun transformToRARuntimeService(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                         templateArtifactName: String): ResourceAssignmentRuntimeService {
 
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/utils/ResourceAssignmentUtilsTest.kt
new file mode 100644 (file)
index 0000000..9b87c12
--- /dev/null
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+
+package org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.utils
+
+import com.fasterxml.jackson.databind.node.TextNode
+import org.junit.Test
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
+import kotlin.test.assertEquals
+
+class ResourceAssignmentUtilsTest {
+
+    @Test
+    fun `generateResourceDataForAssignments - positive test`() {
+        //given a valid resource assignment
+        val validResourceAssignment = createResourceAssignmentForTest("valid_value")
+
+        //and a list containing that resource assignment
+        val resourceAssignmentList = listOf<ResourceAssignment>(validResourceAssignment)
+
+        //when the values of the resources are evaluated
+        val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList)
+
+        //then the assignment should produce a valid result
+        val expected = "{\n" + "  \"pnf-id\" : \"valid_value\"\n" + "}"
+        assertEquals(expected, outcome, "unexpected outcome generated")
+
+    }
+
+    @Test
+    fun `generateResourceDataForAssignments - resource without value is not resolved as null`() {
+        //given a valid resource assignment
+        val resourceAssignmentWithNullValue = createResourceAssignmentForTest(null)
+
+        //and a list containing that resource assignment
+        val resourceAssignmentList = listOf<ResourceAssignment>(resourceAssignmentWithNullValue)
+
+        //when the values of the resources are evaluated
+        val outcome = ResourceAssignmentUtils.generateResourceDataForAssignments(resourceAssignmentList)
+
+        //then the assignment should produce a valid result
+        val expected = "{\n" + "  \"pnf-id\" : \"\${pnf-id}\"\n" + "}"
+        assertEquals(expected, outcome, "unexpected outcome generated")
+
+    }
+
+    private fun createResourceAssignmentForTest(resourceValue: String?): ResourceAssignment {
+        val valueForTest = if (resourceValue == null) null else TextNode(resourceValue)
+        val resourceAssignmentForTest = ResourceAssignment().apply {
+            name = "pnf-id"
+            dictionaryName = "pnf-id"
+            dictionarySource = "input"
+            property = PropertyDefinition().apply {
+                type = "string"
+                value = valueForTest
+            }
+        }
+        return resourceAssignmentForTest
+    }
+}
\ No newline at end of file
index 02505ac..6f961c8 100644 (file)
@@ -26,6 +26,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.test.context.junit4.SpringRunner
 import kotlin.test.BeforeTest
+import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
 @RunWith(SpringRunner::class)
@@ -97,5 +98,39 @@ class BluePrintTemplateServiceTest {
             assertNotNull(content, "failed to generate content for velocity template")
         }
     }
+
+    @Test
+    fun `no value variable should evaluate to default value - standalone template mesh test`() {
+        runBlocking {
+            val template = JacksonUtils.getClassPathFileContent("templates/default-variable-value-velocity-template.vtl")
+            val json = JacksonUtils.getClassPathFileContent("templates/default-variable-value-data.json")
+
+            val content = BluePrintVelocityTemplateService.generateContent(template, json)
+            //first line represents a variable whose value was successfully retrieved, second line contains a variable
+            // whose value could not be evaluated
+            val expected = "sample-hostname\n\${node0_backup_router_address}"
+            assertEquals(expected, content, "No value variable should use default value")
+        }
+    }
+
+    @Test
+    fun `no value variable should evaluate to default value - blueprint processing test`() {
+        runBlocking {
+            val bluePrintTemplateService = BluePrintTemplateService()
+
+            val templateFile = "templates/default-variable-value-velocity-template.vtl"
+            val jsonFile = "templates/default-variable-value-data.json"
+
+            val content = bluePrintTemplateService.generateContentFromFiles(templateFile,
+                    BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, jsonFile, false, mutableMapOf())
+
+            //first line represents a variable whose value was successfully retrieved, second line contains a variable
+            // whose value could not be evaluated
+            val expected = "sample-hostname\n\${node0_backup_router_address}"
+            assertEquals(expected, content, "No value variable should use default value")
+        }
+
+    }
+
 }
 
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-data.json
new file mode 100755 (executable)
index 0000000..940ca8d
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "node0_hostname": "sample-hostname"
+}
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/default-variable-value-velocity-template.vtl
new file mode 100755 (executable)
index 0000000..ce2458e
--- /dev/null
@@ -0,0 +1,2 @@
+$node0_hostname
+${node0_backup_router_address}
\ No newline at end of file