From 1fdaf4953daf15970afe6ee10491dfa2d0a76753 Mon Sep 17 00:00:00 2001 From: Brinda Santh Date: Fri, 27 Dec 2019 15:43:53 -0500 Subject: Runtime services for Relationship Type and Templates Added and improved blueprint runtime service property resolution api. Relationship template CBA sample Performance improvement on Artifact resolutions. Added connection config DSL for DB, GRPC connections. Added starter relationship connection config models. Issue-ID: CCSDK-1054 Signed-off-by: Brinda Santh Change-Id: I73e1deed708dc924352867ddd1d1b2271c8ea106 --- .../core/BluePrintConstants.kt | 5 + .../core/service/BluePrintChainedService.kt | 2 +- .../core/service/BluePrintContext.kt | 10 + .../core/service/BluePrintRuntimeService.kt | 259 +++++++++++++++------ .../core/service/PropertyAssignmentService.kt | 157 +++++++++---- .../core/utils/ServiceTemplateUtils.kt | 21 +- .../core/service/BluePrintRuntimeServiceTest.kt | 22 ++ .../resource/dict/ResourceDefinition.kt | 5 +- 8 files changed, 348 insertions(+), 133 deletions(-) (limited to 'ms/blueprintsprocessor/modules/blueprints') diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt index f0e2c5b03..d1254b24e 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/BluePrintConstants.kt @@ -81,6 +81,7 @@ object BluePrintConstants { const val PATH_INPUTS: String = "inputs" const val PATH_NODE_WORKFLOWS: String = "workflows" const val PATH_NODE_TEMPLATES: String = "node_templates" + const val PATH_RELATIONSHIP_TEMPLATES: String = "relationship_templates" const val PATH_CAPABILITIES: String = "capabilities" const val PATH_REQUIREMENTS: String = "requirements" const val PATH_INTERFACES: String = "interfaces" @@ -97,6 +98,10 @@ object BluePrintConstants { const val MODEL_DEFINITION_TYPE_CAPABILITY_TYPE: String = "capability_type" const val MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE: String = "relationship_type" const val MODEL_DEFINITION_TYPE_DATA_TYPE: String = "data_type" + const val MODEL_DEFINITION_TYPE_NODE_TEMPLATE: String = "node_template" + const val MODEL_DEFINITION_TYPE_RELATIONSHIP_TEMPLATE: String = "relationship_template" + const val MODEL_DEFINITION_TYPE_WORKFLOW: String = "workflow" + const val MODEL_DEFINITION_TYPE_DSL: String = "dsl" const val MODEL_TYPE_DATATYPES_ROOT: String = "tosca.datatypes.Root" const val MODEL_TYPE_NODES_ROOT: String = "tosca.nodes.Root" diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintChainedService.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintChainedService.kt index 7d85963dc..1a43c3066 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintChainedService.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintChainedService.kt @@ -31,7 +31,7 @@ import org.onap.ccsdk.cds.controllerblueprints.core.data.RequirementDefinition * * @author Brinda Santh */ -class BluePrintChainedService { +internal class BluePrintChainedService { var bpc: BluePrintContext diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt index 52fdbb588..a112b6e6c 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintContext.kt @@ -325,6 +325,16 @@ class BluePrintContext(val serviceTemplate: ServiceTemplate) { return nodeTemplateByName(relationshipTemplateName).properties?.get(propertyName) } + fun relationshipTemplateForRelationshipType(name: String): MutableMap? { + return relationshipTemplates()?.filterValues { relationshipTemplate -> relationshipTemplate.type == name } + ?.toMutableMap() + } + + fun relationshipTemplateRelationshipType(relationshipName: String): RelationshipType { + val relationshipTemplateType: String = relationshipTemplateByName(relationshipName).type + return relationshipTypeByName(relationshipTemplateType) + } + // Chained Functions fun nodeTypeChained(nodeTypeName: String): NodeType { diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt index 841cc5242..d68d680dd 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeService.kt @@ -69,20 +69,50 @@ interface BluePrintRuntimeService { fun loadEnvironments(type: String, fileName: String) - fun resolveNodeTemplatePropertyAssignments( - nodeTemplateName: String, + fun resolveWorkflowOutputs(workflowName: String): MutableMap + + fun resolveDSLExpression(dslPropertyName: String): JsonNode + + /** Resolve Property Definition [definitionName] for type [definitionType] with [propertyDefinitions] + * Definition Type may be : node_template, relationship_template, dsl, workflow + * Assumption is Definition holds the expressions or value assigned in it. Mainly used for workflow outputs. + */ + fun resolvePropertyDefinitions( + definitionType: String, + definitionName: String, + propertyDefinitions: MutableMap + ): MutableMap + + /** Resolve Property Assignments [definitionName] for type [definitionType] with [propertyDefinitions] + * and [propertyAssignments] + * Definition Type may be : node_template, relationship_template, dsl, workflow + */ + fun resolvePropertyAssignments( + definitionType: String, + definitionName: String, propertyDefinitions: MutableMap, propertyAssignments: MutableMap ): MutableMap - fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap): - MutableMap - - fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap): - MutableMap + /** Resolve Property Assignments [definitionName] for type [definitionType] with [propertyAssignments] + * Definition Type may be : node_template, relationship_template, dsl, workflow + */ + fun resolvePropertyAssignments( + definitionType: String, + definitionName: String, + propertyAssignments: MutableMap + ): MutableMap + /** Resolve Node Template [nodeTemplateName] Property Assignments */ fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap + /** Resolve Node Template [nodeTemplateName] Property Assignments with [propertyDefinitions] and [propertyAssignments]*/ + fun resolveNodeTemplatePropertyAssignments( + nodeTemplateName: String, + propertyDefinitions: MutableMap, + propertyAssignments: MutableMap + ): MutableMap + fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap @@ -98,13 +128,20 @@ interface BluePrintRuntimeService { operationName: String ): MutableMap - fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String + suspend fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition + /** Resolve Node Template [relationshipTemplateName] Property Assignments */ fun resolveRelationshipTemplateProperties(relationshipTemplateName: String): MutableMap - fun resolveDSLExpression(dslPropertyName: String): JsonNode + /** Resolve Relationship Template [relationshipTemplateName] Property Assignments with + * [propertyDefinitions] and [propertyAssignments] */ + fun resolveRelationshipTemplatePropertyAssignments( + relationshipTemplateName: String, + propertyDefinitions: MutableMap, + propertyAssignments: MutableMap + ): MutableMap fun setInputValue(propertyName: String, value: JsonNode) @@ -156,13 +193,17 @@ interface BluePrintRuntimeService { fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode? + fun getRelationshipTemplatePropertyValue(relationshipTemplateName: String, propertyName: String): JsonNode? + + fun getRelationshipTemplateAttributeValue(relationshipTemplateName: String, attributeName: String): JsonNode? + fun assignInputs(jsonNode: JsonNode) fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) - fun resolveWorkflowOutputs(workflowName: String): MutableMap - fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List): JsonNode + + suspend fun close() } /** @@ -256,15 +297,68 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl } } + override fun resolveWorkflowOutputs(workflowName: String): MutableMap { + log.info("resolveWorkflowOutputs for workflow($workflowName)") + val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf() + return resolvePropertyDefinitions(BluePrintConstants.MODEL_DEFINITION_TYPE_WORKFLOW, "WORKFLOW", outputs) + } + /** - * Resolve any property assignments for the node + * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json + * Type */ - override fun resolveNodeTemplatePropertyAssignments( - nodeTemplateName: String, + override fun resolveDSLExpression(dslPropertyName: String): JsonNode { + val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName) + return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments) && + propertyAssignments is ObjectNode + ) { + val rootKeyMap = propertyAssignments.rootFieldsToMap() + val propertyAssignmentValue: MutableMap = hashMapOf() + rootKeyMap.forEach { (propertyName, propertyValue) -> + val propertyAssignmentExpression = PropertyAssignmentService(this) + propertyAssignmentValue[propertyName] = propertyAssignmentExpression + .resolveAssignmentExpression( + BluePrintConstants.MODEL_DEFINITION_TYPE_DSL, + "DSL", + propertyName, + propertyValue + ) + } + propertyAssignmentValue.asJsonNode() + } else { + propertyAssignments + } + } + + override fun resolvePropertyDefinitions( + definitionType: String, + definitionName: String, + propertyDefinitions: MutableMap + ): MutableMap { + val propertyAssignmentValue: MutableMap = hashMapOf() + + propertyDefinitions.forEach { (propertyName, propertyDefinition) -> + val propertyAssignmentExpression = PropertyAssignmentService(this) + val expression = propertyDefinition.value ?: propertyDefinition.defaultValue + if (expression != null) { + propertyAssignmentValue[propertyName] = + propertyAssignmentExpression.resolveAssignmentExpression( + definitionType, + definitionName, + propertyName, + expression + ) + } + } + return propertyAssignmentValue + } + + override fun resolvePropertyAssignments( + definitionType: String, + definitionName: String, propertyDefinitions: MutableMap, propertyAssignments: MutableMap - ): - MutableMap { + ): MutableMap { val propertyAssignmentValue: MutableMap = hashMapOf() @@ -277,7 +371,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl // Resolve the Expressing val propertyAssignmentExpression = PropertyAssignmentService(this) resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression( - nodeTemplateName, nodeTypePropertyName, propertyAssignment + definitionType, definitionName, nodeTypePropertyName, propertyAssignment ) } @@ -286,11 +380,13 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl nodeTypeProperty.defaultValue?.let { resolvedValue = nodeTypeProperty.defaultValue!! } } - /** If property is Map type, then resolve the property value, It may have expressiong */ + /** If property is Map type, then resolve the property value, It may have expressions */ if (nodeTypeProperty.type == BluePrintConstants.DATA_TYPE_MAP && resolvedValue.returnNullIfMissing() != null ) { - val mapResolvedValue = resolvePropertyAssignments(nodeTemplateName, resolvedValue.rootFieldsToMap()) + val mapResolvedValue = resolvePropertyAssignments( + definitionType, definitionName, resolvedValue.rootFieldsToMap() + ) resolvedValue = mapResolvedValue.asJsonNode() } @@ -300,29 +396,19 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl return propertyAssignmentValue } - override fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap): - MutableMap { - val propertyAssignmentValue: MutableMap = hashMapOf() - - propertyDefinitions.forEach { propertyName, propertyDefinition -> - val propertyAssignmentExpression = PropertyAssignmentService(this) - val expression = propertyDefinition.value ?: propertyDefinition.defaultValue - if (expression != null) { - propertyAssignmentValue[propertyName] = - propertyAssignmentExpression.resolveAssignmentExpression(name, propertyName, expression) - } - } - return propertyAssignmentValue - } - - override fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap): - MutableMap { + override fun resolvePropertyAssignments( + definitionType: String, + definitionName: String, + propertyAssignments: MutableMap + ): MutableMap { val propertyAssignmentValue: MutableMap = hashMapOf() propertyAssignments.forEach { (propertyName, propertyExpression) -> val propertyAssignmentExpression = PropertyAssignmentService(this) propertyAssignmentValue[propertyName] = - propertyAssignmentExpression.resolveAssignmentExpression(name, propertyName, propertyExpression) + propertyAssignmentExpression.resolveAssignmentExpression( + definitionType, definitionName, propertyName, propertyExpression + ) } return propertyAssignmentValue } @@ -348,6 +434,20 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl ) } + /** + * Resolve any property assignments for the node + */ + override fun resolveNodeTemplatePropertyAssignments( + nodeTemplateName: String, + propertyDefinitions: MutableMap, + propertyAssignments: MutableMap + ): MutableMap { + return resolvePropertyAssignments( + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + nodeTemplateName, propertyDefinitions, propertyAssignments + ) + } + override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap { log.info("resolveNodeTemplateCapabilityProperties for node template($nodeTemplateName) capability($capabilityName)") @@ -432,7 +532,7 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl return propertyAssignmentValue } - override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String { + override suspend fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String { val artifactDefinition: ArtifactDefinition = resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName) val propertyAssignmentExpression = PropertyAssignmentService(this) @@ -464,36 +564,23 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl /** * Resolve the RelationshipTemplate Property Assignment Values. - * TODO("Now it supports only input, node not SELF(propert, attribute, artifact) expressions, later it will support SELF expressions") */ - return resolveNodeTemplatePropertyAssignments( - "DSL", + return resolveRelationshipTemplatePropertyAssignments( + relationshipTemplateName, propertiesDefinitions, propertyAssignments ) } - /** - * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json - * Type - */ - override fun resolveDSLExpression(dslPropertyName: String): JsonNode { - val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName) - return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments) && - propertyAssignments is ObjectNode - ) { - - val rootKeyMap = propertyAssignments.rootFieldsToMap() - val propertyAssignmentValue: MutableMap = hashMapOf() - rootKeyMap.forEach { (propertyName, propertyValue) -> - val propertyAssignmentExpression = PropertyAssignmentService(this) - propertyAssignmentValue[propertyName] = propertyAssignmentExpression - .resolveAssignmentExpression("DSL", propertyName, propertyValue) - } - propertyAssignmentValue.asJsonNode() - } else { - propertyAssignments - } + override fun resolveRelationshipTemplatePropertyAssignments( + relationshipTemplateName: String, + propertyDefinitions: MutableMap, + propertyAssignments: MutableMap + ): MutableMap { + return resolvePropertyAssignments( + BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE, + relationshipTemplateName, propertyDefinitions, propertyAssignments + ) } override fun setInputValue(propertyName: String, value: JsonNode) { @@ -628,6 +715,28 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl return getJsonNode(path) } + override fun getRelationshipTemplatePropertyValue( + relationshipTemplateName: String, + propertyName: String + ): JsonNode? { + val path: String = StringBuilder(BluePrintConstants.PATH_RELATIONSHIP_TEMPLATES) + .append(BluePrintConstants.PATH_DIVIDER).append(relationshipTemplateName) + .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES) + .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString() + return getJsonNode(path) + } + + override fun getRelationshipTemplateAttributeValue( + relationshipTemplateName: String, + attributeName: String + ): JsonNode? { + val path: String = StringBuilder(BluePrintConstants.PATH_RELATIONSHIP_TEMPLATES) + .append(BluePrintConstants.PATH_DIVIDER).append(relationshipTemplateName) + .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES) + .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString() + return getJsonNode(path) + } + override fun assignInputs(jsonNode: JsonNode) { log.info("assignInputs from input JSON ({})", jsonNode.toString()) bluePrintContext.inputs()?.forEach { propertyName, property -> @@ -644,32 +753,26 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl val dynamicInputPropertiesName = "$workflowName-properties" bluePrintContext.workflowByName(workflowName).inputs - ?.filter { (propertyName, property) -> propertyName != dynamicInputPropertiesName } - ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, jsonNode) } + ?.filter { (propertyName, property) -> propertyName != dynamicInputPropertiesName } + ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, jsonNode) } // Load Dynamic data Types jsonNode.get(dynamicInputPropertiesName)?.let { bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName") - ?.properties - ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, it) } + ?.properties + ?.forEach { propertyName, property -> findAndSetInputValue(propertyName, property, it) } } } private fun findAndSetInputValue(propertyName: String, property: PropertyDefinition, jsonNode: JsonNode) { val valueNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName) - .returnNullIfMissing() - ?: property.defaultValue - ?: NullNode.getInstance() + .returnNullIfMissing() + ?: property.defaultValue + ?: NullNode.getInstance() val loggableValue = if (hasLogProtect(property)) LOG_REDACTED else valueNode.toString() - log.info("Setting input data - attribute:($propertyName) value:($loggableValue)") + log.trace("Setting input data - attribute:($propertyName) value:($loggableValue)") setInputValue(propertyName, valueNode) } - override fun resolveWorkflowOutputs(workflowName: String): MutableMap { - log.info("resolveWorkflowOutputs for workflow($workflowName)") - val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf() - return resolvePropertyDefinitions("WORKFLOW", outputs) - } - override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List): JsonNode { val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode() @@ -688,4 +791,8 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl } return jsonNode } + + override suspend fun close() { + store.clear() + } } diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/PropertyAssignmentService.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/PropertyAssignmentService.kt index 2dc8b5cf7..4ae01c0b3 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/PropertyAssignmentService.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/PropertyAssignmentService.kt @@ -24,11 +24,9 @@ import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactExpression -import org.onap.ccsdk.cds.controllerblueprints.core.data.AttributeDefinition import org.onap.ccsdk.cds.controllerblueprints.core.data.AttributeExpression import org.onap.ccsdk.cds.controllerblueprints.core.data.ExpressionData import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationOutputExpression -import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyExpression import org.onap.ccsdk.cds.controllerblueprints.core.format import org.onap.ccsdk.cds.controllerblueprints.core.isComplexType @@ -42,7 +40,7 @@ import org.slf4j.LoggerFactory * * @author Brinda Santh */ -class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeService>) { +internal class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeService>) { private val log = LoggerFactory.getLogger(this::class.toString()) @@ -56,23 +54,27 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer */ fun resolveAssignmentExpression( - nodeTemplateName: String, + definitionType: String, + definitionName: String, assignmentName: String, assignment: JsonNode ): JsonNode { - val valueNode: JsonNode log.trace("Assignment ({})", assignment) val expressionData = BluePrintExpressionService.getExpressionData(assignment) - if (expressionData.isExpression) { - valueNode = resolveExpression(nodeTemplateName, assignmentName, expressionData) + return if (expressionData.isExpression) { + resolveExpression(definitionType, definitionName, assignmentName, expressionData) } else { - valueNode = expressionData.valueNode + expressionData.valueNode } - return valueNode } - fun resolveExpression(nodeTemplateName: String, propName: String, expressionData: ExpressionData): JsonNode { + fun resolveExpression( + definitionType: String, + definitionName: String, + propName: String, + expressionData: ExpressionData + ): JsonNode { var valueNode: JsonNode = NullNode.getInstance() @@ -84,24 +86,31 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer valueNode = bluePrintRuntimeService.getInputValue(expressionData.inputExpression?.propertyName!!) } BluePrintConstants.EXPRESSION_GET_ATTRIBUTE -> { - valueNode = resolveAttributeExpression(nodeTemplateName, expressionData.attributeExpression!!) + valueNode = + resolveAttributeExpression(definitionType, definitionName, expressionData.attributeExpression!!) } BluePrintConstants.EXPRESSION_GET_PROPERTY -> { - valueNode = resolvePropertyExpression(nodeTemplateName, expressionData.propertyExpression!!) + valueNode = + resolvePropertyExpression(definitionType, definitionName, expressionData.propertyExpression!!) } BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT -> { - valueNode = resolveOperationOutputExpression(nodeTemplateName, expressionData.operationOutputExpression!!) + valueNode = + resolveOperationOutputExpression(definitionName, expressionData.operationOutputExpression!!) } BluePrintConstants.EXPRESSION_GET_ARTIFACT -> { - valueNode = resolveArtifactExpression(nodeTemplateName, expressionData.artifactExpression!!) + valueNode = resolveArtifactExpression(definitionName, expressionData.artifactExpression!!) } BluePrintConstants.EXPRESSION_DSL_REFERENCE -> { - valueNode = bluePrintRuntimeService.resolveDSLExpression(expressionData.dslExpression!!.propertyName) + valueNode = + bluePrintRuntimeService.resolveDSLExpression(expressionData.dslExpression!!.propertyName) } BluePrintConstants.EXPRESSION_GET_NODE_OF_TYPE -> { } else -> { - throw BluePrintException(format("for property ({}), command ({}) is not supported ", propName, command)) + throw BluePrintException( + "for $definitionType($definitionName) property ($propName), " + + "command ($command) is not supported " + ) } } } @@ -112,13 +121,17 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer get_attribute: [ , , , , ..., ] */ - fun resolveAttributeExpression(nodeTemplateName: String, attributeExpression: AttributeExpression): JsonNode { + fun resolveAttributeExpression( + definitionType: String, + definitionName: String, + attributeExpression: AttributeExpression + ): JsonNode { var valueNode: JsonNode val attributeName = attributeExpression.attributeName val subAttributeName: String? = attributeExpression.subAttributeName - var attributeNodeTemplateName = nodeTemplateName + var attributeDefinitionName = definitionName /** * Attributes are dynamic runtime properties information. There are multiple types of Attributes, * ENV : Environment Variables @@ -128,27 +141,52 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer */ when (attributeExpression.modelableEntityName) { BluePrintConstants.PROPERTY_ENV -> { - val environmentValue = System.getProperty(attributeName) + val environmentValue = System.getenv(attributeName) valueNode = environmentValue.asJsonPrimitive() } BluePrintConstants.PROPERTY_APP -> { - TODO("Get property from application properties") + val environmentValue = System.getProperty(attributeName) + valueNode = environmentValue.asJsonPrimitive() } BluePrintConstants.PROPERTY_BPP -> { - valueNode = bluePrintRuntimeService.getNodeTemplateAttributeValue(BluePrintConstants.PROPERTY_BPP, attributeName) - ?: throw BluePrintException("failed to get env attribute name ($attributeName) ") + valueNode = bluePrintRuntimeService.getNodeTemplateAttributeValue( + BluePrintConstants.PROPERTY_BPP, + attributeName + ) ?: throw BluePrintException("failed to get env attribute name ($attributeName) ") } else -> { if (!attributeExpression.modelableEntityName.equals(BluePrintConstants.PROPERTY_SELF, true)) { - attributeNodeTemplateName = attributeExpression.modelableEntityName + attributeDefinitionName = attributeExpression.modelableEntityName } - var attributeDefinition: AttributeDefinition = bluePrintContext - .nodeTemplateNodeType(attributeNodeTemplateName).attributes?.get(attributeName) - ?: throw BluePrintException("failed to get attribute definitions for node template ($attributeNodeTemplateName)'s attribute name ($attributeName) ") - - valueNode = bluePrintRuntimeService.getNodeTemplateAttributeValue(attributeNodeTemplateName, attributeName) - ?: throw BluePrintException("failed to get node template ($attributeNodeTemplateName)'s attribute name ($attributeName) ") + /** This block is to Validate, if Attribute definition is present */ + when (definitionType) { + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + BluePrintConstants.MODEL_DEFINITION_TYPE_WORKFLOW, + BluePrintConstants.MODEL_DEFINITION_TYPE_DSL -> + bluePrintContext.nodeTemplateNodeType(attributeDefinitionName).attributes + BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TEMPLATE -> + bluePrintContext.relationshipTemplateRelationshipType(attributeDefinitionName).attributes + else -> throw BluePrintException("failed to understand template type($definitionType), it is not supported") + }?.get(attributeName) + ?: throw BluePrintException( + "failed to get attribute definitions for " + + "$definitionType ($attributeDefinitionName)'s attribute name ($attributeName) " + ) + + valueNode = when (definitionType) { + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + BluePrintConstants.MODEL_DEFINITION_TYPE_WORKFLOW, + BluePrintConstants.MODEL_DEFINITION_TYPE_DSL -> + bluePrintRuntimeService.getNodeTemplateAttributeValue(attributeDefinitionName, attributeName) + BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TEMPLATE -> + bluePrintRuntimeService.getRelationshipTemplateAttributeValue( + attributeDefinitionName, + attributeName + ) + else -> throw BluePrintException("failed to understand template type($definitionType), it is not supported") + } + ?: throw BluePrintException("failed to get node template ($attributeDefinitionName)'s attribute name ($attributeName) ") } } if (subAttributeName != null) { @@ -162,38 +200,56 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer get_property: [ , , , , ..., ] */ - fun resolvePropertyExpression(nodeTemplateName: String, propertyExpression: PropertyExpression): JsonNode { + fun resolvePropertyExpression( + definitionType: String, + definitionName: String, + propertyExpression: PropertyExpression + ): JsonNode { var valueNode: JsonNode val propertyName = propertyExpression.propertyName val subPropertyName: String? = propertyExpression.subPropertyName - var propertyNodeTemplateName = nodeTemplateName + var propertyDefinitionName = definitionName if (!propertyExpression.modelableEntityName.equals(BluePrintConstants.PROPERTY_SELF, true)) { - propertyNodeTemplateName = propertyExpression.modelableEntityName + propertyDefinitionName = propertyExpression.modelableEntityName } - val nodeTemplatePropertyExpression = bluePrintContext.nodeTemplateByName(propertyNodeTemplateName).properties?.get(propertyName) - ?: throw BluePrintException( - format( - "failed to get property definitions for node template ({})'s property name ({}) ", - nodeTemplateName, - propertyName - ) - ) - - var propertyDefinition: PropertyDefinition = bluePrintContext.nodeTemplateNodeType(propertyNodeTemplateName).properties?.get(propertyName)!! + val nodeTemplatePropertyExpression = when (definitionType) { + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + BluePrintConstants.MODEL_DEFINITION_TYPE_WORKFLOW, + BluePrintConstants.MODEL_DEFINITION_TYPE_DSL -> + bluePrintContext.nodeTemplateByName(propertyDefinitionName).properties + BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TEMPLATE -> + bluePrintContext.relationshipTemplateByName(propertyDefinitionName).properties + else -> throw BluePrintException("failed to understand template type($definitionType), it is not supported") + }?.get(propertyName) + ?: throw BluePrintException("failed to get property assignment for node template ($definitionName)'s property name ($propertyName).") + + /** This block is to Validate, if Property definition is present */ + when (definitionType) { + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + BluePrintConstants.MODEL_DEFINITION_TYPE_WORKFLOW, + BluePrintConstants.MODEL_DEFINITION_TYPE_DSL -> + bluePrintContext.nodeTemplateNodeType(propertyDefinitionName).properties + BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TEMPLATE -> + bluePrintContext.relationshipTemplateRelationshipType(propertyDefinitionName).properties + else -> throw BluePrintException("failed to understand template type($definitionType), it is not supported") + }?.get(propertyName) + ?: throw BluePrintException("failed to get property definition for node template ($definitionName)'s property name ($propertyName).") log.info( - "node template name ({}), property Name ({}) resolved value ({})", - propertyNodeTemplateName, - propertyName, - nodeTemplatePropertyExpression + "$definitionType($propertyDefinitionName), property($propertyName) resolved value ($nodeTemplatePropertyExpression)" ) // Check it it is a nested expression - valueNode = resolveAssignmentExpression(propertyNodeTemplateName, propertyName, nodeTemplatePropertyExpression) + valueNode = resolveAssignmentExpression( + definitionType, + propertyDefinitionName, + propertyName, + nodeTemplatePropertyExpression + ) if (subPropertyName != null) { if (valueNode.isComplexType()) @@ -205,7 +261,10 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer /* get_operation_output: , , , */ - fun resolveOperationOutputExpression(nodeTemplateName: String, operationOutputExpression: OperationOutputExpression): JsonNode { + fun resolveOperationOutputExpression( + nodeTemplateName: String, + operationOutputExpression: OperationOutputExpression + ): JsonNode { var outputNodeTemplateName = nodeTemplateName if (!operationOutputExpression.modelableEntityName.equals("SELF", true)) { outputNodeTemplateName = operationOutputExpression.modelableEntityName @@ -239,7 +298,7 @@ class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeSer ?: throw BluePrintException( format( "failed to get artifact definitions for node template ({})'s " + - "artifact name ({}) ", nodeTemplateName, artifactExpression.artifactName + "artifact name ({}) ", nodeTemplateName, artifactExpression.artifactName ) ) diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/ServiceTemplateUtils.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/ServiceTemplateUtils.kt index a74722f31..9903b57f1 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/ServiceTemplateUtils.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/ServiceTemplateUtils.kt @@ -36,7 +36,11 @@ object ServiceTemplateUtils { return JacksonUtils.readValue(content) } - fun merge(parentServiceTemplate: ServiceTemplate, toMerge: ServiceTemplate, removeImports: Boolean? = true): ServiceTemplate { + fun merge( + parentServiceTemplate: ServiceTemplate, + toMerge: ServiceTemplate, + removeImports: Boolean? = true + ): ServiceTemplate { if (removeImports!!) { parentServiceTemplate.imports = null toMerge.imports = null @@ -62,6 +66,11 @@ object ServiceTemplateUtils { parentServiceTemplate.nodeTypes?.putAll(toMerge.nodeTypes as MutableMap) } + toMerge.relationshipTypes?.let { + parentServiceTemplate.relationshipTypes = parentServiceTemplate.relationshipTypes ?: hashMapOf() + parentServiceTemplate.relationshipTypes?.putAll(toMerge.relationshipTypes as MutableMap) + } + toMerge.artifactTypes?.let { parentServiceTemplate.artifactTypes = parentServiceTemplate.artifactTypes ?: hashMapOf() parentServiceTemplate.artifactTypes?.putAll(toMerge.artifactTypes as MutableMap) @@ -81,14 +90,16 @@ object ServiceTemplateUtils { } toMerge.topologyTemplate?.nodeTemplates?.let { - parentServiceTemplate.topologyTemplate?.nodeTemplates = parentServiceTemplate.topologyTemplate?.nodeTemplates - ?: hashMapOf() + parentServiceTemplate.topologyTemplate?.nodeTemplates = + parentServiceTemplate.topologyTemplate?.nodeTemplates + ?: hashMapOf() parentServiceTemplate.topologyTemplate?.nodeTemplates?.putAll(parentServiceTemplate.topologyTemplate?.nodeTemplates as MutableMap) } toMerge.topologyTemplate?.relationshipTemplates?.let { - parentServiceTemplate.topologyTemplate?.relationshipTemplates = parentServiceTemplate.topologyTemplate?.relationshipTemplates - ?: hashMapOf() + parentServiceTemplate.topologyTemplate?.relationshipTemplates = + parentServiceTemplate.topologyTemplate?.relationshipTemplates + ?: hashMapOf() parentServiceTemplate.topologyTemplate?.relationshipTemplates?.putAll(parentServiceTemplate.topologyTemplate?.relationshipTemplates as MutableMap) } diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt index b079d42aa..871f8af08 100644 --- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt +++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/test/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt @@ -57,6 +57,28 @@ class BluePrintRuntimeServiceTest { assertNotNull(propContext, "Failed to populate interface property values") } + @Test + fun `test Resolve Relationship Properties`() { + log.info("************************ testResolveRelationshipTemplateProperties **********************") + + val bluePrintRuntimeService = getBluePrintRuntimeService() + + val inputDataPath = "src/test/resources/data/default-context.json" + + val inputNode: JsonNode = JacksonUtils.jsonNodeFromFile(inputDataPath) + bluePrintRuntimeService.assignInputs(inputNode) + + val propContext: MutableMap = bluePrintRuntimeService + .resolveRelationshipTemplateProperties("cli-device-properties") + + assertNotNull(propContext, "Failed to populate relationship property values") + assertEquals( + "localhost".asJsonPrimitive(), + propContext["connection-config"]!!.get("host"), + "failed to resolve expression" + ) + } + @Test fun `test resolve NodeTemplate Capability Properties`() { log.info("************************ testResolveNodeTemplateRequirementProperties **********************") diff --git a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt index a746abac5..4ed98ddd0 100644 --- a/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt +++ b/ms/blueprintsprocessor/modules/blueprints/resource-dict/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/resource/dict/ResourceDefinition.kt @@ -34,8 +34,9 @@ open class ResourceDefinition { var tags: String? = null - @JsonProperty(value = "group") - lateinit var group: String + /** The default group for Resource Definition is "default" */ + @JsonProperty(value = "group", required = true) + var group: String = "default" @JsonProperty(value = "updated-by") lateinit var updatedBy: String -- cgit 1.2.3-korg