Add cli test blueprints 28/88028/5
authorBrinda Santh <brindasanth@in.ibm.com>
Fri, 17 May 2019 14:07:14 +0000 (10:07 -0400)
committerSteve Siani <alphonse.steve.siani.djissitchi@ibm.com>
Thu, 23 May 2019 04:15:54 +0000 (00:15 -0400)
Change-Id: Ieab385f5e4ae60cca3d86f22c4304e4867e6fa96
Issue-ID: CCSDK-1335
Signed-off-by: Brinda Santh <brindasanth@in.ibm.com>
18 files changed:
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/CapabilityCli.cba.kts [new file with mode: 0644]
components/model-catalog/blueprint-model/test-blueprint/capability_cli/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt
ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/ComponentCliExecutor.kt
ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BasicAuthSshClientService.kt
ms/blueprintsprocessor/modules/commons/ssh-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BluePrintSshLibPropertyService.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/interfaces/BlueprintTemplateService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/JacksonUtils.kt
ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
ms/controllerblueprints/modules/service/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/service/enhancer/BluePrintEnhancerServiceImplTest.kt

diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json
new file mode 100644 (file)
index 0000000..c66bb6e
--- /dev/null
@@ -0,0 +1,83 @@
+{
+  "tosca_definitions_version": "controller_blueprint_1_0_0",
+  "metadata": {
+    "template_author": "Brinda Santh Muthuramalingam",
+    "author-email": "brindasanth@in.ibm.com",
+    "user-groups": "ADMIN, OPERATION",
+    "template_name": "capability-cli",
+    "template_version": "1.0.0",
+    "template_tags": "brinda, tosca"
+  },
+  "imports": [
+    {
+      "file": "Definitions/data_types.json"
+    },
+    {
+      "file": "Definitions/relationship_types.json"
+    },
+    {
+      "file": "Definitions/artifact_types.json"
+    },
+    {
+      "file": "Definitions/node_types.json"
+    },
+    {
+      "file": "Definitions/policy_types.json"
+    }
+  ],
+  "dsl_definitions": {
+    "config-deploy-properties": {
+      "resolution-key": {
+        "get_input": "resolution-key"
+      }
+    }
+  },
+  "topology_template": {
+    "workflows": {
+      "check": {
+        "steps": {
+          "activate-process": {
+            "description": "Check CLI",
+            "target": "check",
+            "activities": [
+              {
+                "call_operation": "ComponentCliExecutor.process"
+              }
+            ]
+          }
+        }
+      }
+    },
+    "node_templates": {
+      "check": {
+        "type": "component-cli-executor",
+        "interfaces": {
+          "ComponentCliExecutor": {
+            "operations": {
+              "process": {
+                "implementation": {
+                  "primary": "component-script"
+                },
+                "inputs": {
+                  "script-type": "kotlin",
+                  "script-class-reference": "InternalSimpleCli_cba$TestCliScriptFunction",
+                  "instance-dependencies": []
+                },
+                "outputs": {
+                  "response-data": "",
+                  "status": "success"
+                }
+              }
+            }
+          }
+        },
+        "artifacts": {
+          "command-template": {
+            "type": "artifact-template-velocity",
+            "file": "Templates/check-command-template.vtl"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/CapabilityCli.cba.kts b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/CapabilityCli.cba.kts
new file mode 100644 (file)
index 0000000..e22fd7e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  Copyright © 2019 IBM.
+ *
+ *  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.
+ */
+
+
+
+open class Check : CliComponentFunction() {
+
+    private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!!
+
+    override fun getName(): String {
+        return "SimpleCliConfigure"
+    }
+
+    override suspend fun processNB(executionRequest: ExecutionServiceInput) {
+        log.info("Executing process")
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
+        log.info("Executing Recovery")
+    }
+}
\ No newline at end of file
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/TOSCA-Metadata/TOSCA.meta b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..0018896
--- /dev/null
@@ -0,0 +1,5 @@
+TOSCA-Meta-File-Version: 1.0.0
+CSAR-Version: 1.0
+Created-By: Brinda Santh
+Entry-Definitions: Definitions/capability-cli-blueprint.json
+Template-Tags: capability-cli-blueprint
index 6dcffca..c7f35f7 100644 (file)
@@ -22,6 +22,9 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.Reso
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractScriptComponentFunction
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.BluePrintSshLibPropertyService
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
+import org.onap.ccsdk.cds.controllerblueprints.core.readNBLines
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
 
 abstract class CliComponentFunction : AbstractScriptComponentFunction() {
 
@@ -32,6 +35,18 @@ abstract class CliComponentFunction : AbstractScriptComponentFunction() {
             functionDependencyInstanceAsType(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION)
 
 
+    open suspend fun readCommandLinesFromArtifact(artifactName: String): List<String> {
+        val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
+        val file = normalizedFile(bluePrintRuntimeService.bluePrintContext().rootPath, artifactDefinition.file)
+        return file.readNBLines()
+    }
+
+    suspend fun generateMessage(artifactName: String, json: String): String {
+        val templateService = BluePrintTemplateService()
+        return templateService.generateContent(bluePrintRuntimeService, nodeTemplateName, artifactName, json, true)
+    }
+
+
     fun generateMessage(artifactName: String): String {
         return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName)
     }
index 8c58272..0c1c523 100644 (file)
@@ -35,6 +35,7 @@ open class ComponentCliExecutor(private var componentFunctionScriptingService: C
         const val SCRIPT_TYPE = "script-type"
         const val SCRIPT_CLASS_REFERENCE = "script-class-reference"
         const val INSTANCE_DEPENDENCIES = "instance-dependencies"
+        const val RESPONSE_DATA = "response-data"
     }
 
     private lateinit var scriptComponent: CliComponentFunction
index 136d011..18d4a47 100644 (file)
@@ -18,6 +18,8 @@
 
 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
 import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.CliComponentFunction
+import org.onap.ccsdk.cds.blueprintsprocessor.functions.cli.executor.ComponentCliExecutor
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
 import org.slf4j.LoggerFactory
 
 open class TestCliScriptFunction : CliComponentFunction() {
@@ -36,3 +38,41 @@ open class TestCliScriptFunction : CliComponentFunction() {
         log.info("Executing Recovery")
     }
 }
+
+
+open class Check : CliComponentFunction() {
+
+    private val log = LoggerFactory.getLogger(CliComponentFunction::class.java)!!
+
+    override fun getName(): String {
+        return "Check"
+    }
+
+    override suspend fun processNB(executionRequest: ExecutionServiceInput) {
+        // Get the Device Information from the DSL Model
+        val deviceInformation = bluePrintRuntimeService.resolveDSLExpression("device-properties")
+
+        // Get the Client Service
+        val sshClientService = bluePrintSshLibPropertyService().blueprintSshClientService(deviceInformation)
+
+        sshClientService.startSessionNB()
+
+        // Read Commands
+        val commands = readCommandLinesFromArtifact("command-template")
+
+        // Execute multiple Commands
+        val responseLog = sshClientService.executeCommandsNB(commands, 5000)
+
+        // Close Session
+        sshClientService.closeSessionNB()
+
+        // Set the Response Data
+        setAttribute(ComponentCliExecutor.RESPONSE_DATA, responseLog.asJsonPrimitive())
+
+        log.info("Executing process")
+    }
+
+    override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
+        log.info("Executing Recovery")
+    }
+}
index 5106225..ebff478 100644 (file)
@@ -46,10 +46,10 @@ interface ResourceResolutionService {
                                  artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String>
 
     suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                               artifactPrefix: String, properties: Map<String, Any>): String
+                                 artifactPrefix: String, properties: Map<String, Any>): String
 
     suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                                  artifactMapping: String, artifactTemplate: String?): String
+                                 artifactMapping: String, artifactTemplate: String?): String
 
     suspend fun resolveResourceAssignments(blueprintRuntimeService: BluePrintRuntimeService<*>,
                                            resourceDefinitions: MutableMap<String, ResourceDefinition>,
@@ -89,7 +89,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
     }
 
     override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                                        artifactPrefix: String, properties: Map<String, Any>): String {
+                                          artifactPrefix: String, properties: Map<String, Any>): String {
 
         // Velocity Artifact Definition Name
         val artifactTemplate = "$artifactPrefix-template"
@@ -110,7 +110,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
 
 
     override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                                           artifactMapping: String, artifactTemplate: String?): String {
+                                          artifactMapping: String, artifactTemplate: String?): String {
 
         val resolvedContent: String
         log.info("Resolving resource for template artifact($artifactTemplate) with resource assignment artifact($artifactMapping)")
@@ -137,11 +137,9 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
 
         // Check Template is there
         if (artifactTemplate != null) {
-            val blueprintTemplateService = BluePrintTemplateService(bluePrintRuntimeService, nodeTemplateName, artifactTemplate)
-            val templateContent =
-                    bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactTemplate)
-
-            resolvedContent = blueprintTemplateService.generateContent(templateContent, resolvedParamJsonContent)
+            val blueprintTemplateService = BluePrintTemplateService()
+            resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName,
+                    artifactTemplate, resolvedParamJsonContent)
 
         } else {
             resolvedContent = resolvedParamJsonContent
index 8dbd47c..3482d45 100644 (file)
@@ -25,6 +25,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.functions.resource.resolution.util
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintFunctionNode
 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
@@ -67,6 +68,7 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
                 ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
     }
 
+    //TODO("Convert return Map<String, JsonNode>")
     open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> {
         val resolvedInputKeyMapping = HashMap<String, Any>()
         if (MapUtils.isNotEmpty(inputKeyMapping)) {
@@ -80,12 +82,14 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
         return resolvedInputKeyMapping
     }
 
+    //TODO("Convert keyMapping =  MutableMap<String, JsonNode>")
     open suspend fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: MutableMap<String, Any>):
             String {
         if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
             return valueToResolve
         }
-        return BluePrintVelocityTemplateService.generateContent(valueToResolve, additionalContext = keyMapping)
+        //TODO("Optimize to JSON Node directly")
+        return BluePrintVelocityTemplateService.generateContent(valueToResolve, keyMapping.asJsonNode().toString())
     }
 
     final override suspend fun applyNB(resourceAssignment: ResourceAssignment): Boolean {
index 67d5d51..adbde0f 100644 (file)
@@ -36,6 +36,7 @@ open class BasicAuthSshClientService(private val basicAuthSshClientProperties: B
 
     private lateinit var sshClient: SshClient
     private lateinit var clientSession: ClientSession
+    var channel: ChannelExec? = null
 
     override suspend fun startSessionNB(): ClientSession {
         sshClient = SshClient.setUpDefaultClient()
@@ -69,31 +70,29 @@ open class BasicAuthSshClientService(private val basicAuthSshClientProperties: B
     override suspend fun executeCommandNB(command: String, timeOut: Long): String {
         log.debug("Executing host($clientSession) command($command)")
 
-        var channel: ChannelExec? = null
-        try {
-            channel = clientSession.createExecChannel(command)
-            //TODO("Convert to streaming ")
-            val outputStream = ByteArrayOutputStream()
-            channel.out = outputStream
-            channel.err = outputStream
-            channel.open().await()
-            val waitMask = channel.waitFor(Collections.unmodifiableSet(EnumSet.of(ClientChannelEvent.CLOSED)), timeOut)
-            if (waitMask.contains(ClientChannelEvent.TIMEOUT)) {
-                throw BluePrintProcessorException("Failed to retrieve command result in time: $command")
-            }
-            val exitStatus = channel.exitStatus
-            ClientChannel.validateCommandExitStatusCode(command, exitStatus!!)
-            return outputStream.toString()
-        } finally {
-            if (channel != null)
-                channel.close()
+        channel = clientSession.createExecChannel(command)
+        checkNotNull(channel) { "failed to create Channel for the command : $command" }
+
+        //TODO("Convert to streaming ")
+        val outputStream = ByteArrayOutputStream()
+        channel!!.out = outputStream
+        channel!!.err = outputStream
+        channel!!.open().await()
+        val waitMask = channel!!.waitFor(Collections.unmodifiableSet(EnumSet.of(ClientChannelEvent.CLOSED)), timeOut)
+        if (waitMask.contains(ClientChannelEvent.TIMEOUT)) {
+            throw BluePrintProcessorException("Failed to retrieve command result in time: $command")
         }
+        val exitStatus = channel!!.exitStatus
+        ClientChannel.validateCommandExitStatusCode(command, exitStatus!!)
+        return outputStream.toString()
     }
 
     override suspend fun closeSessionNB() {
+        if (channel != null)
+            channel!!.close()
         if (sshClient.isStarted) {
             sshClient.stop()
-            log.debug("SSH Client Service stopped successfully")
         }
+        log.debug("SSH Client Service stopped successfully")
     }
 }
index 9971c50..1950b71 100644 (file)
 
 package org.onap.ccsdk.cds.blueprintsprocessor.ssh.service
 
+import com.fasterxml.jackson.databind.JsonNode
 import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BasicAuthSshClientProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshClientProperties
 import org.onap.ccsdk.cds.blueprintsprocessor.ssh.SshLibConstants
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.springframework.stereotype.Service
 
 @Service(SshLibConstants.SERVICE_BLUEPRINT_SSH_LIB_PROPERTY)
 open class BluePrintSshLibPropertyService(private var bluePrintProperties: BluePrintProperties) {
 
+    fun blueprintSshClientService(jsonNode: JsonNode): BlueprintSshClientService {
+        val restClientProperties = sshClientProperties(jsonNode)
+        return blueprintSshClientService(restClientProperties)
+    }
+
     fun blueprintSshClientService(selector: String): BlueprintSshClientService {
         val prefix = "${SshLibConstants.PROPERTY_SSH_CLIENT_PREFIX}$selector"
         val sshClientProperties = sshClientProperties(prefix)
@@ -44,6 +51,19 @@ open class BluePrintSshLibPropertyService(private var bluePrintProperties: BlueP
         }
     }
 
+    fun sshClientProperties(jsonNode: JsonNode): SshClientProperties {
+        val type = jsonNode.get("type").textValue()
+        return when (type) {
+            SshLibConstants.TYPE_BASIC_AUTH -> {
+                JacksonUtils.readValue(jsonNode,
+                        BasicAuthSshClientProperties::class.java)!!
+            }
+            else -> {
+                throw BluePrintProcessorException("SSH adaptor($type) is not supported")
+            }
+        }
+    }
+
     private fun blueprintSshClientService(sshClientProperties: SshClientProperties): BlueprintSshClientService {
 
         when (sshClientProperties) {
index 0e45232..583fc9d 100644 (file)
@@ -122,6 +122,18 @@ fun JsonNode.rootFieldsToMap(): MutableMap<String, JsonNode> {
     }
 }
 
+fun JsonNode.removeNullNode() {
+    val it = this.iterator()
+    while (it.hasNext()) {
+        val child = it.next()
+        if (child.isNull) {
+            it.remove()
+        } else {
+            child.removeNullNode()
+        }
+    }
+}
+
 
 fun MutableMap<String, JsonNode>.putJsonElement(key: String, value: Any) {
     val convertedValue = value.asJsonType()
index ec1542c..86bf3ff 100644 (file)
@@ -18,21 +18,43 @@ package org.onap.ccsdk.cds.controllerblueprints.core.interfaces
 import com.fasterxml.jackson.core.io.CharTypes
 import com.fasterxml.jackson.databind.node.JsonNodeFactory
 import com.fasterxml.jackson.databind.node.TextNode
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
 
 interface BlueprintTemplateService {
 
+    /**
+     * Generate dynamique content using Velocity Template or Jinja template
+     *
+     * @param bluePrintRuntimeService blueprint runtime
+     * @param nodeTemplateName node template
+     * @param artifactName Artifact Name
+     * @param jsonData json string data content to mash
+     * @param ignoreJsonNull Ignore Null value in the JSON content
+     * @param additionalContext (Key, value) mutable map for additional variables
+     * @return Content result
+     *
+     **/
+    suspend fun generateContent(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                nodeTemplateName: String,
+                                artifactName: String,
+                                jsonData: String = "",
+                                ignoreJsonNull: Boolean = false,
+                                additionalContext: MutableMap<String, Any> = mutableMapOf()): String
+
+
     /**
      * Generate dynamique content using Velocity Template or Jinja template
      *
      * @param template template string content
-     * @param json json string content
+     * @param templateType template type
+     * @param jsonData json string data content to mash
      * @param ignoreJsonNull Ignore Null value in the JSON content
      * @param additionalContext (Key, value) mutable map for additional variables
      * @return Content result
      *
      **/
-    suspend fun generateContent(template: String, json: String = "", ignoreJsonNull: Boolean = false,
-                        additionalContext: MutableMap<String, Any> = mutableMapOf()): String
+    suspend fun generateContent(template: String, templateType: String, jsonData: String = "", ignoreJsonNull: Boolean = false,
+                                additionalContext: MutableMap<String, Any> = mutableMapOf()): String
 }
 
 /**
index f835cbe..912667e 100644 (file)
@@ -21,14 +21,13 @@ import com.fasterxml.jackson.databind.ObjectMapper
 import com.hubspot.jinjava.Jinjava
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintJsonNodeFactory
-import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService
-import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.removeNullNode
 
 
-object BluePrintJinjaTemplateService: BlueprintTemplateService {
+object BluePrintJinjaTemplateService {
 
-    override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean,
-                                 additionalContext: MutableMap<String, Any>): String {
+    fun generateContent(template: String, json: String, ignoreJsonNull: Boolean,
+                                additionalContext: MutableMap<String, Any>): String {
         // Load template
         val jinJava = Jinjava()
         val mapper = ObjectMapper()
@@ -40,7 +39,7 @@ object BluePrintJinjaTemplateService: BlueprintTemplateService {
             val jsonNode = mapper.readValue<JsonNode>(json, JsonNode::class.java)
                     ?: throw BluePrintProcessorException("couldn't get json node from json")
             if (ignoreJsonNull)
-                JacksonUtils.removeJsonNullNode(jsonNode)
+                jsonNode.removeNullNode()
             jsonNode.fields().forEach { entry ->
                 additionalContext[entry.key] = entry.value
             }
index 4b6905b..496182e 100644 (file)
@@ -26,35 +26,50 @@ import org.apache.velocity.VelocityContext
 import org.apache.velocity.app.Velocity
 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintJsonNodeFactory
-import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService
-import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.removeNullNode
 import java.io.StringWriter
 
-object BluePrintVelocityTemplateService: BlueprintTemplateService {
+object BluePrintVelocityTemplateService {
 
     /**
-     * Generate Content from Velocity Template and JSON Content or property map.
+     * Generate Content from Velocity Template and JSON Content with injected API
      */
-    override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, additionalContext:
-    MutableMap<String, Any>): String {
-        Velocity.init()
+    fun generateContent(template: String, json: String, ignoreJsonNull: Boolean = false,
+                        additionalContext: MutableMap<String, Any> = mutableMapOf()): String {
+
+        // Customized Object Mapper to remove String double quotes
         val mapper = ObjectMapper()
         val nodeFactory = BluePrintJsonNodeFactory()
         mapper.nodeFactory = nodeFactory
 
+        val jsonNode: JsonNode? = if (json.isNotEmpty()) {
+            mapper.readValue(json, JsonNode::class.java)
+                    ?: throw BluePrintProcessorException("couldn't get json node from json")
+        } else {
+            null
+        }
+        return generateContent(template, jsonNode, ignoreJsonNull, additionalContext)
+    }
+
+    /**
+     * Generate Content from Velocity Template and JSON Node with injected API
+     */
+    fun generateContent(template: String, jsonNode: JsonNode?, ignoreJsonNull: Boolean = false,
+                        additionalContext: MutableMap<String, Any> = mutableMapOf()): String {
+
+        Velocity.init()
+
         val velocityContext = VelocityContext()
         velocityContext.put("StringUtils", StringUtils::class.java)
         velocityContext.put("BooleanUtils", BooleanUtils::class.java)
 
         // Add the Custom Velocity Context API
-        additionalContext.forEach { name, value -> velocityContext.put(name, value) }
+        additionalContext.forEach { (name, value) -> velocityContext.put(name, value) }
 
         // Add the JSON Data to the context
-        if (json.isNotEmpty()) {
-            val jsonNode = mapper.readValue<JsonNode>(json, JsonNode::class.java)
-                    ?: throw BluePrintProcessorException("couldn't get json node from json")
+        if (jsonNode != null) {
             if (ignoreJsonNull)
-                JacksonUtils.removeJsonNullNode(jsonNode)
+                jsonNode.removeNullNode()
             jsonNode.fields().forEach { entry ->
                 velocityContext.put(entry.key, entry.value)
             }
@@ -64,6 +79,7 @@ object BluePrintVelocityTemplateService: BlueprintTemplateService {
         Velocity.evaluate(velocityContext, stringWriter, "TemplateData", template)
         stringWriter.flush()
         return stringWriter.toString()
+
     }
 }
 
index 73457b9..45e2678 100644 (file)
@@ -20,19 +20,26 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 
-class BluePrintTemplateService(val bluePrintRuntimeService: BluePrintRuntimeService<*>,
-                               val nodeTemplateName: String, val artifactName: String):
-        BlueprintTemplateService {
+class BluePrintTemplateService : BlueprintTemplateService {
+
+    override suspend fun generateContent(bluePrintRuntimeService: BluePrintRuntimeService<*>,
+                                         nodeTemplateName: String, artifactName: String, jsonData: String,
+                                         ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String {
 
-    override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String {
         val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
         val templateType = artifactDefinition.type
+        val template = bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName)
+        return generateContent(template, templateType, jsonData, ignoreJsonNull, additionalContext)
+    }
+
+    override suspend fun generateContent(template: String, templateType: String, jsonData: String, ignoreJsonNull: Boolean,
+                                         additionalContext: MutableMap<String, Any>): String {
         return when (templateType) {
             BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME -> {
-                BluePrintJinjaTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext)
+                BluePrintJinjaTemplateService.generateContent(template, jsonData, ignoreJsonNull, additionalContext)
             }
             BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME -> {
-                BluePrintVelocityTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext)
+                BluePrintVelocityTemplateService.generateContent(template, jsonData, ignoreJsonNull, additionalContext)
             }
             else -> {
                 throw BluePrintProcessorException("Unknown Artifact type, expecting ${BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME}" +
@@ -41,9 +48,11 @@ class BluePrintTemplateService(val bluePrintRuntimeService: BluePrintRuntimeServ
         }
     }
 
-    suspend fun generateContentFromFiles(templatePath: String, jsonPath: String, ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String {
+    suspend fun generateContentFromFiles(templatePath: String, templateType: String, jsonPath: String,
+                                         ignoreJsonNull: Boolean,
+                                         additionalContext: MutableMap<String, Any>): String {
         val json = JacksonUtils.getClassPathFileContent(jsonPath)
         val template = JacksonUtils.getClassPathFileContent(templatePath)
-        return generateContent(template, json, ignoreJsonNull, additionalContext)
+        return generateContent(template, templateType, json, ignoreJsonNull, additionalContext)
     }
 }
\ No newline at end of file
index 7b5f181..5e9fd62 100644 (file)
@@ -58,19 +58,6 @@ class JacksonUtils {
             return objectMapper.treeToValue(node, valueType)
         }
 
-        fun removeJsonNullNode(node: JsonNode) {
-            val it = node.iterator()
-            while (it.hasNext()) {
-                val child = it.next()
-                if (child.isNull) {
-                    it.remove()
-                } else {
-                    removeJsonNullNode(child)
-                }
-            }
-        }
-
-
         fun getContent(fileName: String): String = runBlocking {
             try {
                 normalizedFile(fileName).readNBText()
index e422718..02505ac 100644 (file)
@@ -21,6 +21,7 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service
 import kotlinx.coroutines.runBlocking
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
 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
@@ -40,13 +41,13 @@ class BluePrintTemplateServiceTest {
 
     @Test
     fun testVelocityGeneratedContent() {
-       runBlocking {
-           val template = JacksonUtils.getClassPathFileContent("templates/base-config-velocity-template.vtl")
-           val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-velocity.json")
+        runBlocking {
+            val template = JacksonUtils.getClassPathFileContent("templates/base-config-velocity-template.vtl")
+            val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-velocity.json")
 
-           val content = BluePrintVelocityTemplateService.generateContent(template, json)
-           assertNotNull(content, "failed to generate content for velocity template")
-       }
+            val content = BluePrintVelocityTemplateService.generateContent(template, json)
+            assertNotNull(content, "failed to generate content for velocity template")
+        }
 
     }
 
@@ -68,13 +69,12 @@ class BluePrintTemplateServiceTest {
     @Test
     fun testVelocityGeneratedContentFromFiles() {
         runBlocking {
-            val bluePrintTemplateService = BluePrintTemplateService(blueprintRuntime,
-                    "resource-assignment", "baseconfig-template")
+            val bluePrintTemplateService = BluePrintTemplateService()
             val templateFile = "templates/base-config-velocity-template.vtl"
             val jsonFile = "templates/base-config-data-velocity.json"
 
             val content = bluePrintTemplateService.generateContentFromFiles(
-                    templateFile, jsonFile, false, mutableMapOf())
+                    templateFile, BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, jsonFile, false, mutableMapOf())
             assertNotNull(content, "failed to generate content for velocity template")
         }
 
@@ -86,14 +86,13 @@ class BluePrintTemplateServiceTest {
             var element: MutableMap<String, Any> = mutableMapOf()
             element["additional_array"] = arrayListOf(hashMapOf("name" to "Element1", "location" to "Region0"), hashMapOf("name" to "Element2", "location" to "Region1"))
 
-            val bluePrintTemplateService = BluePrintTemplateService(blueprintRuntime,
-                    "resource-assignment", "another-template")
+            val bluePrintTemplateService = BluePrintTemplateService()
 
             val templateFile = "templates/base-config-jinja-template.jinja"
             val jsonFile = "templates/base-config-data-jinja.json"
 
             val content = bluePrintTemplateService.generateContentFromFiles(
-                    templateFile,
+                    templateFile, BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME,
                     jsonFile, false, element)
             assertNotNull(content, "failed to generate content for velocity template")
         }
index e1c5c40..b4c29de 100644 (file)
@@ -23,9 +23,11 @@ import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.controllerblueprints.TestApplication
+import org.onap.ccsdk.cds.controllerblueprints.core.compress
 import org.onap.ccsdk.cds.controllerblueprints.core.deleteDir
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintEnhancerService
 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintValidatorService
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName
 import org.onap.ccsdk.cds.controllerblueprints.service.load.ModelTypeLoadService
 import org.onap.ccsdk.cds.controllerblueprints.service.load.ResourceDictionaryLoadService