diff options
30 files changed, 1013 insertions, 177 deletions
diff --git a/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/activation-blueprint.json b/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/activation-blueprint.json index 70c1bc3c6..639c21490 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/activation-blueprint.json +++ b/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/activation-blueprint.json @@ -352,6 +352,23 @@ } } }, + "relationship_templates": { + "cli-device-properties": { + "type": "tosca.relationships.ConnectsTo.SshClient", + "description": "SSH Connection", + "properties": { + "connection-config": { + "password": "sample-password", + "host": { + "get_input": "hostname" + }, + "type": "basic-auth", + "connectionTimeOut": 30, + "username": "sample-user" + } + } + } + }, "workflows": { "resource-assignment": { "inputs": { diff --git a/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/relationship_types.json b/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/relationship_types.json index 87d2dc586..b56c77a80 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/relationship_types.json +++ b/components/model-catalog/blueprint-model/test-blueprint/baseconfiguration/Definitions/relationship_types.json @@ -4,6 +4,21 @@ "description": "Relationship tosca.relationships.ConnectsTo", "version": "1.0.0", "derived_from": "tosca.relationships.Root" + }, + "tosca.relationships.ConnectsTo.SshClient": { + "description": "Relationship connects to through SSH Client.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] } } }
\ No newline at end of file diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json index e73f96ded..04d0752fd 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json +++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Definitions/capability-cli-blueprint.json @@ -26,25 +26,6 @@ "file": "Definitions/policy_types.json" } ], - "dsl_definitions": { - "config-deploy-properties": { - "resolution-key": { - "get_input": "resolution-key" - } - }, - "device-properties": { - "type": "basic-auth", - "host": { - "get_input": "hostname" - }, - "username": { - "get_input": "username" - }, - "password": { - "get_input": "password" - } - } - }, "topology_template": { "workflows": { "check": { diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt index 7bda62810..e29055634 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt +++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCli.kt @@ -24,7 +24,6 @@ import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString import org.onap.ccsdk.cds.controllerblueprints.core.logger import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService - open class Check : AbstractScriptComponentFunction() { private val log = logger(Check::class) @@ -45,8 +44,8 @@ open class Check : AbstractScriptComponentFunction() { log.info("Check Commands :$checkCommands") - // Get the Device Information from the DSL Model - val deviceInformation = bluePrintRuntimeService.resolveDSLExpression("device-properties") + // Get the Device Information from the Relationship Model + val deviceInformation = relationshipProperty("ssh-connection-config", "connection-config") log.info("Device Info :$deviceInformation") @@ -54,10 +53,9 @@ open class Check : AbstractScriptComponentFunction() { val sshClientService = BluePrintDependencyService.sshClientService(deviceInformation) log.info("Client service is ready") - } override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) { log.info("Executing Recovery") } -}
\ No newline at end of file +} diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCliDefinitions.kt b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCliDefinitions.kt index 3700a0bad..a4a2ccf61 100644 --- a/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCliDefinitions.kt +++ b/components/model-catalog/blueprint-model/test-blueprint/capability_cli/Scripts/kotlin/cba/capability/cli/CapabilityCliDefinitions.kt @@ -18,8 +18,11 @@ package cba.capability.cli import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTemplateComponentScriptExecutor import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTypeComponentScriptExecutor -import org.onap.ccsdk.cds.blueprintsprocessor.ssh.basicAuthSshProperties +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.relationshipTemplateSshClient +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.relationshipTypeConnectsToSshClient +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonString import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate import org.onap.ccsdk.cds.controllerblueprints.core.dsl.artifactTypeTemplateVelocity import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getAttribute @@ -43,13 +46,6 @@ fun CapabilityCliDefinitions.defaultServiceTemplate() = author = "Brinda Santh Muthuramalingam", tags = "brinda, tosca" ) { - - dsl("device-properties", BluePrintTypes.basicAuthSshProperties { - host(getInput("hostname")) - password(getInput("password")) - username(getInput("username")) - }) - topologyTemplate { workflow(id = "check", description = "CLI Check Workflow") { inputs { @@ -69,8 +65,8 @@ fun CapabilityCliDefinitions.defaultServiceTemplate() = val checkComponent = BluePrintTypes.nodeTemplateComponentScriptExecutor(id = "check", description = "") { definedOperation(description = "") { inputs { - type("kotlin") - scriptClassReference("cba.capability.cli.Check") + type(BluePrintConstants.SCRIPT_KOTLIN) + scriptClassReference(Check::class) } outputs { status(getAttribute("status")) @@ -83,6 +79,15 @@ fun CapabilityCliDefinitions.defaultServiceTemplate() = ) } nodeTemplate(checkComponent) + + /** Connection Configuration through Relationship **/ + relationshipTemplateSshClient("ssh-connection-config", "Device connection config") { + basicAuth { + host(getInput("hostname")) + password(getInput("password")) + username(getInput("username")) + } + } } /** Artifact Types */ @@ -91,6 +96,6 @@ fun CapabilityCliDefinitions.defaultServiceTemplate() = nodeType(BluePrintTypes.nodeTypeComponent()) nodeType(BluePrintTypes.nodeTypeComponentScriptExecutor()) /** Relationship Types */ + relationshipType(BluePrintTypes.relationshipTypeConnectsToSshClient()) relationshipType(BluePrintTypes.relationshipTypeConnectsTo()) - } diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Db.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Db.json new file mode 100644 index 000000000..01e87d58a --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Db.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through Database.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcClient.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcClient.json new file mode 100644 index 000000000..eea7a0d29 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcClient.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through GRPC Client.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcServer.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcServer.json new file mode 100644 index 000000000..d98114350 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.GrpcServer.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through GRPC Server.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageConsumer.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageConsumer.json new file mode 100644 index 000000000..7de2fc286 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageConsumer.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship type connects to message consumer.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageProducer.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageProducer.json new file mode 100644 index 000000000..d3c3580bc --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.MessageProducer.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through message producer.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Nats.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Nats.json new file mode 100644 index 000000000..be03484e0 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.Nats.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through NATS Client.", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.RestClient.json b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.RestClient.json new file mode 100644 index 000000000..9182dbfe5 --- /dev/null +++ b/components/model-catalog/definition-type/starter-type/relationship_type/tosca.relationships.ConnectsTo.RestClient.json @@ -0,0 +1,15 @@ +{ + "description": "Relationship connects to through", + "version": "1.0.0", + "properties": { + "connection-config": { + "description": "Connection Config details.", + "required": true, + "type": "map" + } + }, + "derived_from": "tosca.relationships.ConnectsTo", + "valid_target_types": [ + "tosca.capabilities.Endpoint" + ] +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt index 58e6151f0..bb3538168 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/NetconfComponentFunction.kt @@ -55,8 +55,8 @@ abstract class NetconfComponentFunction : AbstractScriptComponentFunction() { "org.onap.ccsdk.cds.blueprintsprocessor.services.execution.artifactContent" ) ) - fun generateMessage(artifactName: String): String { - return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) + fun generateMessage(artifactName: String): String = runBlocking { + bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } @Deprecated( diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentJythonExecutor.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentJythonExecutor.kt index 99e6c6c62..03daf2aa9 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentJythonExecutor.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/ComponentJythonExecutor.kt @@ -60,7 +60,7 @@ open class ComponentJythonExecutor( .addError("Failed in ComponentJythonExecutor : ${runtimeException.message}") } - private fun populateJythonComponentInstance() { + private suspend fun populateJythonComponentInstance() { val bluePrintContext = bluePrintRuntimeService.bluePrintContext() val operationAssignment: OperationAssignment = bluePrintContext diff --git a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintJythonServiceImpl.kt b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintJythonServiceImpl.kt index 7f4afe699..9000d65d8 100644 --- a/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintJythonServiceImpl.kt +++ b/ms/blueprintsprocessor/functions/python-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/python/executor/scripts/BlueprintJythonServiceImpl.kt @@ -85,7 +85,7 @@ class BlueprintJythonServiceImpl( ) } - fun jythonComponentInstance(abstractComponentFunction: AbstractComponentFunction): AbstractComponentFunction { + suspend fun jythonComponentInstance(abstractComponentFunction: AbstractComponentFunction): AbstractComponentFunction { val bluePrintRuntimeService = abstractComponentFunction.bluePrintRuntimeService val bluePrintContext = bluePrintRuntimeService.bluePrintContext() 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<String, RelationshipTemplate>? { + 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<T> { fun loadEnvironments(type: String, fileName: String) - fun resolveNodeTemplatePropertyAssignments( - nodeTemplateName: String, + fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode> + + 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<String, PropertyDefinition> + ): MutableMap<String, JsonNode> + + /** 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<String, PropertyDefinition>, propertyAssignments: MutableMap<String, JsonNode> ): MutableMap<String, JsonNode> - fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap<String, PropertyDefinition>): - MutableMap<String, JsonNode> - - fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap<String, JsonNode>): - MutableMap<String, JsonNode> + /** 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<String, JsonNode> + ): MutableMap<String, JsonNode> + /** Resolve Node Template [nodeTemplateName] Property Assignments */ fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode> + /** Resolve Node Template [nodeTemplateName] Property Assignments with [propertyDefinitions] and [propertyAssignments]*/ + fun resolveNodeTemplatePropertyAssignments( + nodeTemplateName: String, + propertyDefinitions: MutableMap<String, PropertyDefinition>, + propertyAssignments: MutableMap<String, JsonNode> + ): MutableMap<String, JsonNode> + fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap<String, JsonNode> @@ -98,13 +128,20 @@ interface BluePrintRuntimeService<T> { operationName: String ): MutableMap<String, JsonNode> - 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<String, JsonNode> - fun resolveDSLExpression(dslPropertyName: String): JsonNode + /** Resolve Relationship Template [relationshipTemplateName] Property Assignments with + * [propertyDefinitions] and [propertyAssignments] */ + fun resolveRelationshipTemplatePropertyAssignments( + relationshipTemplateName: String, + propertyDefinitions: MutableMap<String, PropertyDefinition>, + propertyAssignments: MutableMap<String, JsonNode> + ): MutableMap<String, JsonNode> fun setInputValue(propertyName: String, value: JsonNode) @@ -156,13 +193,17 @@ interface BluePrintRuntimeService<T> { 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<String, JsonNode> - fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode + + suspend fun close() } /** @@ -256,15 +297,68 @@ open class DefaultBluePrintRuntimeService(private var id: String, private var bl } } + override fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode> { + 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<String, JsonNode> = 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<String, PropertyDefinition> + ): MutableMap<String, JsonNode> { + val propertyAssignmentValue: MutableMap<String, JsonNode> = 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<String, PropertyDefinition>, propertyAssignments: MutableMap<String, JsonNode> - ): - MutableMap<String, JsonNode> { + ): MutableMap<String, JsonNode> { val propertyAssignmentValue: MutableMap<String, JsonNode> = 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<String, PropertyDefinition>): - MutableMap<String, JsonNode> { - val propertyAssignmentValue: MutableMap<String, JsonNode> = 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<String, JsonNode>): - MutableMap<String, JsonNode> { + override fun resolvePropertyAssignments( + definitionType: String, + definitionName: String, + propertyAssignments: MutableMap<String, JsonNode> + ): MutableMap<String, JsonNode> { val propertyAssignmentValue: MutableMap<String, JsonNode> = 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<String, PropertyDefinition>, + propertyAssignments: MutableMap<String, JsonNode> + ): MutableMap<String, JsonNode> { + return resolvePropertyAssignments( + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TEMPLATE, + nodeTemplateName, propertyDefinitions, propertyAssignments + ) + } + override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap<String, JsonNode> { 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<String, JsonNode> = 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<String, PropertyDefinition>, + propertyAssignments: MutableMap<String, JsonNode> + ): MutableMap<String, JsonNode> { + 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<String, JsonNode> { - log.info("resolveWorkflowOutputs for workflow($workflowName)") - val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf() - return resolvePropertyDefinitions("WORKFLOW", outputs) - } - override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): 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<MutableMap<String, JsonNode>>) { +internal class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeService<MutableMap<String, JsonNode>>) { 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: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>, <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ] */ - 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: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>, <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ] */ - 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: <modelable_entity_name>, <interface_name>, <operation_name>, <output_variable_name> */ - 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 @@ -58,6 +58,28 @@ class BluePrintRuntimeServiceTest { } @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<String, JsonNode> = 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 **********************") val bluePrintRuntimeService = getBluePrintRuntimeService() 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 diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibData.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibData.kt index d4d804857..f78334fcd 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibData.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/BluePrintDBLibData.kt @@ -17,6 +17,7 @@ package org.onap.ccsdk.cds.blueprintsprocessor.db open class DBDataSourceProperties { + var type: String = DBLibConstants.MARIA_DB lateinit var url: String lateinit var username: String lateinit var password: String @@ -34,7 +35,6 @@ open class MariaDataSourceProperties : DBDataSourceProperties() { lateinit var hibernateHbm2ddlAuto: String lateinit var hibernateDDLAuto: String lateinit var hibernateNamingStrategy: String - lateinit var type: String lateinit var hibernateDialect: String override var driverClassName = DBLibConstants.DRIVER_MARIA_DB } @@ -43,7 +43,6 @@ open class MySqlDataSourceProperties : DBDataSourceProperties() { lateinit var hibernateHbm2ddlAuto: String lateinit var hibernateDDLAuto: String lateinit var hibernateNamingStrategy: String - lateinit var type: String lateinit var hibernateDialect: String override var driverClassName = DBLibConstants.DRIVER_MYSQL_DB } diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSL.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSL.kt index 036beb369..2bf56f482 100644 --- a/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSL.kt +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSL.kt @@ -15,3 +15,109 @@ */ package org.onap.ccsdk.cds.blueprintsprocessor.db + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.data.RelationshipType +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.RelationshipTemplateBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.TopologyTemplateBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.relationshipType + +/** Relationships Types DSL for Database Producer */ +fun BluePrintTypes.relationshipTypeConnectsToDb(): RelationshipType { + return relationshipType( + id = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_DB, + version = BluePrintConstants.DEFAULT_VERSION_NUMBER, + derivedFrom = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO, + description = "Relationship connects to through Database." + ) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintConstants.DATA_TYPE_MAP, + true, + "Connection Config details." + ) + validTargetTypes(arrayListOf(BluePrintConstants.MODEL_TYPE_CAPABILITY_TYPE_ENDPOINT)) + } +} + +/** Relationships Templates for Database Server */ +fun TopologyTemplateBuilder.relationshipTemplateDb( + name: String, + description: String, + block: DbRelationshipTemplateBuilder.() -> Unit +) { + if (relationshipTemplates == null) relationshipTemplates = hashMapOf() + val relationshipTemplate = DbRelationshipTemplateBuilder(name, description).apply(block).build() + relationshipTemplates!![relationshipTemplate.id!!] = relationshipTemplate +} + +class DbRelationshipTemplateBuilder(name: String, description: String) : + RelationshipTemplateBuilder( + name, + BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_DB, description + ) { + + fun mariaDb(block: DbMariaDataSourcePropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.mariaDbProperties(block)) + } + + fun mySqlDb(block: DbMySqlDataSourcePropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.mySqlDbProperties(block)) + } +} + +fun BluePrintTypes.mariaDbProperties(block: DbMariaDataSourcePropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = DbMariaDataSourcePropertiesAssignmentBuilder().apply(block).build() + assignments[DBDataSourceProperties::type.name] = DBLibConstants.MARIA_DB.asJsonPrimitive() + return assignments.asJsonNode() +} + +fun BluePrintTypes.mySqlDbProperties(block: DbMySqlDataSourcePropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = DbMySqlDataSourcePropertiesAssignmentBuilder().apply(block).build() + assignments[DBDataSourceProperties::type.name] = DBLibConstants.MYSQL_DB.asJsonPrimitive() + return assignments.asJsonNode() +} + +open class DbPropertiesAssignmentBuilder : PropertiesAssignmentBuilder() { + + fun url(url: String) = url(url.asJsonPrimitive()) + + fun url(url: JsonNode) = + property(DBDataSourceProperties::url, url) + + fun username(username: String) = username(username.asJsonPrimitive()) + + fun username(username: JsonNode) = property(DBDataSourceProperties::username, username) + + fun password(password: String) = password(password.asJsonPrimitive()) + + fun password(password: JsonNode) = property(DBDataSourceProperties::password, password) +} + +open class DbMariaDataSourcePropertiesAssignmentBuilder : DbPropertiesAssignmentBuilder() { + + fun hibernateHbm2ddlAuto(hibernateHbm2ddlAuto: String) = + hibernateHbm2ddlAuto(hibernateHbm2ddlAuto.asJsonPrimitive()) + + fun hibernateHbm2ddlAuto(hibernateHbm2ddlAuto: JsonNode) = + property(MariaDataSourceProperties::hibernateHbm2ddlAuto, hibernateHbm2ddlAuto) + + fun hibernateDDLAuto(hibernateDDLAuto: String) = + hibernateDDLAuto(hibernateDDLAuto.asJsonPrimitive()) + + fun hibernateDDLAuto(hibernateDDLAuto: JsonNode) = + property(MariaDataSourceProperties::hibernateDDLAuto, hibernateDDLAuto) + + fun hibernateNamingStrategy(hibernateNamingStrategy: String) = + hibernateNamingStrategy(hibernateNamingStrategy.asJsonPrimitive()) + + fun hibernateNamingStrategy(hibernateNamingStrategy: JsonNode) = + property(MariaDataSourceProperties::hibernateNamingStrategy, hibernateNamingStrategy) +} + +open class DbMySqlDataSourcePropertiesAssignmentBuilder : DbMariaDataSourcePropertiesAssignmentBuilder() diff --git a/ms/blueprintsprocessor/modules/commons/db-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSLTest.kt b/ms/blueprintsprocessor/modules/commons/db-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSLTest.kt new file mode 100644 index 000000000..b0c7d8b3c --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/db-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/db/DatabasePropertiesDSLTest.kt @@ -0,0 +1,70 @@ +/* + * Copyright © 2018-2019 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.db + +import org.junit.Test +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.relationshipTypeConnectsTo +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.serviceTemplate +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class DatabasePropertiesDSLTest { + + @Test + fun testDatabasePropertiesDSL() { + val serviceTemplate = serviceTemplate("database-properties-test", "1.0.0", "xxx.@xx.com", "database") { + topologyTemplate { + relationshipTemplateDb("sample-maria-db", "Database Server") { + mariaDb { + url("jdbc://mariadb:3600") + username("user") + password("credential") + hibernateDDLAuto("hibernateDDLAuto") + hibernateHbm2ddlAuto("hibernateHbm2ddlAuto") + hibernateDDLAuto("hibernateDDLAuto") + hibernateNamingStrategy("hibernateNamingStrategy") + } + } + relationshipTemplateDb("sample-mysql-db", "Database Server") { + mySqlDb { + url("jdbc://mysql:3600") + username("user") + password("credential") + hibernateDDLAuto("hibernateDDLAuto") + hibernateHbm2ddlAuto("hibernateHbm2ddlAuto") + hibernateDDLAuto("hibernateDDLAuto") + hibernateNamingStrategy("hibernateNamingStrategy") + } + } + } + relationshipTypes( + arrayListOf( + BluePrintTypes.relationshipTypeConnectsToDb(), + BluePrintTypes.relationshipTypeConnectsTo() + ) + ) + } + assertNotNull(serviceTemplate, "failed to create service template") + val relationshipTemplates = serviceTemplate.topologyTemplate?.relationshipTemplates + assertNotNull(relationshipTemplates, "failed to get relationship templates") + assertEquals(2, relationshipTemplates.size, "relationshipTemplates doesn't match") + assertNotNull(relationshipTemplates["sample-maria-db"], "failed to get sample-maria-db") + assertNotNull(relationshipTemplates["sample-mysql-db"], "failed to get sample-mysql-db") + // println(serviceTemplate.asJsonString(true)) + } +} diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSL.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSL.kt index 3a0e9c633..354e38dc7 100644 --- a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSL.kt +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSL.kt @@ -15,3 +15,215 @@ */ package org.onap.ccsdk.cds.blueprintsprocessor.grpc + +import com.fasterxml.jackson.databind.JsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode +import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive +import org.onap.ccsdk.cds.controllerblueprints.core.data.RelationshipType +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.PropertiesAssignmentBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.RelationshipTemplateBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.TopologyTemplateBuilder +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.relationshipType + +/** Relationships Types DSL for GRPC Server Producer */ +fun BluePrintTypes.relationshipTypeConnectsToGrpcServer(): RelationshipType { + return relationshipType( + id = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_GRPC_SERVER, + version = BluePrintConstants.DEFAULT_VERSION_NUMBER, + derivedFrom = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO, + description = "Relationship connects to through GRPC Server." + ) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintConstants.DATA_TYPE_MAP, + true, + "Connection Config details." + ) + validTargetTypes(arrayListOf(BluePrintConstants.MODEL_TYPE_CAPABILITY_TYPE_ENDPOINT)) + } +} + +fun BluePrintTypes.relationshipTypeConnectsToGrpcClient(): RelationshipType { + return relationshipType( + id = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_GRPC_CLIENT, + version = BluePrintConstants.DEFAULT_VERSION_NUMBER, + derivedFrom = BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO, + description = "Relationship connects to through GRPC Client." + ) { + property( + BluePrintConstants.PROPERTY_CONNECTION_CONFIG, + BluePrintConstants.DATA_TYPE_MAP, + true, + "Connection Config details." + ) + validTargetTypes(arrayListOf(BluePrintConstants.MODEL_TYPE_CAPABILITY_TYPE_ENDPOINT)) + } +} + +/** Relationships Templates for GRPC Server */ +fun TopologyTemplateBuilder.relationshipTemplateGrpcServer( + name: String, + description: String, + block: GrpcServerRelationshipTemplateBuilder.() -> Unit +) { + if (relationshipTemplates == null) relationshipTemplates = hashMapOf() + val relationshipTemplate = GrpcServerRelationshipTemplateBuilder(name, description).apply(block).build() + relationshipTemplates!![relationshipTemplate.id!!] = relationshipTemplate +} + +class GrpcServerRelationshipTemplateBuilder(name: String, description: String) : + RelationshipTemplateBuilder( + name, + BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_GRPC_SERVER, description + ) { + + fun tokenAuth(block: GrpcServerTokenAuthPropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.tokenAuthGrpcServerProperties(block)) + } + + fun tlsAuth(block: GrpcServerTLSAuthPropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.tlsAuthGrpcServerProperties(block)) + } +} + +fun BluePrintTypes.tokenAuthGrpcServerProperties(block: GrpcServerTokenAuthPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = GrpcServerTokenAuthPropertiesAssignmentBuilder().apply(block).build() + assignments[GrpcServerProperties::type.name] = GRPCLibConstants.TYPE_TOKEN_AUTH.asJsonPrimitive() + return assignments.asJsonNode() +} + +fun BluePrintTypes.tlsAuthGrpcServerProperties(block: GrpcServerTLSAuthPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = GrpcServerTLSAuthPropertiesAssignmentBuilder().apply(block).build() + assignments[GrpcServerProperties::type.name] = GRPCLibConstants.TYPE_TLS_AUTH.asJsonPrimitive() + return assignments.asJsonNode() +} + +open class GrpcServerPropertiesAssignmentBuilder : PropertiesAssignmentBuilder() { + + fun port(port: Int) = port(port.asJsonPrimitive()) + + fun port(port: JsonNode) = + property(GrpcServerProperties::port, port) +} + +open class GrpcServerTokenAuthPropertiesAssignmentBuilder : GrpcServerPropertiesAssignmentBuilder() { + + fun token(selector: String) = token(selector.asJsonPrimitive()) + + fun token(selector: JsonNode) = property(TokenAuthGrpcServerProperties::token, selector) +} + +open class GrpcServerTLSAuthPropertiesAssignmentBuilder : GrpcServerPropertiesAssignmentBuilder() { + + fun certChain(certChain: String) = certChain(certChain.asJsonPrimitive()) + + fun certChain(certChain: JsonNode) = property(TLSAuthGrpcServerProperties::certChain, certChain) + + fun privateKey(privateKey: String) = privateKey(privateKey.asJsonPrimitive()) + + fun privateKey(privateKey: JsonNode) = property(TLSAuthGrpcServerProperties::privateKey, privateKey) + + fun trustCertCollection(trustCertCollection: String) = trustCertCollection(trustCertCollection.asJsonPrimitive()) + + fun trustCertCollection(trustCertCollection: JsonNode) = + property(TLSAuthGrpcServerProperties::trustCertCollection, trustCertCollection) +} + +/** Relationships Templates for GRPC Client */ +fun TopologyTemplateBuilder.relationshipTemplateGrpcClient( + name: String, + description: String, + block: GrpcClientRelationshipTemplateBuilder.() -> Unit +) { + if (relationshipTemplates == null) relationshipTemplates = hashMapOf() + val relationshipTemplate = GrpcClientRelationshipTemplateBuilder(name, description).apply(block).build() + relationshipTemplates!![relationshipTemplate.id!!] = relationshipTemplate +} + +class GrpcClientRelationshipTemplateBuilder(name: String, description: String) : + RelationshipTemplateBuilder( + name, + BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO_GRPC_CLIENT, description + ) { + + fun basicAuth(block: GrpcClientBasicAuthPropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.basicAuthGrpcClientProperties(block)) + } + + fun tokenAuth(block: GrpcClientTokenAuthPropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.tokenAuthGrpcClientProperties(block)) + } + + fun tlsAuth(block: GrpcClientTLSAuthPropertiesAssignmentBuilder.() -> Unit) { + property(BluePrintConstants.PROPERTY_CONNECTION_CONFIG, BluePrintTypes.tlsAuthGrpcClientProperties(block)) + } +} + +fun BluePrintTypes.basicAuthGrpcClientProperties(block: GrpcClientBasicAuthPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = GrpcClientBasicAuthPropertiesAssignmentBuilder().apply(block).build() + assignments[GrpcClientProperties::type.name] = GRPCLibConstants.TYPE_BASIC_AUTH.asJsonPrimitive() + return assignments.asJsonNode() +} + +fun BluePrintTypes.tokenAuthGrpcClientProperties(block: GrpcClientTokenAuthPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = GrpcClientTokenAuthPropertiesAssignmentBuilder().apply(block).build() + assignments[GrpcClientProperties::type.name] = GRPCLibConstants.TYPE_TOKEN_AUTH.asJsonPrimitive() + return assignments.asJsonNode() +} + +fun BluePrintTypes.tlsAuthGrpcClientProperties(block: GrpcClientTLSAuthPropertiesAssignmentBuilder.() -> Unit): JsonNode { + val assignments = GrpcClientTLSAuthPropertiesAssignmentBuilder().apply(block).build() + assignments[GrpcClientProperties::type.name] = GRPCLibConstants.TYPE_TLS_AUTH.asJsonPrimitive() + return assignments.asJsonNode() +} + +open class GrpcClientPropertiesAssignmentBuilder : PropertiesAssignmentBuilder() { + + fun host(host: String) = host(host.asJsonPrimitive()) + + fun host(host: JsonNode) = + property(GrpcClientProperties::host, host) + + fun port(port: Int) = port(port.asJsonPrimitive()) + + fun port(port: JsonNode) = + property(GrpcClientProperties::port, port) +} + +open class GrpcClientBasicAuthPropertiesAssignmentBuilder : GrpcClientPropertiesAssignmentBuilder() { + + fun username(username: String) = username(username.asJsonPrimitive()) + + fun username(username: JsonNode) = property(BasicAuthGrpcClientProperties::username, username) + + fun password(password: String) = password(password.asJsonPrimitive()) + + fun password(password: JsonNode) = property(BasicAuthGrpcClientProperties::password, password) +} + +open class GrpcClientTokenAuthPropertiesAssignmentBuilder : GrpcClientPropertiesAssignmentBuilder() { + + fun token(selector: String) = token(selector.asJsonPrimitive()) + + fun token(selector: JsonNode) = property(TokenAuthGrpcClientProperties::token, selector) +} + +open class GrpcClientTLSAuthPropertiesAssignmentBuilder : GrpcClientPropertiesAssignmentBuilder() { + + fun trustCertCollection(trustCertCollection: String) = trustCertCollection(trustCertCollection.asJsonPrimitive()) + + fun trustCertCollection(trustCertCollection: JsonNode) = + property(TLSAuthGrpcClientProperties::trustCertCollection, trustCertCollection) + + fun clientCertChain(clientCertChain: String) = clientCertChain(clientCertChain.asJsonPrimitive()) + + fun clientCertChain(clientCertChain: JsonNode) = + property(TLSAuthGrpcClientProperties::clientCertChain, clientCertChain) + + fun clientPrivateKey(clientPrivateKey: String) = clientPrivateKey(clientPrivateKey.asJsonPrimitive()) + + fun clientPrivateKey(clientPrivateKey: JsonNode) = + property(TLSAuthGrpcClientProperties::clientPrivateKey, clientPrivateKey) +} diff --git a/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSLTest.kt b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSLTest.kt new file mode 100644 index 000000000..9b3cf80bc --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/grpc-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/grpc/GrpcPropertiesDSLTest.kt @@ -0,0 +1,108 @@ +/* + * Copyright © 2018-2019 AT&T Intellectual Property. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.grpc + +import org.junit.Test +import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.relationshipTypeConnectsTo +import org.onap.ccsdk.cds.controllerblueprints.core.dsl.serviceTemplate +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class GrpcPropertiesDSLTest { + + @Test + fun testGrpcServerPropertiesDSL() { + val serviceTemplate = serviceTemplate("grpc-properties-test", "1.0.0", "xxx.@xx.com", "grpc") { + topologyTemplate { + relationshipTemplateGrpcServer("sample-tls-auth", "Grpc Server") { + tlsAuth { + port(40002) + certChain("sample-cert-chains") + privateKey("sample-private-key") + trustCertCollection("sample-trust-cert-collection") + } + } + relationshipTemplateGrpcServer("sample-token-auth", "Grpc Server") { + tokenAuth { + port(40002) + token("sample-token") + } + } + } + relationshipTypes( + arrayListOf( + BluePrintTypes.relationshipTypeConnectsToGrpcServer(), + BluePrintTypes.relationshipTypeConnectsTo() + ) + ) + } + assertNotNull(serviceTemplate, "failed to create service template") + val relationshipTemplates = serviceTemplate.topologyTemplate?.relationshipTemplates + assertNotNull(relationshipTemplates, "failed to get relationship templates") + assertEquals(2, relationshipTemplates.size, "relationshipTemplates doesn't match") + assertNotNull(relationshipTemplates["sample-tls-auth"], "failed to get sample-tls-auth") + assertNotNull(relationshipTemplates["sample-token-auth"], "failed to get sample-token-auth") + // println(serviceTemplate.asJsonString(true)) + } + + @Test + fun testGrpcClientPropertiesDSL() { + val serviceTemplate = serviceTemplate("grpc-properties-test", "1.0.0", "xxx.@xx.com", "grpc") { + topologyTemplate { + relationshipTemplateGrpcClient("sample-tls-auth", "Grpc Server") { + tlsAuth { + host("localhost") + port(40002) + clientCertChain("sample-certchains") + clientPrivateKey("sample-private-key") + trustCertCollection("sample-trust-cert-collection") + } + } + relationshipTemplateGrpcClient("sample-basic-auth", "Grpc Server") { + basicAuth { + host("localhost") + port(40002) + username("sample-user") + password("credential") + } + } + relationshipTemplateGrpcClient("sample-token-auth", "Grpc Server") { + tokenAuth { + host("localhost") + port(40002) + token("sample-token") + } + } + } + relationshipTypes( + arrayListOf( + BluePrintTypes.relationshipTypeConnectsToGrpcClient(), + BluePrintTypes.relationshipTypeConnectsTo() + ) + ) + } + assertNotNull(serviceTemplate, "failed to create service template") + val relationshipTemplates = serviceTemplate.topologyTemplate?.relationshipTemplates + assertNotNull(relationshipTemplates, "failed to get relationship templates") + assertEquals(3, relationshipTemplates.size, "relationshipTemplates doesn't match") + assertNotNull(relationshipTemplates["sample-tls-auth"], "failed to get sample-tls-auth") + assertNotNull(relationshipTemplates["sample-basic-auth"], "failed to get sample-basic-auth") + assertNotNull(relationshipTemplates["sample-token-auth"], "failed to get sample-token-auth") + // println(serviceTemplate.asJsonString(true)) + } +} diff --git a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/load/ResourceDictionaryLoadService.kt b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/load/ResourceDictionaryLoadService.kt index 0350bc731..432ef0f38 100644 --- a/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/load/ResourceDictionaryLoadService.kt +++ b/ms/blueprintsprocessor/modules/inbounds/designer-api/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/designer/api/load/ResourceDictionaryLoadService.kt @@ -70,7 +70,7 @@ open class ResourceDictionaryLoadService(private val resourceDictionaryHandler: private suspend fun loadResourceDictionary(errorBuilder: StrBuilder, file: File) { try { - log.trace("Loading NodeType(${file.name}}") + log.trace("Loading Resource Dictionary(${file.name}}") val definitionContent = file.readNBText() val resourceDefinition = JacksonUtils.readValue(definitionContent, ResourceDefinition::class.java) if (resourceDefinition != null) { @@ -102,7 +102,7 @@ open class ResourceDictionaryLoadService(private val resourceDictionaryHandler: throw BluePrintException("couldn't get dictionary from content information") } } catch (e: Exception) { - errorBuilder.appendln("Couldn't load Resource dictionary (${file.name}: ${e.message}") + errorBuilder.appendln("Couldn't load Resource dictionary (${file.name}: ${e.message})") } } } diff --git a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt index e2a594b08..3e329d7f5 100644 --- a/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt +++ b/ms/blueprintsprocessor/modules/services/execution-service/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/services/execution/AbstractComponentFunction.kt @@ -184,10 +184,15 @@ abstract class AbstractComponentFunction : BlueprintFunctionNode<ExecutionServic return executionServiceInput.payload.jsonPathParse(".$requestExpression") } - fun artifactContent(artifactName: String): String { + suspend fun artifactContent(artifactName: String): String { return bluePrintRuntimeService.resolveNodeTemplateArtifact(nodeTemplateName, artifactName) } + suspend fun relationshipProperty(relationshipName: String, propertyName: String): JsonNode { + return bluePrintRuntimeService.resolveRelationshipTemplateProperties(relationshipName).get(propertyName) + ?: throw BluePrintProcessorException("failed to get relationship($relationshipName) property($propertyName)") + } + suspend fun mashTemplateNData(artifactName: String, json: String): String { val content = artifactContent(artifactName) return BluePrintVelocityTemplateService.generateContent(content, json) |