diff options
author | Brinda Santh <bs2796@att.com> | 2019-12-27 15:43:53 -0500 |
---|---|---|
committer | KAPIL SINGAL <ks220y@att.com> | 2019-12-30 18:18:57 +0000 |
commit | 1fdaf4953daf15970afe6ee10491dfa2d0a76753 (patch) | |
tree | a820366a5de5ac7f44492a11f88de7f4f24350f7 | |
parent | 41712e142c8d2b2bff9bc9e094f45306a60d7cb9 (diff) |
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 <bs2796@att.com>
Change-Id: I73e1deed708dc924352867ddd1d1b2271c8ea106
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) |