diff options
author | Alexis de Talhouët <adetalhouet89@gmail.com> | 2019-06-18 19:43:50 -0400 |
---|---|---|
committer | Alexis de Talhouët <adetalhouet89@gmail.com> | 2019-06-21 01:10:53 +0000 |
commit | 7ad72c86fbd10888a849eed2b00dc9fddadef5aa (patch) | |
tree | 28ea065a77e3ce60b14603b86748aeed87f9d80b | |
parent | 091bba704d8e9137b9bca9ed02d139539aa2ac53 (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>
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 |