Bug fixes request input default value 73/91173/3
authorBrinda Santh <brindasanth@in.ibm.com>
Wed, 10 Jul 2019 16:10:17 +0000 (12:10 -0400)
committerBrinda Santh <brindasanth@in.ibm.com>
Thu, 11 Jul 2019 00:02:59 +0000 (20:02 -0400)
Change-Id: I16afd71c2c35b7f270577ea784a9173ea3e0d604
Issue-ID: CCSDK-1357
Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
ms/blueprintsprocessor/functions/ansible-awx-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/ansible/executor/ComponentRemoteAnsibleExecutor.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt

index 63998dd..947a963 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright © 2019 Bell Canada.
+ *  Modifications Copyright © 2018-2019 IBM.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -18,21 +19,24 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor
 
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.databind.node.ObjectNode
-import java.net.URI
-import java.net.URLEncoder
-import java.util.NoSuchElementException
-import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.*
+import com.fasterxml.jackson.databind.node.TextNode
+import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
-import org.onap.ccsdk.cds.controllerblueprints.core.*
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString
+import org.onap.ccsdk.cds.controllerblueprints.core.isNotNull
+import org.onap.ccsdk.cds.controllerblueprints.core.rootFieldsToMap
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.slf4j.LoggerFactory
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
 import org.springframework.context.annotation.Scope
 import org.springframework.http.HttpMethod
 import org.springframework.stereotype.Component
+import java.net.URI
+import java.net.URLEncoder
+import java.util.*
 
 /**
  * ComponentRemoteAnsibleExecutor
@@ -99,7 +103,7 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
 
     override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
         val message = "Error in ComponentRemoteAnsibleExecutor : ${runtimeException.message}"
-        log.error(message,runtimeException)
+        log.error(message, runtimeException)
         setNodeOutputErrors(ATTRIBUTE_EXEC_CMD_STATUS_ERROR, message)
     }
 
@@ -123,7 +127,7 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
 
         try {
             return blueprintRestLibPropertyService.blueprintWebClientService(endpointSelector)
-        } catch (e : NoSuchElementException) {
+        } catch (e: NoSuchElementException) {
             throw IllegalArgumentException("No value provided for input selector $endpointSelector", e)
         }
     }
@@ -131,13 +135,13 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
     /**
      * Finds the job template ID based on the job template name provided in the request
      */
-    private fun lookupJobTemplateIDByName(awxClient : BlueprintWebClientService, job_template_name: String?): String {
-        val encodedJTName = URI(null,null,
+    private fun lookupJobTemplateIDByName(awxClient: BlueprintWebClientService, job_template_name: String?): String {
+        val encodedJTName = URI(null, null,
                 "/api/v2/job_templates/${job_template_name}/",
-                null,null).rawPath
+                null, null).rawPath
 
         // Get Job Template details by name
-        var response = awxClient.exchangeResource(GET, encodedJTName,"")
+        var response = awxClient.exchangeResource(GET, encodedJTName, "")
         val jtDetails: JsonNode = mapper.readTree(response.body)
         return jtDetails.at("/id").asText()
     }
@@ -148,18 +152,18 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
      * its execution. Finally, it retrieves the job results via the stdout api.
      * The status and output attributes are populated in the process.
      */
-    private fun runJobTemplateOnAWX(awxClient : BlueprintWebClientService, job_template_name: String?, jtId: String) {
-        setNodeOutputProperties( "preparing".asJsonPrimitive(), "".asJsonPrimitive())
+    private fun runJobTemplateOnAWX(awxClient: BlueprintWebClientService, job_template_name: String?, jtId: String) {
+        setNodeOutputProperties("preparing".asJsonPrimitive(), "".asJsonPrimitive())
 
         // Get Job Template requirements
-        var response = awxClient.exchangeResource(GET, "/api/v2/job_templates/${jtId}/launch/","")
+        var response = awxClient.exchangeResource(GET, "/api/v2/job_templates/${jtId}/launch/", "")
         // FIXME: handle non-successful SC
         val jtLaunchReqs: JsonNode = mapper.readTree(response.body)
-        var payload = prepareLaunchPayload(awxClient, jtLaunchReqs)
+        val payload = prepareLaunchPayload(awxClient, jtLaunchReqs)
         log.info("Running job with $payload, for requestId $processId.")
 
         // Launch the job for the targeted template
-        var jtLaunched : JsonNode = JacksonUtils.jsonNode("{}") as ObjectNode
+        var jtLaunched: JsonNode = JacksonUtils.objectMapper.createObjectNode()
         response = awxClient.exchangeResource(POST, "/api/v2/job_templates/${jtId}/launch/", payload)
         if (response.status in HTTP_SUCCESS) {
             jtLaunched = mapper.readTree(response.body)
@@ -188,9 +192,9 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
             // Get job execution results (stdout)
             val plainTextHeaders = mutableMapOf<String, String>()
             plainTextHeaders["Content-Type"] = "text/plain ;utf-8"
-            response = awxClient.exchangeResource(GET, "/api/v2/jobs/${jobId}/stdout/?format=txt","", plainTextHeaders)
+            response = awxClient.exchangeResource(GET, "/api/v2/jobs/${jobId}/stdout/?format=txt", "", plainTextHeaders)
 
-            setNodeOutputProperties( jobStatus.asJsonPrimitive(), response.body.asJsonPrimitive())
+            setNodeOutputProperties(jobStatus.asJsonPrimitive(), response.body.asJsonPrimitive())
         } else {
             // The job template requirements were not fulfilled with the values passed in. The message below will
             // provide more information via the response, like the ignored_fields, or variables_needed_to_start,
@@ -198,7 +202,7 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
             val message = "Execution of job template $job_template_name could not be started for requestId $processId." +
                     " (Response: ${response.body}) "
             log.error(message)
-            setNodeOutputErrors( ATTRIBUTE_EXEC_CMD_STATUS_ERROR, message)
+            setNodeOutputErrors(ATTRIBUTE_EXEC_CMD_STATUS_ERROR, message)
         }
     }
 
@@ -207,51 +211,49 @@ open class ComponentRemoteAnsibleExecutor(private val blueprintRestLibPropertySe
      * by applying the overrides that were provided
      * and allowed by the template definition flags in jtLaunchReqs
      */
-    private fun prepareLaunchPayload(awxClient : BlueprintWebClientService, jtLaunchReqs: JsonNode): String {
-        val payload = JacksonUtils.jsonNode("{}") as ObjectNode
+    private fun prepareLaunchPayload(awxClient: BlueprintWebClientService, jtLaunchReqs: JsonNode): String {
+        val payload = JacksonUtils.objectMapper.createObjectNode()
 
         // Parameter defaults
-        val limitProp = getOptionalOperationInput(INPUT_LIMIT_TO_HOST)?.asText()
-        val tagsProp = getOptionalOperationInput(INPUT_TAGS)?.asText()
-        val skipTagsProp = getOptionalOperationInput(INPUT_SKIP_TAGS)?.asText()
-        val inventoryProp : String? = getOptionalOperationInput(INPUT_INVENTORY)?.asText()
-        val extraArgs : JsonNode = getOperationInput(INPUT_EXTRA_VARS)
-
-        val askLimitOnLaunch = jtLaunchReqs.at( "/ask_limit_on_launch").asBoolean()
-        if (askLimitOnLaunch && limitProp!!.isNotEmpty()) {
-            payload.put(INPUT_LIMIT_TO_HOST, limitProp)
+        val limitProp = getOptionalOperationInput(INPUT_LIMIT_TO_HOST)
+        val tagsProp = getOptionalOperationInput(INPUT_TAGS)
+        val skipTagsProp = getOptionalOperationInput(INPUT_SKIP_TAGS)
+        val inventoryProp = getOptionalOperationInput(INPUT_INVENTORY)
+        val extraArgs = getOperationInput(INPUT_EXTRA_VARS)
+
+        val askLimitOnLaunch = jtLaunchReqs.at("/ask_limit_on_launch").asBoolean()
+        if (askLimitOnLaunch && limitProp.isNotNull()) {
+            payload.set(INPUT_LIMIT_TO_HOST, limitProp)
         }
         val askTagsOnLaunch = jtLaunchReqs.at("/ask_tags_on_launch").asBoolean()
-        if (askTagsOnLaunch && tagsProp!!.isNotEmpty()) {
-            payload.put(INPUT_TAGS, tagsProp)
+        if (askTagsOnLaunch && tagsProp.isNotNull()) {
+            payload.set(INPUT_TAGS, tagsProp)
         }
-        if (askTagsOnLaunch && skipTagsProp!!.isNotEmpty()) {
-            payload.put("skip_tags", skipTagsProp)
+        if (askTagsOnLaunch && skipTagsProp.isNotNull()) {
+            payload.set("skip_tags", skipTagsProp)
         }
         val askInventoryOnLaunch = jtLaunchReqs.at("/ask_inventory_on_launch").asBoolean()
-        if (askInventoryOnLaunch && inventoryProp != null) {
-            var inventoryKeyId = inventoryProp.toIntOrNull()
-            if (inventoryKeyId == null) {
-                inventoryKeyId = resolveInventoryIdByName(awxClient, inventoryProp)
+        if (askInventoryOnLaunch && inventoryProp.isNotNull()) {
+            var inventoryKeyId = if (inventoryProp is TextNode) {
+                resolveInventoryIdByName(awxClient, inventoryProp!!.textValue())?.asJsonPrimitive()
+            } else {
+                inventoryProp
             }
-            payload.put(INPUT_INVENTORY, inventoryKeyId)
+            payload.set(INPUT_INVENTORY, inventoryKeyId)
         }
         val askVariablesOnLaunch = jtLaunchReqs.at("/ask_variables_on_launch").asBoolean()
         if (askVariablesOnLaunch && extraArgs != null) {
-            payload.put("extra_vars", extraArgs)
+            payload.set("extra_vars", extraArgs)
         }
-
-        val strPayload = "$payload"
-
-        return strPayload
+        return payload.asJsonString(false)
     }
 
-    private fun resolveInventoryIdByName(awxClient : BlueprintWebClientService, inventoryProp: String): Int? {
-        var invId : Int? = null
+    private fun resolveInventoryIdByName(awxClient: BlueprintWebClientService, inventoryProp: String): Int? {
+        var invId: Int? = null
 
         // Get Inventory by name
         val encoded = URLEncoder.encode(inventoryProp)
-        val response = awxClient.exchangeResource(GET,"/api/v2/inventories/?name=$encoded","")
+        val response = awxClient.exchangeResource(GET, "/api/v2/inventories/?name=$encoded", "")
         if (response.status in HTTP_SUCCESS) {
             // Extract the inventory ID from response
             val invDetails = mapper.readTree(response.body)
index ab54f56..42ff882 100644 (file)
@@ -40,7 +40,7 @@ fun String.isJson(): Boolean {
 }
 
 fun Any.asJsonString(intend: Boolean? = false): String {
-    return JacksonUtils.getJson(this, true)
+    return JacksonUtils.getJson(this, intend!!)
 }
 
 fun String.asJsonPrimitive(): TextNode {
@@ -130,6 +130,18 @@ fun JsonNode.returnNullIfMissing(): JsonNode? {
     } else this
 }
 
+fun <T : JsonNode> T?.isNull(): Boolean {
+    return if (this == null || this is NullNode || this is MissingNode) {
+        true
+    } else false
+}
+
+fun <T : JsonNode> T?.isNotNull(): Boolean {
+    return if (this == null || this is NullNode || this is MissingNode) {
+        false
+    } else true
+}
+
 /**
  * Convert Json to map of json node, the root fields will be map keys
  */
index b48e446..a7ed72d 100644 (file)
@@ -18,7 +18,6 @@
 package org.onap.ccsdk.cds.controllerblueprints.core.service
 
 
-import org.slf4j.LoggerFactory
 import com.fasterxml.jackson.databind.JsonNode
 import com.fasterxml.jackson.databind.node.NullNode
 import com.fasterxml.jackson.databind.node.ObjectNode
@@ -28,6 +27,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
+import org.slf4j.LoggerFactory
 import java.io.File
 
 interface BluePrintRuntimeService<T> {
@@ -145,7 +145,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
          * Load Blueprint Environments Properties
          */
         val absoluteEnvFilePath = bluePrintContext.rootPath.plus(File.separator)
-            .plus(BluePrintConstants.TOSCA_ENVIRONMENTS_DIR)
+                .plus(BluePrintConstants.TOSCA_ENVIRONMENTS_DIR)
         loadEnvironments(BluePrintConstants.PROPERTY_BPP, absoluteEnvFilePath)
 
     }
@@ -214,7 +214,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
     override fun loadEnvironments(type: String, fileName: String) {
         BluePrintMetadataUtils.environmentFileProperties(fileName).forEach { key, value ->
             setNodeTemplateAttributeValue(type, key.toString(), value.toString()
-                .asJsonPrimitive())
+                    .asJsonPrimitive())
         }
     }
 
@@ -237,7 +237,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                 // Resolve the Expressing
                 val propertyAssignmentExpression = PropertyAssignmentService(this)
                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName,
-                    nodeTypePropertyName, propertyAssignment)
+                        nodeTypePropertyName, propertyAssignment)
             }
 
             // Set default value if null
@@ -260,7 +260,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
             val expression = propertyDefinition.value ?: propertyDefinition.defaultValue
             if (expression != null) {
                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
-                    propertyName, expression)
+                        propertyName, expression)
             }
         }
         return propertyAssignmentValue
@@ -274,7 +274,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
         propertyAssignments.forEach { propertyName, propertyExpression ->
             val propertyAssignmentExpression = PropertyAssignmentService(this)
             propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
-                propertyName, propertyExpression)
+                    propertyName, propertyExpression)
         }
         return propertyAssignmentValue
     }
@@ -288,13 +288,13 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
         // Get the Node Type Definitions
         val nodeTypePropertieDefinitions: MutableMap<String, PropertyDefinition> = bluePrintContext
-            .nodeTypeChainedProperties(nodeTemplate.type)!!
+                .nodeTypeChainedProperties(nodeTemplate.type)!!
 
         /**
          * Resolve the NodeTemplate Property Assignment Values.
          */
         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypePropertieDefinitions,
-            propertyAssignments)
+                propertyAssignments)
     }
 
     override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String):
@@ -306,13 +306,13 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
         val propertyAssignments = nodeTemplate.capabilities?.get(capabilityName)?.properties ?: hashMapOf()
 
         val propertyDefinitions = bluePrintContext.nodeTemplateNodeType(nodeTemplateName)
-            .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
+                .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
 
         /**
          * Resolve the Capability Property Assignment Values.
          */
         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, propertyDefinitions,
-            propertyAssignments)
+                propertyAssignments)
     }
 
     override fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,
@@ -322,14 +322,14 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                 "($interfaceName), operationName($operationName)")
 
         val propertyAssignments: MutableMap<String, JsonNode> =
-            bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
-                ?: hashMapOf()
+                bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
+                        ?: hashMapOf()
 
         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
 
         val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =
-            bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
-                ?: hashMapOf()
+                bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
+                        ?: hashMapOf()
 
         log.info("input definition for node template ($nodeTemplateName), values ($propertyAssignments)")
 
@@ -337,7 +337,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
          * Resolve the Property Input Assignment Values.
          */
         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypeInterfaceOperationInputs,
-            propertyAssignments)
+                propertyAssignments)
 
     }
 
@@ -349,19 +349,19 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                 "($interfaceName), operationName($operationName)")
 
         val propertyAssignments: MutableMap<String, JsonNode> =
-            bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
-                ?: hashMapOf()
+                bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
+                        ?: hashMapOf()
 
         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
 
         val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =
-            bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
-                ?: hashMapOf()
+                bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
+                        ?: hashMapOf()
         /**
          * Resolve the Property Output Assignment Values.
          */
         val propertyAssignmentValue = resolveNodeTemplatePropertyAssignments(nodeTemplateName,
-            nodeTypeInterfaceOperationOutputs, propertyAssignments)
+                nodeTypeInterfaceOperationOutputs, propertyAssignments)
 
         // Store  operation output values into context
         propertyAssignmentValue.forEach { key, value ->
@@ -372,7 +372,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
     override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {
         val artifactDefinition: ArtifactDefinition =
-            resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
+                resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
         val propertyAssignmentExpression = PropertyAssignmentService(this)
         return propertyAssignmentExpression.artifactContent(artifactDefinition)
     }
@@ -382,8 +382,8 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
 
         return nodeTemplate.artifacts?.get(artifactName)
-            ?: throw BluePrintProcessorException("failed to get artifat definition($artifactName) from the node " +
-                    "template")
+                ?: throw BluePrintProcessorException("failed to get artifat definition($artifactName) from the node " +
+                        "template")
 
     }
 
@@ -394,14 +394,14 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
     override fun resolveDSLExpression(dslPropertyName: String): JsonNode {
         val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName)
         return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments)
-            && propertyAssignments is ObjectNode) {
+                && propertyAssignments is ObjectNode) {
 
             val rootKeyMap = propertyAssignments.rootFieldsToMap()
             val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
             rootKeyMap.forEach { propertyName, propertyValue ->
                 val propertyAssignmentExpression = PropertyAssignmentService(this)
                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression
-                    .resolveAssignmentExpression("DSL", propertyName, propertyValue)
+                        .resolveAssignmentExpression("DSL", propertyName, propertyValue)
             }
             propertyAssignmentValue.asJsonNode()
         } else {
@@ -411,7 +411,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
     override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         log.trace("setting input path ({}), values ({})", path, value)
         put(path, value)
     }
@@ -419,28 +419,28 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
     override fun setWorkflowInputValue(workflowName: String, propertyName: String,
                                        propertyDefinition: PropertyDefinition, value: JsonNode) {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         put(path, value)
     }
 
     override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
 
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         put(path, value)
     }
 
     override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
 
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
         put(path, value)
     }
 
@@ -448,13 +448,13 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                                                        operationName: String, propertyName: String,
                                                        value: JsonNode) {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         log.trace("setting operation property path ({}), values ({})", path, value)
         put(path, value)
     }
@@ -463,14 +463,14 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                                                     operationName: String, propertyName: String,
                                                     value: JsonNode) {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         put(path, value)
     }
 
@@ -478,51 +478,51 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
                                                      operationName: String, propertyName: String,
                                                      value: JsonNode) {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         put(path, value)
     }
 
 
     override fun getInputValue(propertyName: String): JsonNode {
         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         return getJsonNode(path)
     }
 
     override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
                                                      operationName: String, propertyName: String): JsonNode {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         return getJsonNode(path)
     }
 
     override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
         return getJsonNode(path)
     }
 
     override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
+                .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
         return getJsonNode(path)
     }
 
@@ -530,7 +530,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
         log.info("assignInputs from input JSON ({})", jsonNode.toString())
         bluePrintContext.inputs()?.forEach { propertyName, property ->
             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
-                ?: NullNode.getInstance()
+                    ?: NullNode.getInstance()
             setInputValue(propertyName, property, valueNode)
         }
     }
@@ -542,8 +542,10 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
         bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
             if (propertyName != dynamicInputPropertiesName) {
-                val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
-                    ?: NullNode.getInstance()
+                val valueNode: JsonNode = jsonNode
+                        .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
+                        ?: property.defaultValue
+                        ?: NullNode.getInstance()
                 setInputValue(propertyName, property, valueNode)
             }
         }
@@ -552,11 +554,12 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
         workflowDynamicInputs?.let {
             bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")
-                ?.properties?.forEach { propertyName, property ->
+                    ?.properties?.forEach { propertyName, property ->
                 val valueNode: JsonNode =
-                    workflowDynamicInputs.at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
-                        ?: property.defaultValue
-                        ?: NullNode.getInstance()
+                        workflowDynamicInputs
+                                .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
+                                ?: property.defaultValue
+                                ?: NullNode.getInstance()
                 setInputValue(propertyName, property, valueNode)
 
             }
@@ -573,9 +576,9 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl
 
         val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
-            .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
-            .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
-            .append(BluePrintConstants.PATH_DIVIDER).toString()
+                .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
+                .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
+                .append(BluePrintConstants.PATH_DIVIDER).toString()
         store.keys.filter {
             it.startsWith(path)
         }.map {