Jinja template for Blueprint template service 39/84139/9
authorSteve Siani <alphonse.steve.siani.djissitchi@ibm.com>
Wed, 3 Apr 2019 19:23:27 +0000 (15:23 -0400)
committerSteve Siani <alphonse.steve.siani.djissitchi@ibm.com>
Tue, 9 Apr 2019 17:08:39 +0000 (13:08 -0400)
Change-Id: Iec777e4500c2a040faccc8375b1d2dd24c27cb7f
Issue-ID: CCSDK-1193
Signed-off-by: Steve Siani <alphonse.steve.siani.djissitchi@ibm.com>
27 files changed:
components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/activation-blueprint.json
components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/artifact_types.json
components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Templates/another-template.jinja [moved from components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Templates/another-template.vtl with 100% similarity]
components/model-catalog/definition-type/starter-type/artifact_type/artifact-template-jinja.json [new file with mode: 0644]
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/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt
ms/blueprintsprocessor/functions/resource-resolution/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionServiceTest.kt
ms/blueprintsprocessor/modules/services/execution-service/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/scripts/BlueprintJythonServiceTest.kt
ms/blueprintsprocessor/parent/pom.xml
ms/controllerblueprints/modules/blueprint-core/load/model_type/artifact_type/artifact-mapping-resource.json
ms/controllerblueprints/modules/blueprint-core/load/model_type/artifact_type/artifact-template-jinja.json [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/load/model_type/node_type/artifact-config-template.json
ms/controllerblueprints/modules/blueprint-core/pom.xml
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateService.kt [deleted file]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data-jinja.json [new file with mode: 0644]
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data-velocity.json [moved from ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data.json with 100% similarity]
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-jinja-template.jinja [new file with mode: 0755]
ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-velocity-template.vtl [moved from ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-template.vtl with 100% similarity]
ms/controllerblueprints/modules/service/pom.xml
ms/controllerblueprints/parent/pom.xml

index 78a9d8c..eae6924 100644 (file)
             "file": "Definitions/baseconfig-mapping.json"
           },
           "another-template": {
-            "type": "artifact-template-velocity",
-            "file": "Templates/another-template.vtl"
+            "type": "artifact-template-jinja",
+            "file": "Templates/another-template.jinja"
           },
           "another-mapping": {
             "type": "artifact-mapping-resource",
index d741d15..f1e5bb1 100644 (file)
@@ -8,6 +8,14 @@
       ],
       "derived_from": "tosca.artifacts.Implementation"
     },
+    "artifact-template-jinja": {
+      "description": "Jinja Template used for Configuration",
+      "version": "1.0.0",
+      "file_ext": [
+        "jinja"
+      ],
+      "derived_from": "tosca.artifacts.Implementation"
+    },
     "artifact-mapping-resource": {
       "description": "Velocity Template Resource Mapping File used along with Configuration template",
       "version": "1.0.0",
@@ -42,4 +50,4 @@
       "derived_from": "tosca.artifacts.Implementation"
     }
   }
-}
\ No newline at end of file
+}
diff --git a/components/model-catalog/definition-type/starter-type/artifact_type/artifact-template-jinja.json b/components/model-catalog/definition-type/starter-type/artifact_type/artifact-template-jinja.json
new file mode 100644 (file)
index 0000000..5d4fcc3
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "description": " Jinja Template used for Configuration",
+  "version": "1.0.0",
+  "file_ext": [
+    "jinja"
+  ],
+  "derived_from": "tosca.artifacts.Implementation"
+}
\ No newline at end of file
index 31cb9ca..5106225 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright © 2017-2018 AT&T Intellectual Property.
- *  Modifications Copyright © 2018-2019 IBM.
+ *  Modifications Copyright © 2018-2019 IBM, Bell Canada
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -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>,
@@ -77,26 +77,27 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
     }
 
     override suspend fun resolveResources(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String,
-                                          artifactNames: List<String>,
-                                          properties: Map<String, Any>): MutableMap<String, String> {
+                                          artifactNames: List<String>, properties: Map<String, Any>): MutableMap<String, String> {
 
         val resolvedParams: MutableMap<String, String> = hashMapOf()
         artifactNames.forEach { artifactName ->
-            val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactName, properties)
+            val resolvedContent = resolveResources(bluePrintRuntimeService, nodeTemplateName,
+                    artifactName, properties)
             resolvedParams[artifactName] = resolvedContent
         }
         return resolvedParams
     }
 
     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"
         // Resource Assignment Artifact Definition Name
         val artifactMapping = "$artifactPrefix-mapping"
 
-        val result = resolveResources(bluePrintRuntimeService, nodeTemplateName, artifactMapping, artifactTemplate)
+        val result = resolveResources(bluePrintRuntimeService, nodeTemplateName,
+                artifactMapping, artifactTemplate)
 
         if (properties.containsKey(ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT)
                 && properties[ResourceResolutionConstants.RESOURCE_RESOLUTION_INPUT_STORE_RESULT] as Boolean) {
@@ -109,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)")
@@ -136,9 +137,12 @@ 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)
+
+            resolvedContent = blueprintTemplateService.generateContent(templateContent, resolvedParamJsonContent)
+
         } else {
             resolvedContent = resolvedParamJsonContent
         }
index e9bb2ff..8dbd47c 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright © 2018 IBM.
- *  Modifications Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ *  Modifications Copyright © 2017-2019 AT&T, Bell Canada
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -25,7 +26,7 @@ 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.interfaces.BlueprintFunctionNode
-import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceAssignment
 import org.onap.ccsdk.cds.controllerblueprints.resource.dict.ResourceDefinition
@@ -79,11 +80,12 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
         return resolvedInputKeyMapping
     }
 
-    open fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: Map<String, Any>): String {
+    open suspend fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: MutableMap<String, Any>):
+            String {
         if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
             return valueToResolve
         }
-        return BluePrintTemplateService.generateContent(valueToResolve, additionalContext = keyMapping)
+        return BluePrintVelocityTemplateService.generateContent(valueToResolve, additionalContext = keyMapping)
     }
 
     final override suspend fun applyNB(resourceAssignment: ResourceAssignment): Boolean {
index cd93852..9852e34 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright © 2018 IBM.
- *  Modifications Copyright © 2017-2018 AT&T Intellectual Property.
+ *  Modifications Copyright © 2017-2019 AT&T, Bell Canada
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -71,10 +71,9 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
                         JacksonUtils.getInstanceFromMap(resourceSourceProperties, RestResourceSource::class.java)
 
                 val path = nullToEmpty(sourceProperties.path)
-                val inputKeyMapping = checkNotNull(sourceProperties.inputKeyMapping) {
-                    "failed to get input-key-mappings for $dName under $dSource properties"
-                }
-                val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping)
+                val inputKeyMapping =
+                    checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
+                val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping).toMutableMap()
 
                 // Resolving content Variables
                 val payload = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.payload), resolvedInputKeyMapping)
index f7f4a98..3f251b1 100644 (file)
@@ -1,9 +1,7 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  *
- * Modifications Copyright © 2018 IBM.
- *
- *  Modifications Copyright © 2019 IBM, Bell Canada.
+ * Modifications Copyright © 2018 - 2019 IBM, Bell Canada.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 5c9ae99..dd417e5 100644 (file)
@@ -18,7 +18,6 @@ package org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts
 
 import io.mockk.every
 import io.mockk.mockk
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
@@ -48,7 +47,7 @@ class BlueprintJythonServiceTest {
         blueprintContext = mockk<BluePrintContext>()
         every { blueprintContext.rootPath } returns normalizedPathName("target")
     }
-
+    
     @Test
     fun testGetAbstractPythonPlugin() {
         val content = JacksonUtils.getClassPathFileContent("scripts/SamplePythonComponentNode.py")
@@ -60,7 +59,7 @@ class BlueprintJythonServiceTest {
 
         assertNotNull(abstractPythonPlugin, "failed to get python component")
     }
-    
+
     @Test
     fun testGetAbstractJythonComponent() {
         val scriptInstance = "test-classes/scripts/SamplePythonComponentNode.py"
index 772c739..c9505cb 100755 (executable)
@@ -2,8 +2,7 @@
 <!--
   ~  Copyright © 2017-2018 AT&T Intellectual Property.
   ~
-  ~  Modifications Copyright © 2018 IBM.
-  ~  Modifications Copyright © 2019 Bell Canada.
+  ~  Modifications Copyright © 2018 - 2019 IBM, Bell Canada
   ~
   ~  Licensed under the Apache License, Version 2.0 (the "License");
   ~  you may not use this file except in compliance with the License.
@@ -50,6 +49,7 @@
         <powermock.version>1.7.4</powermock.version>
         <mockk.version>1.9</mockk.version>
         <dmaap.client.version>1.1.5</dmaap.client.version>
+        <jinja.version>2.5.0</jinja.version>
     </properties>
     <dependencyManagement>
         <dependencies>
                     </exclusion>
                 </exclusions>
             </dependency>
+            <dependency>
+                <groupId>com.hubspot.jinjava</groupId>
+                <artifactId>jinjava</artifactId>
+                <version>${jinja.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
index 9123efd..f505628 100644 (file)
@@ -1,5 +1,5 @@
 {
-  "description": " Velocity Template Resource Mapping File used along with Configuration template",
+  "description": " Velocity and jinja Templates Resource Mapping File used along with Configuration template",
   "version": "1.0.0",
   "file_ext": [
     "json"
diff --git a/ms/controllerblueprints/modules/blueprint-core/load/model_type/artifact_type/artifact-template-jinja.json b/ms/controllerblueprints/modules/blueprint-core/load/model_type/artifact_type/artifact-template-jinja.json
new file mode 100644 (file)
index 0000000..e32da5e
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "description": "Jinja Template used for Configuration",
+  "version": "1.0.0",
+  "file_ext": [
+    "jinja"
+  ],
+  "derived_from": "tosca.artifacts.Implementation"
+}
\ No newline at end of file
index 057038f..1420661 100644 (file)
@@ -1,5 +1,5 @@
 {
-       "description": "This is Configuration Velocity Template",
+       "description": "This is Configuration Velocity and Jinja Template",
        "version": "1.0.0",
        "properties": {
                "action-names": {
index 3342e36..524a42f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
   ~ Copyright © 2017-2018 AT&T Intellectual Property.
-  ~ Modifications Copyright © 2018 IBM.
+  ~ Modifications Copyright © 2018 - 2019 IBM, Bell Canada
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
             <groupId>org.apache.velocity</groupId>
             <artifactId>velocity</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.hubspot.jinjava</groupId>
+            <artifactId>jinjava</artifactId>
+        </dependency>
         <!--Testing dependencies-->
         <dependency>
             <groupId>org.jetbrains.kotlin</groupId>
index 23c52b4..9a652fb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
- * Modifications Copyright © 2018 IBM.
+ * Modifications Copyright © 2018 - 2019 IBM, Bell Canada
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -180,5 +180,6 @@ object BluePrintConstants {
     const val PROPERTY_CURRENT_IMPLEMENTATION = "current-implementation"
     const val PROPERTY_EXECUTION_REQUEST = "execution-request"
 
-
+    const val ARTIFACT_VELOCITY_TYPE_NAME = "artifact-template-velocity"
+    const val ARTIFACT_JINJA_TYPE_NAME = "artifact-template-jinja"
 }
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt
new file mode 100644 (file)
index 0000000..ec1542c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2019 IBM, Bell Canada.
+ *
+ * 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.
+ */
+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
+
+interface BlueprintTemplateService {
+
+    /**
+     * Generate dynamique content using Velocity Template or Jinja template
+     *
+     * @param template template string content
+     * @param json json string content
+     * @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
+}
+
+/**
+ * Customise JsonNodeFactory and TextNode, Since it introduces quotes for string data.
+ */
+open class BluePrintJsonNodeFactory : JsonNodeFactory() {
+    override fun textNode(text: String): TextNode {
+        return BluePrintTextNode(text)
+    }
+}
+
+open class BluePrintTextNode(v: String) : TextNode(v) {
+    override fun toString(): String {
+        var len = this._value.length
+        len = len + 2 + (len shr 4)
+        val sb = StringBuilder(len)
+        CharTypes.appendQuoted(sb, this._value)
+        return sb.toString()
+    }
+
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt
new file mode 100644 (file)
index 0000000..f835cbe
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2019 IBM, Bell Canada.
+ *
+ * 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.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core.service
+
+import com.fasterxml.jackson.databind.JsonNode
+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
+
+
+object BluePrintJinjaTemplateService: BlueprintTemplateService {
+
+    override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean,
+                                 additionalContext: MutableMap<String, Any>): String {
+        // Load template
+        val jinJava = Jinjava()
+        val mapper = ObjectMapper()
+        val nodeFactory = BluePrintJsonNodeFactory()
+        mapper.nodeFactory = nodeFactory
+
+        // 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 (ignoreJsonNull)
+                JacksonUtils.removeJsonNullNode(jsonNode)
+            jsonNode.fields().forEach { entry ->
+                additionalContext[entry.key] = entry.value
+            }
+        }
+
+        return jinJava.render(template, additionalContext.toMap())
+    }
+}
+
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateService.kt
deleted file mode 100644 (file)
index 4e2184d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright © 2017-2018 AT&T Intellectual Property.
- *
- * 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.
- */
-
-package org.onap.ccsdk.cds.controllerblueprints.core.service
-
-import com.fasterxml.jackson.core.io.CharTypes
-import com.fasterxml.jackson.databind.JsonNode
-import com.fasterxml.jackson.databind.ObjectMapper
-import com.fasterxml.jackson.databind.node.JsonNodeFactory
-import com.fasterxml.jackson.databind.node.TextNode
-import org.apache.commons.lang3.BooleanUtils
-import org.apache.commons.lang3.StringUtils
-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.utils.JacksonUtils
-import java.io.StringWriter
-
-open class BluePrintTemplateService {
-
-    companion object {
-
-        /**
-         * Generate Content from Velocity Template and JSON Content or property map.
-         */
-        fun generateContent(template: String, json: String = "",
-                            ignoreJsonNull: Boolean = false,
-                            additionalContext: Map<String, Any> = hashMapOf()): String {
-            Velocity.init()
-            val mapper = ObjectMapper()
-            val nodeFactory = BluePrintJsonNodeFactory()
-            mapper.nodeFactory = nodeFactory
-
-            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) }
-
-            // 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 (ignoreJsonNull)
-                    JacksonUtils.removeJsonNullNode(jsonNode)
-                jsonNode.fields().forEach { entry ->
-                    velocityContext.put(entry.key, entry.value)
-                }
-            }
-
-            val stringWriter = StringWriter()
-            Velocity.evaluate(velocityContext, stringWriter, "TemplateData", template)
-            stringWriter.flush()
-            return stringWriter.toString()
-        }
-    }
-}
-
-/**
- * Customise JsonNodeFactory adn TextNode, Since it introduces quotes for string data.
- */
-open class BluePrintJsonNodeFactory : JsonNodeFactory() {
-    override fun textNode(text: String): TextNode {
-        return BluePrintTextNode(text)
-    }
-}
-
-open class BluePrintTextNode(v: String) : TextNode(v) {
-    override fun toString(): String {
-        var len = this._value.length
-        len = len + 2 + (len shr 4)
-        val sb = StringBuilder(len)
-        CharTypes.appendQuoted(sb, this._value)
-        return sb.toString()
-    }
-
-}
-
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintVelocityTemplateService.kt
new file mode 100644 (file)
index 0000000..4b6905b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Modifications Copyright © 2019 IBM, Bell Canada.
+ *
+ * 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.
+ */
+
+package org.onap.ccsdk.cds.controllerblueprints.core.service
+
+import com.fasterxml.jackson.databind.JsonNode
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.apache.commons.lang3.BooleanUtils
+import org.apache.commons.lang3.StringUtils
+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 java.io.StringWriter
+
+object BluePrintVelocityTemplateService: BlueprintTemplateService {
+
+    /**
+     * Generate Content from Velocity Template and JSON Content or property map.
+     */
+    override suspend fun generateContent(template: String, json: String, ignoreJsonNull: Boolean, additionalContext:
+    MutableMap<String, Any>): String {
+        Velocity.init()
+        val mapper = ObjectMapper()
+        val nodeFactory = BluePrintJsonNodeFactory()
+        mapper.nodeFactory = nodeFactory
+
+        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) }
+
+        // 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 (ignoreJsonNull)
+                JacksonUtils.removeJsonNullNode(jsonNode)
+            jsonNode.fields().forEach { entry ->
+                velocityContext.put(entry.key, entry.value)
+            }
+        }
+
+        val stringWriter = StringWriter()
+        Velocity.evaluate(velocityContext, stringWriter, "TemplateData", template)
+        stringWriter.flush()
+        return stringWriter.toString()
+    }
+}
+
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt
new file mode 100644 (file)
index 0000000..73457b9
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright © 2019 IBM, Bell Canada
+ *
+ *  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.
+ */
+package org.onap.ccsdk.cds.controllerblueprints.core.service
+
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+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 {
+
+    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
+        return when (templateType) {
+            BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME -> {
+                BluePrintJinjaTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext)
+            }
+            BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME -> {
+                BluePrintVelocityTemplateService.generateContent(template, json, ignoreJsonNull, additionalContext)
+            }
+            else -> {
+                throw BluePrintProcessorException("Unknown Artifact type, expecting ${BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME}" +
+                        "or ${BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME}")
+            }
+        }
+    }
+
+    suspend fun generateContentFromFiles(templatePath: 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)
+    }
+}
\ No newline at end of file
index 6a193c3..e422718 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * Copyright © 2017-2018 AT&T Intellectual Property.
  *
+ * Modifications Copyright © 2019 IBM, Bell Canada.
+ *
  * 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
 
 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.utils.BluePrintMetadataUtils
 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.springframework.test.context.junit4.SpringRunner
+import kotlin.test.BeforeTest
 import kotlin.test.assertNotNull
 
+@RunWith(SpringRunner::class)
 class BluePrintTemplateServiceTest {
 
+    lateinit var blueprintRuntime: BluePrintRuntimeService<*>
+
+    @BeforeTest
+    fun setup() {
+        val blueprintBasePath: String = ("./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+        blueprintRuntime = BluePrintMetadataUtils.getBluePrintRuntime("1234", blueprintBasePath)
+    }
+
     @Test
-    fun testGenerateContent() {
+    fun testVelocityGeneratedContent() {
+       runBlocking {
+           val template = JacksonUtils.getClassPathFileContent("templates/base-config-velocity-template.vtl")
+           val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-velocity.json")
 
-        val template = JacksonUtils.getClassPathFileContent("templates/base-config-template.vtl")
-        val json = JacksonUtils.getClassPathFileContent("templates/base-config-data.json")
+           val content = BluePrintVelocityTemplateService.generateContent(template, json)
+           assertNotNull(content, "failed to generate content for velocity template")
+       }
 
-        val content = BluePrintTemplateService.generateContent(template, json)
-        assertNotNull(content, "failed to generate content for velocity template")
+    }
+
+    @Test
+    fun testJinjaGeneratedContent() {
+        runBlocking {
+            val template = JacksonUtils.getClassPathFileContent("templates/base-config-jinja-template.jinja")
+            val json = JacksonUtils.getClassPathFileContent("templates/base-config-data-jinja.json")
+
+            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 content = BluePrintJinjaTemplateService.generateContent(template, json, false, element)
+            assertNotNull(content, "failed to generate content for velocity template")
+        }
 
     }
-}
\ No newline at end of file
+
+    @Test
+    fun testVelocityGeneratedContentFromFiles() {
+        runBlocking {
+            val bluePrintTemplateService = BluePrintTemplateService(blueprintRuntime,
+                    "resource-assignment", "baseconfig-template")
+            val templateFile = "templates/base-config-velocity-template.vtl"
+            val jsonFile = "templates/base-config-data-velocity.json"
+
+            val content = bluePrintTemplateService.generateContentFromFiles(
+                    templateFile, jsonFile, false, mutableMapOf())
+            assertNotNull(content, "failed to generate content for velocity template")
+        }
+
+    }
+
+    @Test
+    fun testJinjaGeneratedContentFromFiles() {
+        runBlocking {
+            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 templateFile = "templates/base-config-jinja-template.jinja"
+            val jsonFile = "templates/base-config-data-jinja.json"
+
+            val content = bluePrintTemplateService.generateContentFromFiles(
+                    templateFile,
+                    jsonFile, false, element)
+            assertNotNull(content, "failed to generate content for velocity template")
+        }
+    }
+}
+
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data-jinja.json b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data-jinja.json
new file mode 100644 (file)
index 0000000..bbfb38d
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "node_hostname": "sdnc-host",
+  "node_backup_router_address": "2001:1890:1253::192:168:100:1",
+  "node_backup_router_d_address": "2011:1090:1253::112:158:100:1",
+  "servers": [
+    "Server1",
+    "Server2",
+    "Server3"
+  ],
+  "classes": [
+    "superuser-class",
+    "tacacs-adv-class",
+    "tacacs-base-class"
+  ],
+  "system_password": "teamops-system-password"
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-jinja-template.jinja b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-jinja-template.jinja
new file mode 100755 (executable)
index 0000000..db900bc
--- /dev/null
@@ -0,0 +1,42 @@
+<configuration xmlns="http://xml.juniper.net/xnm/1.1/xnm"
+xmlns:a="http://xml.juniper.net/junos/15.1X49/junos">
+       <version>15.1X49-D50.3</version>
+       <groups>
+               <name>node0</name>
+               <system>
+        {%- for server in servers %}
+            <server-host-name>{{ server }}</server-host-name>
+        {%- endfor %}
+        </system>
+               <system>
+                       <host-name>{{ node_hostname }}</host-name>
+                       <backup-router>
+                               <address>{{ node_backup_router_address }}</address>
+                               <destination>{{ node_backup_router_d_address }}</destination>
+                       </backup-router>
+                       <login>
+                               <message>ONAP information assets</message>
+                               {%- for class in classes %}
+                <class>
+                    {{ class }}
+                </class>
+                               {%- endfor %}
+                               <user>
+                                       <name>readwrite</name>
+                                       <full-name>Read - Write Account Access</full-name>
+                                       <uid>1002</uid>
+                                       <class>tacacs-adv-class</class>
+                                       <authentication>
+                                               <encrypted-password>{{ system_password }}</encrypted-password>
+                                       </authentication>
+                               </user>
+                       </login>
+                       {%- for element in additional_array %}
+                       <additionalArray>
+                <name>{{ element.name }}</name>
+                <location>{{ element.location }}</location>
+            </additionalArray>
+            {%- endfor %}
+               </system>
+       </groups>
+</configuration>
\ No newline at end of file
index f47a5b4..40a5c25 100644 (file)
@@ -4,6 +4,8 @@
   ~
   ~ Modifications Copyright © 2018 IBM.
   ~
+  ~ Modifications Copyright © 2019 IBM, Bell Canada
+  ~
   ~ 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
             <groupId>org.apache.velocity</groupId>
             <artifactId>velocity</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.hubspot.jinjava</groupId>
+            <artifactId>jinjava</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webflux</artifactId>
index 50cfae1..276c400 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ~ Copyright © 2017-2018 AT&T Intellectual Property.
   ~
-  ~ Modifications Copyright © 2018 IBM.
+  ~ Modifications Copyright © 2018 - 2019 IBM, Bell Canada
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@
         <onap.logger.slf4j>1.2.2</onap.logger.slf4j>
         <powermock.version>1.7.4</powermock.version>
         <mockk.version>1.9</mockk.version>
+        <jinja.version>2.5.0</jinja.version>
     </properties>
     <dependencyManagement>
         <dependencies>
                 <artifactId>velocity</artifactId>
                 <version>1.7</version>
             </dependency>
+            <dependency>
+                <groupId>com.hubspot.jinjava</groupId>
+                <artifactId>jinjava</artifactId>
+                <version>${jinja.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>