summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexis de Talhouët <adetalhouet89@gmail.com>2019-06-18 19:43:50 -0400
committerAlexis de Talhouët <adetalhouet89@gmail.com>2019-06-21 01:10:53 +0000
commit7ad72c86fbd10888a849eed2b00dc9fddadef5aa (patch)
tree28ea065a77e3ce60b14603b86748aeed87f9d80b
parent091bba704d8e9137b9bca9ed02d139539aa2ac53 (diff)
Add Jinja2 custom ResourceLocator
This will allow to include template within template to create template hierarchy Change-Id: I21c5deaf51d391e1a51b9863a905c26b1891db16 Issue-ID: CCSDK-1417 Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
-rw-r--r--ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt6
-rw-r--r--ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts1
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt5
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/interfaces/BlueprintTemplateService.kt15
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintJinjaTemplateService.kt59
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BlueprintTemplateService.kt29
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt61
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-data-jinja.json15
-rwxr-xr-xms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-jinja-template.jinja42
-rwxr-xr-xms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/interface.jinja3
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/isis.jinja3
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/master.jinja7
12 files changed, 96 insertions, 150 deletions
diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt
index c7f35f7c8..1b84964e8 100644
--- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt
+++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/cli/executor/CliComponentFunction.kt
@@ -41,12 +41,6 @@ abstract class CliComponentFunction : AbstractScriptComponentFunction() {
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)
}
diff --git a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts
index 18d4a4797..0955ace79 100644
--- a/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts
+++ b/ms/blueprintsprocessor/functions/cli-executor/src/main/kotlin/scripts/InternalSimpleCli.cba.kts
@@ -20,6 +20,7 @@ import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInpu
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.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintTemplateService
import org.slf4j.LoggerFactory
open class TestCliScriptFunction : CliComponentFunction() {
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
index ebff47899..fe5906220 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/resource/resolution/ResourceResolutionService.kt
@@ -59,7 +59,8 @@ interface ResourceResolutionService {
@Service(ResourceResolutionConstants.SERVICE_RESOURCE_RESOLUTION)
open class ResourceResolutionServiceImpl(private var applicationContext: ApplicationContext,
- private var resolutionResultService: ResourceResolutionResultService) :
+ private var resolutionResultService: ResourceResolutionResultService,
+ private var blueprintTemplateService: BluePrintTemplateService) :
ResourceResolutionService {
private val log = LoggerFactory.getLogger(ResourceResolutionService::class.java)
@@ -137,7 +138,6 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
// Check Template is there
if (artifactTemplate != null) {
- val blueprintTemplateService = BluePrintTemplateService()
resolvedContent = blueprintTemplateService.generateContent(bluePrintRuntimeService, nodeTemplateName,
artifactTemplate, resolvedParamJsonContent)
@@ -189,6 +189,7 @@ open class ResourceResolutionServiceImpl(private var applicationContext: Applica
// Set errors from RA
blueprintRuntimeService.setBluePrintError(resourceAssignmentRuntimeService.getBluePrintError())
} catch (e: RuntimeException) {
+ log.error("Fail in processing ${resourceAssignment.name}", e)
throw BluePrintProcessorException(e)
}
}
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
index 86bf3ff56..98abf8987 100644
--- 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
@@ -40,21 +40,6 @@ interface BlueprintTemplateService {
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 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, templateType: String, jsonData: String = "", ignoreJsonNull: Boolean = false,
- additionalContext: MutableMap<String, Any> = mutableMapOf()): String
}
/**
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
index 1dbbd9977..baddd6a12 100644
--- 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
@@ -19,18 +19,73 @@ package org.onap.ccsdk.cds.controllerblueprints.core.service
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
+import com.google.common.io.Resources
import com.hubspot.jinjava.Jinjava
+import com.hubspot.jinjava.interpret.Context
+import com.hubspot.jinjava.interpret.JinjavaInterpreter
+import com.hubspot.jinjava.loader.ClasspathResourceLocator
+import com.hubspot.jinjava.loader.ResourceLocator
+import com.hubspot.jinjava.loader.ResourceNotFoundException
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
+import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintLoadConfiguration
+import org.onap.ccsdk.cds.controllerblueprints.core.config.BluePrintPathConfiguration
import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintJsonNodeFactory
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
+import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName
import org.onap.ccsdk.cds.controllerblueprints.core.removeNullNode
+import org.springframework.context.annotation.Scope
+import org.springframework.stereotype.Service
+import java.io.IOException
+import java.nio.charset.Charset
+import java.nio.file.Files.readAllBytes
+import java.nio.file.Paths
object BluePrintJinjaTemplateService {
+ /**
+ * To enable inheritance within CBA, we need Jinja runtime to know where to load the templates.
+ */
+ class BlueprintRelatedTemplateLocator(private val bluePrintPathConfiguration: BluePrintPathConfiguration,
+ private val artifactName: String,
+ private val artifactVersion: String) : ResourceLocator {
+
+ @Throws(IOException::class)
+ override fun getString(fullName: String, encoding: Charset, interpreter: JinjavaInterpreter): String {
+ try {
+ val deployFile =
+ normalizedPathName(bluePrintPathConfiguration.blueprintDeployPath,
+ artifactName,
+ artifactVersion,
+ fullName)
+
+ return String(readAllBytes(Paths.get(deployFile)))
+ } catch (var5: IllegalArgumentException) {
+ throw ResourceNotFoundException("Couldn't find resource: $fullName")
+ }
+
+ }
+ }
+
fun generateContent(template: String, json: String, ignoreJsonNull: Boolean,
- additionalContext: MutableMap<String, Any>): String {
+ additionalContext: MutableMap<String, Any>,
+ bluePrintPathConfiguration: BluePrintPathConfiguration, artifactName: String,
+ artifactVersion: String): String {
- // Load template
+
+ return generateContent(template,
+ json,
+ ignoreJsonNull,
+ additionalContext,
+ BlueprintRelatedTemplateLocator(bluePrintPathConfiguration, artifactName, artifactVersion))
+ }
+
+ fun generateContent(template: String, json: String, ignoreJsonNull: Boolean,
+ additionalContext: MutableMap<String, Any>, resourceLocator: ResourceLocator? = null): String {
val jinJava = Jinjava()
+ if (resourceLocator != null) {
+ jinJava.resourceLocator = resourceLocator
+ }
+
val mapper = ObjectMapper()
val nodeFactory = BluePrintJsonNodeFactory()
mapper.nodeFactory = nodeFactory
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
index 45e2678ed..af97d6691 100644
--- 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
@@ -17,26 +17,33 @@ 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.config.BluePrintPathConfiguration
import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BlueprintTemplateService
import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.springframework.stereotype.Service
-class BluePrintTemplateService : BlueprintTemplateService {
+@Service
+class BluePrintTemplateService(private val bluePrintPathConfiguration: BluePrintPathConfiguration) :
+ BlueprintTemplateService {
override suspend fun generateContent(bluePrintRuntimeService: BluePrintRuntimeService<*>,
nodeTemplateName: String, artifactName: String, jsonData: String,
ignoreJsonNull: Boolean, additionalContext: MutableMap<String, Any>): String {
- val artifactDefinition = bluePrintRuntimeService.resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
+ 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, jsonData, ignoreJsonNull, additionalContext)
+ BluePrintJinjaTemplateService.generateContent(template,
+ jsonData,
+ ignoreJsonNull,
+ additionalContext,
+ bluePrintPathConfiguration,
+ bluePrintRuntimeService.bluePrintContext().name(),
+ bluePrintRuntimeService.bluePrintContext().version())
}
BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME -> {
BluePrintVelocityTemplateService.generateContent(template, jsonData, ignoreJsonNull, additionalContext)
@@ -47,12 +54,4 @@ class BluePrintTemplateService : BlueprintTemplateService {
}
}
}
-
- 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, templateType, json, ignoreJsonNull, additionalContext)
- }
} \ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
index 6f961c8ed..63c8ad74e 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintTemplateServiceTest.kt
@@ -36,7 +36,8 @@ class BluePrintTemplateServiceTest {
@BeforeTest
fun setup() {
- val blueprintBasePath: String = ("./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
+ val blueprintBasePath: String =
+ ("./../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration")
blueprintRuntime = BluePrintMetadataUtils.getBluePrintRuntime("1234", blueprintBasePath)
}
@@ -55,11 +56,12 @@ class BluePrintTemplateServiceTest {
@Test
fun testJinjaGeneratedContent() {
runBlocking {
- val template = JacksonUtils.getClassPathFileContent("templates/base-config-jinja-template.jinja")
+ val template = JacksonUtils.getClassPathFileContent("templates/master.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"))
+ 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")
@@ -67,42 +69,12 @@ class BluePrintTemplateServiceTest {
}
- @Test
- fun testVelocityGeneratedContentFromFiles() {
- runBlocking {
- val bluePrintTemplateService = BluePrintTemplateService()
- val templateFile = "templates/base-config-velocity-template.vtl"
- val jsonFile = "templates/base-config-data-velocity.json"
-
- val content = bluePrintTemplateService.generateContentFromFiles(
- templateFile, BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, 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()
-
- val templateFile = "templates/base-config-jinja-template.jinja"
- val jsonFile = "templates/base-config-data-jinja.json"
-
- val content = bluePrintTemplateService.generateContentFromFiles(
- templateFile, BluePrintConstants.ARTIFACT_JINJA_TYPE_NAME,
- jsonFile, false, element)
- assertNotNull(content, "failed to generate content for velocity template")
- }
- }
@Test
fun `no value variable should evaluate to default value - standalone template mesh test`() {
runBlocking {
- val template = JacksonUtils.getClassPathFileContent("templates/default-variable-value-velocity-template.vtl")
+ val template =
+ JacksonUtils.getClassPathFileContent("templates/default-variable-value-velocity-template.vtl")
val json = JacksonUtils.getClassPathFileContent("templates/default-variable-value-data.json")
val content = BluePrintVelocityTemplateService.generateContent(template, json)
@@ -113,24 +85,5 @@ class BluePrintTemplateServiceTest {
}
}
- @Test
- fun `no value variable should evaluate to default value - blueprint processing test`() {
- runBlocking {
- val bluePrintTemplateService = BluePrintTemplateService()
-
- val templateFile = "templates/default-variable-value-velocity-template.vtl"
- val jsonFile = "templates/default-variable-value-data.json"
-
- val content = bluePrintTemplateService.generateContentFromFiles(templateFile,
- BluePrintConstants.ARTIFACT_VELOCITY_TYPE_NAME, jsonFile, false, mutableMapOf())
-
- //first line represents a variable whose value was successfully retrieved, second line contains a variable
- // whose value could not be evaluated
- val expected = "sample-hostname\n\${node0_backup_router_address}"
- assertEquals(expected, content, "No value variable should use default value")
- }
-
- }
-
}
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
index bbfb38d80..ab7abf3d4 100644
--- 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
@@ -1,16 +1,3 @@
{
- "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"
+ "occurrence": 2
} \ 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
deleted file mode 100755
index db900bc8b..000000000
--- a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/base-config-jinja-template.jinja
+++ /dev/null
@@ -1,42 +0,0 @@
-<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
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/interface.jinja b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/interface.jinja
new file mode 100755
index 000000000..93114d90a
--- /dev/null
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/interface.jinja
@@ -0,0 +1,3 @@
+ <interface-configurations xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg">
+blo
+ </interface-configurations> \ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/isis.jinja b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/isis.jinja
new file mode 100644
index 000000000..f46d91330
--- /dev/null
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/isis.jinja
@@ -0,0 +1,3 @@
+ <isis xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-clns-isis-cfg">
+blah
+ </isis> \ No newline at end of file
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/master.jinja b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/master.jinja
new file mode 100644
index 000000000..1137b2595
--- /dev/null
+++ b/ms/controllerblueprints/modules/blueprint-core/src/test/resources/templates/master.jinja
@@ -0,0 +1,7 @@
+{%- for i in range(occurrence) %}
+<config>
+{% include "templates/isis.jinja" %}
+{% include "templates/interface.jinja" %}
+</config>
+{{ "]]>]]" if not loop.last }}
+{%- endfor %} \ No newline at end of file