Resource Resoulution Service
authorSingal, Kapil (ks220y) <ks220y@att.com>
Thu, 10 Jan 2019 17:50:06 +0000 (12:50 -0500)
committerSingal, Kapil (ks220y) <ks220y@att.com>
Fri, 11 Jan 2019 15:08:58 +0000 (10:08 -0500)
Implement Input Resource Resolution Processor Service along with Resource Resolution Utilities

Change-Id: Ibb4899e415f4b79cd6cd1b190b0f4969b09c3fe4
Issue-ID: CCSDK-936
Signed-off-by: Singal, Kapil (ks220y) <ks220y@att.com>
ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtils.kt
ms/blueprintsprocessor/functions/python-executor/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/python/executor/utils/PythonExecutorUtilsTest.kt
ms/blueprintsprocessor/functions/python-executor/src/test/resources/requests/sample-activate-request.json [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt [new file with mode: 0644]
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/InputResourceAssignmentProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/utils/ResourceResolutionUtils.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/resources/payload/requests/sample-resourceresolution-request.json

index 66c919d..341ede5 100644 (file)
@@ -20,6 +20,7 @@ import org.onap.ccsdk.apps.blueprintsprocessor.services.execution.AbstractCompon
 import org.python.core.PyObject
 import org.python.util.PythonInterpreter
 import org.slf4j.LoggerFactory
+import java.io.File
 import java.util.*
 
 class PythonExecutorUtils {
@@ -61,9 +62,9 @@ class PythonExecutorUtils {
             sb.append(System.getProperty("java.class.path"))
 
             for (p in pythonPath) {
-                sb.append(":").append(p)
+                sb.append(File.pathSeparator).append(p)
             }
-            log.debug("Paths : $sb")
+            log.debug("Python Paths : $sb")
 
             props["python.import.site"] = "true"
             props.setProperty("python.path", sb.toString())
index 431c6b8..c4fd546 100644 (file)
@@ -30,7 +30,7 @@ class PythonExecutorUtilsTest {
     @Test
     fun testGetPythonComponent() {
 
-        val pythonPath: MutableList<String> = arrayListOf()
+        val pythonPath: MutableList<String> = mutableListOf()
         pythonPath.add("./../../../../components/scripts/python/ccsdk_blueprints")
 
         val properties: MutableMap<String, Any> = hashMapOf()
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/test/resources/requests/sample-activate-request.json b/ms/blueprintsprocessor/functions/python-executor/src/test/resources/requests/sample-activate-request.json
new file mode 100644 (file)
index 0000000..7142f04
--- /dev/null
@@ -0,0 +1,31 @@
+{\r
+  "actionIdentifiers": {\r
+    "actionName": "activate",\r
+    "blueprintName": "baseconfiguration",\r
+    "blueprintVersion": "1.0.0",\r
+    "mode": "sync"\r
+  },\r
+  "commonHeader": {\r
+    "flags": {\r
+      "force": true,\r
+      "ttl": 3600\r
+    },\r
+    "originatorId": "sdnc",\r
+    "requestId": "123456-1000",\r
+    "subRequestId": "sub-123456-1000",\r
+    "timestamp": "2012-04-23T18:25:43.511Z"\r
+  },\r
+  "payload": {\r
+    "resource-assignment-request": {\r
+      "resource-assignment-properties": {\r
+        "request-id": "1234",\r
+        "service-instance-id": "siid_1234",\r
+        "vnf-id": "vnf_1234",\r
+        "action-name": "assign-activate",\r
+        "scope-type": "vnf-type",\r
+        "hostname": "localhost",\r
+        "vnf_name": "temp_vnf"\r
+      }\r
+    }\r
+  }\r
+}\r
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/ResourceAssignmentRuntimeService.kt
new file mode 100644 (file)
index 0000000..9d6f4a6
--- /dev/null
@@ -0,0 +1,58 @@
+package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.DefaultBluePrintRuntimeService\r
+\r
+class ResourceAssignmentRuntimeService(private var id: String, private var bluePrintContext: BluePrintContext)\r
+    : DefaultBluePrintRuntimeService(id, bluePrintContext){\r
+\r
+    private var resourceResolutionStore: MutableMap<String, JsonNode> = hashMapOf()\r
+\r
+    override fun getExecutionContext(): MutableMap<String, JsonNode> {\r
+        return resourceResolutionStore\r
+    }\r
+\r
+    @Suppress("UNCHECKED_CAST")\r
+    override fun setExecutionContext(executionContext: MutableMap<String, JsonNode>) {\r
+        this.resourceResolutionStore = executionContext\r
+    }\r
+\r
+    override fun put(key: String, value: JsonNode) {\r
+        resourceResolutionStore[key] = value\r
+    }\r
+\r
+    override fun get(key: String): JsonNode {\r
+        return resourceResolutionStore[key] ?: throw BluePrintProcessorException("failed to get execution property($key)")\r
+    }\r
+\r
+    override fun check(key: String): Boolean {\r
+        return resourceResolutionStore.containsKey(key)\r
+    }\r
+\r
+    override fun cleanRuntime() {\r
+        resourceResolutionStore.clear()\r
+    }\r
+\r
+    private fun getJsonNode(key: String): JsonNode {\r
+        return get(key)\r
+    }\r
+\r
+    override fun getAsString(key: String): String? {\r
+        return get(key).asText()\r
+    }\r
+\r
+    override fun getAsBoolean(key: String): Boolean? {\r
+        return get(key).asBoolean()\r
+    }\r
+\r
+    override fun getAsInt(key: String): Int? {\r
+        return get(key).asInt()\r
+    }\r
+\r
+    override fun getAsDouble(key: String): Double? {\r
+        return get(key).asDouble()\r
+    }\r
+\r
+}\r
index 9d47600..ccf3aee 100644 (file)
 
 package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.processor
 
+import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.utils.ResourceResolutionUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.*
 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
 import org.springframework.stereotype.Service
+import com.fasterxml.jackson.databind.node.NullNode
 
 /**
  * InputResourceAssignmentProcessor
@@ -33,6 +36,20 @@ open class InputResourceAssignmentProcessor : ResourceAssignmentProcessor() {
     }
 
     override fun process(executionRequest: ResourceAssignment) {
+        try {
+            if (checkNotEmpty(executionRequest.name)) {
+                val value = bluePrintRuntimeService!!.getInputValue(executionRequest.name)
+                // if value is null don't call setResourceDataValue to populate the value
+                if (value != null && value !is NullNode) {
+                    ResourceResolutionUtils.setResourceDataValue(executionRequest, value)
+                }
+            }
+            // Check the value has populated for mandatory case
+            ResourceResolutionUtils.assertTemplateKeyValueNotNull(executionRequest)
+        } catch (e: Exception) {
+            ResourceResolutionUtils.setFailedResourceDataValue(executionRequest, e.message)
+            throw BluePrintProcessorException("Failed in template key ($executionRequest) assignments with : (${e.message})", e)
+        }
     }
 
     override fun recover(runtimeException: RuntimeException, executionRequest: ResourceAssignment) {
index 6bcd21b..7c59088 100644 (file)
 
 package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.utils
 
+import java.util.Date
+import org.apache.commons.lang3.StringUtils
+import com.att.eelf.configuration.EELFLogger
+import com.att.eelf.configuration.EELFManager
 import com.fasterxml.jackson.databind.JsonNode
-import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.databind.node.NullNode
+import com.fasterxml.jackson.databind.node.ObjectNode
+import org.onap.ccsdk.apps.controllerblueprints.core.*
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
 
 class ResourceResolutionUtils {
     companion object {
 
+        private val logger: EELFLogger = EELFManager.getInstance().getLogger(ResourceResolutionUtils::class.toString())
+
+        @Synchronized
+        @Throws(BluePrintProcessorException::class)
+        fun setResourceDataValue(resourceAssignment: ResourceAssignment, value: Any?) {
+
+            val resourceProp = checkNotNull(resourceAssignment.property) { "Failed in setting resource value for resource mapping $resourceAssignment" }
+            checkNotEmptyNThrow(resourceAssignment.name, "Failed in setting resource value for resource mapping $resourceAssignment")
+
+            if (checkNotEmpty(resourceAssignment.dictionaryName)) {
+                resourceAssignment.dictionaryName = resourceAssignment.name
+                logger.warn("Missing dictionary key, setting with template key (${resourceAssignment.name}) as dictionary key (${resourceAssignment.dictionaryName})")
+            }
+
+            try {
+                if (checkNotEmpty(resourceProp.type)) {
+                    val convertedValue = convertResourceValue(resourceProp.type, value)
+                    logger.info("Setting Resource Value ($convertedValue) for Resource Name (${resourceAssignment.dictionaryName}) of type (${resourceProp.type})")
+                    resourceProp.value = convertedValue
+                    resourceAssignment.updatedDate = Date()
+                    resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
+                    resourceAssignment.status = BluePrintConstants.STATUS_SUCCESS
+                }
+            } catch (e: Exception) {
+                throw BluePrintProcessorException("Failed in setting value for template key (%s) and " +
+                        "dictionary key (${resourceAssignment.name}) of type (${resourceProp.type}) with error message (${e.message})", e)
+            }
+        }
+
+        private fun convertResourceValue(type: String, value: Any?): JsonNode? {
+            var convertedValue: JsonNode?
+
+            if (value == null || value is NullNode) {
+                logger.info("Returning {} value from convertResourceValue", value)
+                return null
+            } else if (BluePrintTypes.validPrimitiveTypes().contains(type) && value is String) {
+                convertedValue = JacksonUtils.convertPrimitiveResourceValue(type, value)
+            } else {
+                // Case where Resource is non-primitive type
+                if (value is String) {
+                    convertedValue = JacksonUtils.jsonNode(value)
+                } else {
+                    convertedValue = JacksonUtils.getJsonNode(value)
+                }
+            }
+            return convertedValue
+        }
+
+        @Synchronized
+        fun setFailedResourceDataValue(resourceAssignment: ResourceAssignment, message: String?) {
+            if (checkNotEmpty(resourceAssignment.name)) {
+                resourceAssignment.updatedDate = Date()
+                resourceAssignment.updatedBy = BluePrintConstants.USER_SYSTEM
+                resourceAssignment.status = BluePrintConstants.STATUS_FAILURE
+                resourceAssignment.message = message
+            }
+        }
+
+        @Synchronized
+        @Throws(BluePrintProcessorException::class)
+        fun assertTemplateKeyValueNotNull(resourceAssignment: ResourceAssignment) {
+            val resourceProp = checkNotNull(resourceAssignment.property) { "Failed to populate mandatory resource resource mapping $resourceAssignment" }
+            if (resourceProp.required != null && resourceProp.required!! && (resourceProp.value == null || resourceProp.value !is NullNode)) {
+                logger.error("failed to populate mandatory resource mapping ($resourceAssignment)")
+                throw BluePrintProcessorException("failed to populate mandatory resource mapping ($resourceAssignment)")
+            }
+        }
+
+        @Synchronized
+        @Throws(BluePrintProcessorException::class)
+        fun generateResourceDataForAssignments(assignments: List<ResourceAssignment>): String {
+            var result = "{}"
+            try {
+                val mapper = ObjectMapper()
+                val root = mapper.readTree(result)
+
+                assignments.forEach {
+                    if (checkNotEmpty(it.name) && it.property != null) {
+
+                        val type = it.property?.type
+                        val value = it.property?.value
+                        logger.info("Generating Resource name ({}), type ({}), value ({})", it.name, type,
+                                value)
+                        if (value == null) {
+                            (root as ObjectNode).set(it.name, null)
+                        } else if (value is JsonNode) {
+                            (root as ObjectNode).put(it.name, value as JsonNode)
+                        } else if (BluePrintConstants.DATA_TYPE_STRING.equals(type, ignoreCase = true)) {
+                            (root as ObjectNode).put(it.name, value as String)
+                        } else if (BluePrintConstants.DATA_TYPE_BOOLEAN.equals(type, ignoreCase = true)) {
+                            (root as ObjectNode).put(it.name, value as Boolean)
+                        } else if (BluePrintConstants.DATA_TYPE_INTEGER.equals(type, ignoreCase = true)) {
+                            (root as ObjectNode).put(it.name, value as Int)
+                        } else if (BluePrintConstants.DATA_TYPE_FLOAT.equals(type, ignoreCase = true)) {
+                            (root as ObjectNode).put(it.name, value as Float)
+                        } else if (BluePrintConstants.DATA_TYPE_TIMESTAMP.equals(type, ignoreCase = true)) {
+                            (root as ObjectNode).put(it.name, value as String)
+                        } else {
+                            val jsonNode = JacksonUtils.getJsonNode(value)
+                            if (jsonNode != null) {
+                                (root as ObjectNode).put(it.name, jsonNode)
+                            } else {
+                                (root as ObjectNode).set(it.name, null)
+                            }
+                        }
+                    }
+                }
+                result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root)
+                logger.info("Generated Resource Param Data ({})", result)
+            } catch (e: Exception) {
+                throw BluePrintProcessorException("kapil is failing with $e.message", e)
+            }
+
+            return result
+        }
+
         fun <T> transformResourceSource(properties: MutableMap<String, JsonNode>, classType: Class<T>): T {
             val content = JacksonUtils.getJson(properties)
             return JacksonUtils.readValue(content, classType)
                     ?: throw BluePrintProcessorException("failed to transform content($content) to type($classType)")
         }
+
     }
 }
\ No newline at end of file
index 7f41ba1..46ccb97 100644 (file)
@@ -19,8 +19,11 @@ package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution
 import org.junit.Assert
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.onap.ccsdk.apps.blueprintsprocessor.core.api.data.ExecutionServiceInput
+import org.onap.ccsdk.apps.blueprintsprocessor.core.utils.PayloadUtils
 import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.processor.*
 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.test.context.ContextConfiguration
@@ -62,6 +65,12 @@ class ResourceResolutionServiceTest {
         val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("1234",
                 "./../../../../components/model-catalog/blueprint-model/starter-blueprint/baseconfiguration")
 
+        val executionServiceInput = JacksonUtils.readValueFromClassPathFile("payload/requests/sample-resourceresolution-request.json",
+                ExecutionServiceInput::class.java)!!
+
+        // Prepare Inputs
+        PayloadUtils.prepareInputsFromWorkflowPayload(bluePrintRuntimeService, executionServiceInput.payload, "resource-assignment")
+
         resourceResolutionService.resolveResources(bluePrintRuntimeService, "resource-assignment", "baseconfig")
 
     }
index 7889a7e..c4fe4ea 100644 (file)
     "resource-assignment-request": {\r
       "resource-assignment-properties": {\r
         "request-id": "1234",\r
+        "service-instance-id": "siid_1234",\r
+        "vnf-id": "vnf_1234",\r
         "action-name": "assign-activate",\r
         "scope-type": "vnf-type",\r
-        "hostname": "localhost"\r
+        "hostname": "localhost",\r
+        "vnf_name": "temp_vnf"\r
       }\r
     }\r
   }\r