Merge "Python executor parameters sorted again."
diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt
index c45fb88..fa5d882 100644
--- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt
+++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentRemotePythonExecutor.kt
@@ -79,16 +79,8 @@
         val argsNode = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing()
 
         // This prevents unescaping values, as well as quoting the each parameter, in order to allow for spaces in values
-        var args = ""
-        argsNode?.fields()?.forEach {
-            if (it.value.isValueNode) {
-                args = "$args ${it.value}"
-            } else {
-                it.value.fields().forEach { item ->
-                    args = "$args ${item.value}"
-                }
-            }
-        }
+        val args = getOptionalOperationInput(INPUT_ARGUMENT_PROPERTIES)?.returnNullIfMissing()
+            ?.rootFieldsToMap()?.toSortedMap()?.values?.joinToString(" ") { formatNestedJsonNode(it) }
 
         val command = getOperationInput(INPUT_COMMAND).asText()
         var scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath)
@@ -141,4 +133,14 @@
         bluePrintRuntimeService.getBluePrintError()
                 .addError("Failed in ComponentJythonExecutor : ${runtimeException.message}")
     }
+
+    private fun formatNestedJsonNode(node: JsonNode): String {
+        val sb = StringBuilder()
+        if (node.isValueNode) {
+            sb.append(" $node")
+        } else {
+            node.forEach { sb.append(" $it") }
+        }
+        return sb.toString()
+    }
 }
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
index 42ff882..4832970 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/CustomFunctions.kt
@@ -147,7 +147,7 @@
  */
 fun JsonNode.rootFieldsToMap(): MutableMap<String, JsonNode> {
     if (this is ObjectNode) {
-        val propertyMap: MutableMap<String, JsonNode> = hashMapOf()
+        val propertyMap: MutableMap<String, JsonNode> = linkedMapOf()
         this.fields().forEach {
             propertyMap[it.key] = it.value
         }