aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Timoney <dtimoney@att.com>2019-03-13 00:23:43 +0000
committerGerrit Code Review <gerrit@onap.org>2019-03-13 00:23:43 +0000
commite67ccb367e2cc3618ce4a9526a77c923373d13da (patch)
tree01d47fd967f85a0c3e33672d58154fecda0d2607
parentd77524d5f0b7445b3b64846c5332d4ce81752f46 (diff)
parent51b06267304d9c5dec53d15f9a2f9f614e843cbd (diff)
Merge "Mesh input-key-mapping using velocity"
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt22
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt28
-rw-r--r--ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt32
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintTemplateService.kt34
-rw-r--r--ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt44
-rw-r--r--ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/resource/dict/service/ResourceAssignmentValidationService.kt8
6 files changed, 88 insertions, 80 deletions
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt
index ca4d631b..bac76e72 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/DatabaseResourceAssignmentProcessor.kt
@@ -37,7 +37,6 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
import org.springframework.stereotype.Service
-import java.util.*
/**
* DatabaseResourceAssignmentProcessor
@@ -77,12 +76,16 @@ open class DatabaseResourceAssignmentProcessor(private val dBLibGenericService:
val sql = checkNotNull(sourceProperties.query) { "failed to get request query for $dName under $dSource properties" }
val inputKeyMapping = checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
- logger.info("$dSource dictionary information : ($sql), ($inputKeyMapping), (${sourceProperties.outputKeyMapping})")
+ val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping)
+
+ val resolvedSql = resolveFromInputKeyMapping(sql, resolvedInputKeyMapping)
+
+ logger.info("$dSource dictionary information : ($resolvedSql), ($inputKeyMapping), (${sourceProperties.outputKeyMapping})")
val jdbcTemplate = blueprintDBLibService(sourceProperties)
- val rows = jdbcTemplate.queryForList(sql, populateNamedParameter(inputKeyMapping))
+ val rows = jdbcTemplate.queryForList(resolvedSql, resolvedInputKeyMapping)
if (rows.isNullOrEmpty()) {
- logger.warn("Failed to get $dSource result for dictionary name ($dName) the query ($sql)")
+ logger.warn("Failed to get $dSource result for dictionary name ($dName) the query ($resolvedSql)")
} else {
populateResource(resourceAssignment, sourceProperties, rows)
}
@@ -115,17 +118,6 @@ open class DatabaseResourceAssignmentProcessor(private val dBLibGenericService:
}
}
- private fun populateNamedParameter(inputKeyMapping: Map<String, String>): Map<String, Any> {
- val namedParameters = HashMap<String, Any>()
- inputKeyMapping.forEach {
- val expressionValue = raRuntimeService.getDictionaryStore(it.value).textValue()
- logger.trace("Reference dictionary key (${it.key}) resulted in value ($expressionValue)")
- namedParameters[it.key] = expressionValue
- }
- logger.info("Parameter information : ({})", namedParameters)
- return namedParameters
- }
-
@Throws(BluePrintProcessorException::class)
private fun populateResource(resourceAssignment: ResourceAssignment, sourceProperties: DatabaseResourceSource, rows: List<Map<String, Any>>) {
val dName = resourceAssignment.dictionaryName
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
index 9b7c70aa..3022ca52 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/ResourceAssignmentProcessor.kt
@@ -17,12 +17,16 @@
package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.processor
+import org.apache.commons.collections.MapUtils
import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.ResourceAssignmentRuntimeService
import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BlueprintFunctionNode
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintTemplateService
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceDefinition
import org.slf4j.LoggerFactory
+import java.util.*
abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssignment, ResourceAssignment> {
@@ -38,12 +42,32 @@ abstract class ResourceAssignmentProcessor : BlueprintFunctionNode<ResourceAssig
*/
open fun <T> scriptPropertyInstanceType(name: String): T {
return scriptPropertyInstances as? T
- ?: throw BluePrintProcessorException("couldn't get script property instance ($name)")
+ ?: throw BluePrintProcessorException("couldn't get script property instance ($name)")
}
open fun resourceDefinition(name: String): ResourceDefinition {
return resourceDictionaries[name]
- ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
+ ?: throw BluePrintProcessorException("couldn't get resource definition for ($name)")
+ }
+
+ open fun resolveInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> {
+ val resolvedInputKeyMapping = HashMap<String, Any>()
+ if (MapUtils.isNotEmpty(inputKeyMapping)) {
+ for ((key, value) in inputKeyMapping) {
+ val resultValue = raRuntimeService.getResolutionStore(value)
+ val expressionValue = JacksonUtils.getValue(resultValue)
+ log.trace("Reference dictionary key ({}), value ({})", key, expressionValue)
+ resolvedInputKeyMapping[key] = expressionValue
+ }
+ }
+ return resolvedInputKeyMapping
+ }
+
+ open fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: Map<String, Any>): String {
+ if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
+ return valueToResolve
+ }
+ return BluePrintTemplateService.generateContent(valueToResolve, additionalContext = keyMapping)
}
override fun prepareRequest(resourceAssignment: ResourceAssignment): ResourceAssignment {
diff --git a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt
index 9bb1ea21..73ccfb2a 100644
--- a/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt
+++ b/ms/blueprintsprocessor/functions/resource-resolution/src/main/kotlin/org/onap/ccsdk/apps/blueprintsprocessor/functions/resource/resolution/processor/RestResourceResolutionProcessor.kt
@@ -19,8 +19,6 @@ package org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.pr
import com.fasterxml.jackson.databind.node.ArrayNode
import com.fasterxml.jackson.databind.node.JsonNodeFactory
-import com.fasterxml.jackson.databind.node.ObjectNode
-import org.apache.commons.collections.MapUtils
import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.ResourceResolutionConstants.PREFIX_RESOURCE_RESOLUTION_PROCESSOR
import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.RestResourceSource
import org.onap.ccsdk.apps.blueprintsprocessor.functions.resource.resolution.utils.ResourceAssignmentUtils
@@ -40,7 +38,6 @@ import org.slf4j.LoggerFactory
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
import org.springframework.stereotype.Service
-import java.util.*
/**
* RestResourceResolutionProcessor
@@ -81,7 +78,7 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
val path = nullToEmpty(sourceProperties.path)
val inputKeyMapping =
checkNotNull(sourceProperties.inputKeyMapping) { "failed to get input-key-mappings for $dName under $dSource properties" }
- val resolvedInputKeyMapping = populateInputKeyMappingVariables(inputKeyMapping)
+ val resolvedInputKeyMapping = resolveInputKeyMappingVariables(inputKeyMapping)
// Resolving content Variables
val payload = resolveFromInputKeyMapping(nullToEmpty(sourceProperties.payload), resolvedInputKeyMapping)
@@ -170,7 +167,9 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
}
else -> {
// Complex Types
- val objectNode = responseNode as ObjectNode
+ entrySchemaType =
+ returnNotEmptyOrThrow(resourceAssignment.property?.entrySchema?.type) { "Entry schema is not defined for dictionary ($dName) info" }
+ val objectNode = JsonNodeFactory.instance.objectNode()
outputKeyMapping.map {
val responseKeyValue = responseNode.get(it.key)
val propertyTypeForDataType =
@@ -186,29 +185,6 @@ open class RestResourceResolutionProcessor(private val blueprintRestLibPropertyS
}
}
- private fun populateInputKeyMappingVariables(inputKeyMapping: Map<String, String>): Map<String, Any> {
- val resolvedInputKeyMapping = HashMap<String, Any>()
- if (MapUtils.isNotEmpty(inputKeyMapping)) {
- for ((key, value) in inputKeyMapping) {
- val expressionValue = raRuntimeService.getResolutionStore(value).asText()
- logger.trace("Reference dictionary key ({}), value ({})", key, expressionValue)
- resolvedInputKeyMapping[key] = expressionValue
- }
- }
- return resolvedInputKeyMapping
- }
-
- private fun resolveFromInputKeyMapping(valueToResolve: String, keyMapping: Map<String, Any>): String {
- if (valueToResolve.isEmpty() || !valueToResolve.contains("$")) {
- return valueToResolve
- }
- var res = valueToResolve
- for (entry in keyMapping.entries) {
- res = res.replace(("\\$" + entry.key).toRegex(), entry.value.toString())
- }
- return res
- }
-
@Throws(BluePrintProcessorException::class)
private fun validate(resourceAssignment: ResourceAssignment) {
checkNotEmptyOrThrow(resourceAssignment.name, "resource assignment template key is not defined")
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintTemplateService.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintTemplateService.kt
index d175fdde..4fa69cad 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintTemplateService.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintTemplateService.kt
@@ -34,34 +34,32 @@ open class BluePrintTemplateService {
companion object {
/**
- * Generate Content from Velocity Template and JSON Content.
+ * Generate Content from Velocity Template and JSON Content or property map.
*/
- fun generateContent(template: String, json: String,
+ fun generateContent(template: String, json: String = "",
ignoreJsonNull: Boolean = false,
- additionalContext: MutableMap<String, Any> = hashMapOf()): String {
+ additionalContext: Map<String, Any> = hashMapOf()): String {
Velocity.init()
val mapper = ObjectMapper()
val nodeFactory = BluePrintJsonNodeFactory()
- mapper.setNodeFactory(nodeFactory)
-
- val jsonNode = mapper.readValue<JsonNode>(json, JsonNode::class.java)
- ?: throw BluePrintProcessorException("couldn't get json node from json")
-
- if (ignoreJsonNull)
- JacksonUtils.removeJsonNullNode(jsonNode)
+ mapper.nodeFactory = nodeFactory
val velocityContext = VelocityContext()
velocityContext.put("StringUtils", StringUtils::class.java)
velocityContext.put("BooleanUtils", BooleanUtils::class.java)
- /**
- * Add the Custom Velocity Context API
- */
+
+ // Add the Custom Velocity Context API
additionalContext.forEach { name, value -> velocityContext.put(name, value) }
- /**
- * Add the JSON Data to the context
- */
- jsonNode.fields().forEach { entry ->
- velocityContext.put(entry.key, entry.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()
diff --git a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt
index 932f0edc..e0341b8a 100644
--- a/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt
+++ b/ms/controllerblueprints/modules/blueprint-core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt
@@ -22,8 +22,13 @@ import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.node.ArrayNode
+import com.fasterxml.jackson.databind.node.BooleanNode
+import com.fasterxml.jackson.databind.node.DoubleNode
+import com.fasterxml.jackson.databind.node.FloatNode
+import com.fasterxml.jackson.databind.node.IntNode
import com.fasterxml.jackson.databind.node.NullNode
import com.fasterxml.jackson.databind.node.ObjectNode
+import com.fasterxml.jackson.databind.node.TextNode
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
@@ -46,7 +51,7 @@ class JacksonUtils {
companion object {
private val log: EELFLogger = EELFManager.getInstance().getLogger(this::class.toString())
inline fun <reified T : Any> readValue(content: String): T =
- jacksonObjectMapper().readValue(content, T::class.java)
+ jacksonObjectMapper().readValue(content, T::class.java)
fun <T> readValue(content: String, valueType: Class<T>): T? {
return jacksonObjectMapper().readValue(content, valueType)
@@ -84,7 +89,7 @@ class JacksonUtils {
return runBlocking {
withContext(Dispatchers.Default) {
IOUtils.toString(JacksonUtils::class.java.classLoader
- .getResourceAsStream(fileName), Charset.defaultCharset())
+ .getResourceAsStream(fileName), Charset.defaultCharset())
}
}
}
@@ -184,7 +189,7 @@ class JacksonUtils {
fun <T> getInstanceFromMap(properties: MutableMap<String, JsonNode>, classType: Class<T>): T {
return readValue(getJson(properties), classType)
- ?: throw BluePrintProcessorException("failed to transform content ($properties) to type ($classType)")
+ ?: throw BluePrintProcessorException("failed to transform content ($properties) to type ($classType)")
}
fun checkJsonNodeValueOfType(type: String, jsonNode: JsonNode): Boolean {
@@ -228,14 +233,35 @@ class JacksonUtils {
}
}
+ fun getValue(value: JsonNode): Any {
+ return when (value) {
+ is BooleanNode -> value.booleanValue()
+ is IntNode -> value.intValue()
+ is FloatNode -> value.floatValue()
+ is DoubleNode -> value.doubleValue()
+ is TextNode -> value.textValue()
+ else -> value
+ }
+ }
+
+ fun getValue(value: Any, type: String): Any {
+ return when (type.toLowerCase()) {
+ BluePrintConstants.DATA_TYPE_BOOLEAN -> (value as BooleanNode).booleanValue()
+ BluePrintConstants.DATA_TYPE_INTEGER -> (value as IntNode).intValue()
+ BluePrintConstants.DATA_TYPE_FLOAT -> (value as FloatNode).floatValue()
+ BluePrintConstants.DATA_TYPE_DOUBLE -> (value as DoubleNode).doubleValue()
+ BluePrintConstants.DATA_TYPE_STRING -> (value as TextNode).textValue()
+ else -> (value as JsonNode)
+ }
+ }
+
fun populatePrimitiveValues(key: String, value: Any, primitiveType: String, objectNode: ObjectNode) {
when (primitiveType.toLowerCase()) {
- BluePrintConstants.DATA_TYPE_BOOLEAN -> objectNode.put(key, value as Boolean)
- BluePrintConstants.DATA_TYPE_INTEGER -> objectNode.put(key, value as Int)
- BluePrintConstants.DATA_TYPE_FLOAT -> objectNode.put(key, value as Float)
- BluePrintConstants.DATA_TYPE_DOUBLE -> objectNode.put(key, value as Double)
- BluePrintConstants.DATA_TYPE_TIMESTAMP -> objectNode.put(key, value as String)
- else -> objectNode.put(key, value as String)
+ BluePrintConstants.DATA_TYPE_BOOLEAN -> objectNode.put(key, (value as BooleanNode).booleanValue())
+ BluePrintConstants.DATA_TYPE_INTEGER -> objectNode.put(key, (value as IntNode).intValue())
+ BluePrintConstants.DATA_TYPE_FLOAT -> objectNode.put(key, (value as FloatNode).floatValue())
+ BluePrintConstants.DATA_TYPE_DOUBLE -> objectNode.put(key, (value as DoubleNode).doubleValue())
+ else -> objectNode.put(key, (value as TextNode).textValue())
}
}
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/resource/dict/service/ResourceAssignmentValidationService.kt b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/resource/dict/service/ResourceAssignmentValidationService.kt
index b35bca74..cd1dd431 100644
--- a/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/resource/dict/service/ResourceAssignmentValidationService.kt
+++ b/ms/controllerblueprints/modules/resource-dict/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/resource/dict/service/ResourceAssignmentValidationService.kt
@@ -76,14 +76,6 @@ open class ResourceAssignmentValidationServiceImpl : ResourceAssignmentValidatio
validationMessage.appendln(String.format("Duplicate Assignment Template Keys (%s) is Present", duplicateKeyNames))
}
- // Check the Resource Assignment has Duplicate Dictionary Names
- val duplicateDictionaryKeyNames = resourceAssignments.groupBy { it.dictionaryName }
- .filter { it.value.size > 1 }
- .map { it.key }
- if (duplicateDictionaryKeyNames.isNotEmpty()) {
- validationMessage.appendln(String.format("Duplicate Assignment Dictionary Keys (%s) is Present", duplicateDictionaryKeyNames))
- }
-
// Collect all the dependencies as a single list
val dependenciesNames = resourceAssignments.mapNotNull { it.dependencies }.flatten()