import org.springframework.context.annotation.Scope
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
import org.springframework.stereotype.Service
-import java.util.*
/**
* DatabaseResourceAssignmentProcessor
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)
}
}
}
- 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
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> {
*/
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 {
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
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
import org.springframework.stereotype.Service
-import java.util.*
/**
* RestResourceResolutionProcessor
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)
}
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 =
}
}
- 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")
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()
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
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)
return runBlocking {
withContext(Dispatchers.Default) {
IOUtils.toString(JacksonUtils::class.java.classLoader
- .getResourceAsStream(fileName), Charset.defaultCharset())
+ .getResourceAsStream(fileName), Charset.defaultCharset())
}
}
}
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 {
}
}
+ 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())
}
}
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()