From 7a9879297e324ac0eb08ff5422dce31436bf10f6 Mon Sep 17 00:00:00 2001 From: "Muthuramalingam, Brinda Santh(bs2796)" Date: Wed, 5 Sep 2018 23:40:46 +0000 Subject: Controller Blueprints Microservice Add Property Assign validation and Data Type Entry schema validation. Change-Id: Ifa40f62f848d06381ab83d7f1c9e7c6526f5edf0 Issue-ID: CCSDK-484 Signed-off-by: Muthuramalingam, Brinda Santh(bs2796) --- .../Definitions/activation-blueprint.json | 33 +----- .../Definitions/simple-baseconfig.json | 4 +- .../node_type/component-resource-assignment.json | 2 +- .../model_type/node_type/dg-activate-netconf.json | 2 +- .../model_type/node_type/dg-config-generator.json | 2 +- .../node_type/dg-resource-assign-activate.json | 2 +- .../node_type/dg-resource-assignment.json | 2 +- .../node_type/tosca.nodes.Component.json | 5 + .../load/model_type/node_type/tosca.nodes.DG.json | 5 + .../load/model_type/node_type/tosca.nodes.Vnf.json | 5 + .../node_type/tosca.nodes.component.Python.json | 5 + .../core/BluePrintConstants.kt | 2 + .../controllerblueprints/core/BluePrintTypes.kt | 27 +++++ .../core/service/BluePrintValidatorService.kt | 129 ++++++++++++++------- 14 files changed, 144 insertions(+), 81 deletions(-) create mode 100644 components/core/load/model_type/node_type/tosca.nodes.Component.json create mode 100644 components/core/load/model_type/node_type/tosca.nodes.DG.json create mode 100644 components/core/load/model_type/node_type/tosca.nodes.Vnf.json create mode 100644 components/core/load/model_type/node_type/tosca.nodes.component.Python.json (limited to 'components') diff --git a/components/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json b/components/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json index 635e177a1..7b9b7dd71 100644 --- a/components/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json +++ b/components/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json @@ -44,7 +44,7 @@ "resource-assignment": { "type": "component-resource-assignment", "properties":{ - "request-id": ["1234", "1234"] + "request-id": "1234" }, "interfaces": { "DefaultComponentNode": { @@ -80,7 +80,7 @@ "resource-assignment-py": { "type": "component-resource-assignment", "properties":{ - "request-id": ["1234", "1234"] + "request-id": "1234" }, "interfaces": { "DefaultComponentNode": { @@ -256,35 +256,6 @@ "tosca.nodes.component.Python": { "description": "This is Resource Assignment Python Component API", "version": "1.0.0", - "properties": { - "type": { - "description": "Request Id used to store the generated configuration, in the database along with the template-name", - "required": false, - "type": "string" - } - }, - "interfaces": { - "DefaultOperation": { - "operations": { - "validate": { - "inputs": { - "action-name": { - "description": "validate for action", - "required": false, - "type": "string" - } - } - } - } - } - }, - "artifacts" :{ - "component-jar": { - "description": "Component Jar", - "type": "artifact-component-jar", - "file": "Component/basecomponent.jar" - } - }, "derived_from": "tosca.nodes.Root" }, "component-resource-assignment": { diff --git a/components/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json b/components/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json index e78f32f02..65028ace0 100644 --- a/components/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json +++ b/components/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json @@ -117,7 +117,7 @@ "properties": { "mode": "sync", "version": "LATEST", - "is-start-flow": "false" + "is-start-flow": false }, "requirements": { "component-dependency": { @@ -151,7 +151,7 @@ "properties": { "mode": "sync", "version": "LATEST", - "is-start-flow": "false" + "is-start-flow": false }, "requirements": { "component-dependency": { diff --git a/components/core/load/model_type/node_type/component-resource-assignment.json b/components/core/load/model_type/node_type/component-resource-assignment.json index 34c028482..03f3c2845 100644 --- a/components/core/load/model_type/node_type/component-resource-assignment.json +++ b/components/core/load/model_type/node_type/component-resource-assignment.json @@ -7,7 +7,7 @@ } }, "interfaces": { - "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": { + "org-onap-sdnc-config-assignment-service-ConfigAssignmentNode": { "operations": { "process": { "inputs": { diff --git a/components/core/load/model_type/node_type/dg-activate-netconf.json b/components/core/load/model_type/node_type/dg-activate-netconf.json index c638df00c..a9d16eddc 100644 --- a/components/core/load/model_type/node_type/dg-activate-netconf.json +++ b/components/core/load/model_type/node_type/dg-activate-netconf.json @@ -15,7 +15,7 @@ "is-start-flow": { "required": false, "type": "boolean", - "default": "false" + "default": false } }, "capabilities": { diff --git a/components/core/load/model_type/node_type/dg-config-generator.json b/components/core/load/model_type/node_type/dg-config-generator.json index 28bace0f0..6794b3c89 100644 --- a/components/core/load/model_type/node_type/dg-config-generator.json +++ b/components/core/load/model_type/node_type/dg-config-generator.json @@ -15,7 +15,7 @@ "is-start-flow": { "required": false, "type": "boolean", - "default": "false" + "default": false } }, "capabilities": { diff --git a/components/core/load/model_type/node_type/dg-resource-assign-activate.json b/components/core/load/model_type/node_type/dg-resource-assign-activate.json index e98fa5a67..22a4d813c 100644 --- a/components/core/load/model_type/node_type/dg-resource-assign-activate.json +++ b/components/core/load/model_type/node_type/dg-resource-assign-activate.json @@ -15,7 +15,7 @@ "is-start-flow": { "required": false, "type": "boolean", - "default": "false" + "default": false } }, "capabilities": { diff --git a/components/core/load/model_type/node_type/dg-resource-assignment.json b/components/core/load/model_type/node_type/dg-resource-assignment.json index 36fbb6861..7c01faa13 100644 --- a/components/core/load/model_type/node_type/dg-resource-assignment.json +++ b/components/core/load/model_type/node_type/dg-resource-assignment.json @@ -15,7 +15,7 @@ "is-start-flow": { "required": false, "type": "boolean", - "default": "false" + "default": false } }, "capabilities": { diff --git a/components/core/load/model_type/node_type/tosca.nodes.Component.json b/components/core/load/model_type/node_type/tosca.nodes.Component.json new file mode 100644 index 000000000..bc4827b8b --- /dev/null +++ b/components/core/load/model_type/node_type/tosca.nodes.Component.json @@ -0,0 +1,5 @@ +{ + "description": "This is default Component Node", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" +} \ No newline at end of file diff --git a/components/core/load/model_type/node_type/tosca.nodes.DG.json b/components/core/load/model_type/node_type/tosca.nodes.DG.json new file mode 100644 index 000000000..86728cf2f --- /dev/null +++ b/components/core/load/model_type/node_type/tosca.nodes.DG.json @@ -0,0 +1,5 @@ +{ + "description": "This is Directed Graph Node Type", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" +} \ No newline at end of file diff --git a/components/core/load/model_type/node_type/tosca.nodes.Vnf.json b/components/core/load/model_type/node_type/tosca.nodes.Vnf.json new file mode 100644 index 000000000..acb1f2f31 --- /dev/null +++ b/components/core/load/model_type/node_type/tosca.nodes.Vnf.json @@ -0,0 +1,5 @@ +{ + "description": "This is VNF Node Type", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" +} \ No newline at end of file diff --git a/components/core/load/model_type/node_type/tosca.nodes.component.Python.json b/components/core/load/model_type/node_type/tosca.nodes.component.Python.json new file mode 100644 index 000000000..7b67c8cb2 --- /dev/null +++ b/components/core/load/model_type/node_type/tosca.nodes.component.Python.json @@ -0,0 +1,5 @@ +{ + "description": "This is Python Component", + "version": "1.0.0", + "derived_from": "tosca.nodes.Root" +} \ No newline at end of file diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt index 4ae1f4d5d..ffad8e561 100644 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt @@ -94,6 +94,8 @@ object BluePrintConstants { const val MODEL_TYPE_NODES_COMPONENT_PYTHON: String = "tosca.nodes.component.Python" const val MODEL_TYPE_NODES_COMPONENT_JAVA_SCRIPT: String = "tosca.nodes.component.JavaScript" + const val MODEL_TYPE_ARTIFACT_TYPE_IMPLEMENTATION ="tosca.artifacts.Implementation" + const val MODEL_TYPE_DATA_TYPE_DYNAMIC = "tosca.datatypes.Dynamic" const val EXPRESSION_GET_INPUT: String = "get_input" diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt index 33c811f4a..af3966aad 100644 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt @@ -23,6 +23,33 @@ package org.onap.ccsdk.apps.controllerblueprints.core */ object BluePrintTypes { + @JvmStatic + val validNodeTypeDerivedFroms: MutableList = arrayListOf( + BluePrintConstants.MODEL_TYPE_NODES_ROOT, + BluePrintConstants.MODEL_TYPE_NODE_DG, + BluePrintConstants.MODEL_TYPE_NODE_COMPONENT, + BluePrintConstants.MODEL_TYPE_NODE_VNF, + BluePrintConstants.MODEL_TYPE_NODE_ARTIFACT, + BluePrintConstants.MODEL_TYPE_NODE_RESOURCE_SOURCE, + BluePrintConstants.MODEL_TYPE_NODES_COMPONENT_JAVA, + BluePrintConstants.MODEL_TYPE_NODES_COMPONENT_BUNDLE, + BluePrintConstants.MODEL_TYPE_NODES_COMPONENT_SCRIPT, + BluePrintConstants.MODEL_TYPE_NODES_COMPONENT_PYTHON, + BluePrintConstants.MODEL_TYPE_NODES_COMPONENT_JAVA_SCRIPT + ) + + @JvmStatic + val validArtifactTypeDerivedFroms: MutableList = arrayListOf( + BluePrintConstants.MODEL_TYPE_ARTIFACTS_ROOT, + BluePrintConstants.MODEL_TYPE_ARTIFACT_TYPE_IMPLEMENTATION + ) + + @JvmStatic + val validDataTypeDerivedFroms: MutableList = arrayListOf( + BluePrintConstants.MODEL_TYPE_DATATYPES_ROOT, + BluePrintConstants.MODEL_TYPE_DATA_TYPE_DYNAMIC + ) + @JvmStatic fun validModelTypes(): List { val validTypes: MutableList = arrayListOf() diff --git a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt index 34399fdd2..a3b68e0dd 100644 --- a/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt +++ b/components/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt @@ -23,6 +23,7 @@ import org.onap.ccsdk.apps.controllerblueprints.core.* import org.onap.ccsdk.apps.controllerblueprints.core.data.* import com.att.eelf.configuration.EELFLogger import com.att.eelf.configuration.EELFManager +import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils import java.io.Serializable /** @@ -52,7 +53,7 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { @Throws(BluePrintException::class) override fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap) { - validateBlueprint(bluePrintContext.serviceTemplate,properties) + validateBlueprint(bluePrintContext.serviceTemplate, properties) } @Throws(BluePrintException::class) @@ -121,7 +122,7 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { paths.add("nodeTypes") nodeTypes.forEach { nodeTypeName, nodeType -> // Validate Single Node Type - validateNodeType(nodeTypeName,nodeType) + validateNodeType(nodeTypeName, nodeType) } paths.removeAt(paths.lastIndex) } @@ -132,13 +133,20 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { message.appendln("--> Node Type :" + paths.joinToString(separator)) val derivedFrom: String = nodeType.derivedFrom //Check Derived From - checkValidNodeTypesDerivedFrom(derivedFrom) + checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom) nodeType.properties?.let { validatePropertyDefinitions(nodeType.properties!!) } nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) } paths.removeAt(paths.lastIndex) } + @Throws(BluePrintException::class) + open fun checkValidNodeTypesDerivedFrom(nodeTypeName: String, derivedFrom: String) { + check(BluePrintTypes.validNodeTypeDerivedFroms.contains(derivedFrom)) { + throw BluePrintException(format("Failed to get node type ({})'s derived from({}) definition ", nodeTypeName, derivedFrom)) + } + } + @Throws(BluePrintException::class) open fun validateTopologyTemplate(topologyTemplate: TopologyTemplate) { paths.add("topology") @@ -167,7 +175,7 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { } @Throws(BluePrintException::class) - open fun validateNodeTemplate(nodeTemplateName : String, nodeTemplate: NodeTemplate) { + open fun validateNodeTemplate(nodeTemplateName: String, nodeTemplate: NodeTemplate) { paths.add(nodeTemplateName) message.appendln("---> Node Template :" + paths.joinToString(separator)) val type: String = nodeTemplate.type @@ -183,6 +191,25 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { paths.removeAt(paths.lastIndex) } + @Throws(BluePrintException::class) + open fun validateArtifactDefinitions(artifacts: MutableMap) { + paths.add("artifacts") + artifacts.forEach { artifactDefinitionName, artifactDefinition -> + paths.add(artifactDefinitionName) + message.appendln("Validating artifact " + paths.joinToString(separator)) + val type: String = artifactDefinition.type + ?: throw BluePrintException("type is missing for artifact definition :" + artifactDefinitionName) + // Check Artifact Type + checkValidArtifactType(artifactDefinitionName, type) + + val file: String = artifactDefinition.file + ?: throw BluePrintException(format("file is missing for artifact definition : {}", artifactDefinitionName)) + + paths.removeAt(paths.lastIndex) + } + paths.removeAt(paths.lastIndex) + } + @Throws(BluePrintException::class) open fun validateWorkFlows(workflows: MutableMap) { paths.add("workflows") @@ -195,7 +222,7 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { } @Throws(BluePrintException::class) - open fun validateWorkFlow(workflowName:String, workflow: Workflow) { + open fun validateWorkFlow(workflowName: String, workflow: Workflow) { paths.add(workflowName) message.appendln("---> Workflow :" + paths.joinToString(separator)) // Step Validation Start @@ -239,31 +266,20 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { properties.forEach { propertyName, propertyAssignment -> val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName] ?: throw BluePrintException(format("failed to get definition for the property ({})", propertyName)) - // Check and Validate if Expression Node - val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment) - if (!expressionData.isExpression) { - checkPropertyValue(propertyDefinition, propertyAssignment) - } + + validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment) + } } @Throws(BluePrintException::class) - open fun validateArtifactDefinitions(artifacts: MutableMap) { - paths.add("artifacts") - artifacts.forEach { artifactName, artifactDefinition -> - paths.add(artifactName) - message.appendln("Validating artifact " + paths.joinToString(separator)) - val type: String = artifactDefinition.type - ?: throw BluePrintException("type is missing for artifact definition :" + artifactName) - // Check Artifact Type - checkValidArtifactType(type) - - val file: String = artifactDefinition.file - ?: throw BluePrintException(format("file is missing for artifact definition : {}", artifactName)) - - paths.removeAt(paths.lastIndex) + open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition, + propertyAssignment: JsonNode) { + // Check and Validate if Expression Node + val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment) + if (!expressionData.isExpression) { + checkPropertyValue(propertyName, propertyDefinition, propertyAssignment) } - paths.removeAt(paths.lastIndex) } @Throws(BluePrintException::class) @@ -313,34 +329,65 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { } @Throws(BluePrintException::class) - open fun checkValidNodeType(nodeType : String) { + open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) { + + val artifactType = serviceTemplate.artifactTypes?.get(artifactTypeName) + ?: throw BluePrintException(format("Failed to artifact type for artifact definition : {}", artifactDefinitionName)) + checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom) } @Throws(BluePrintException::class) - open fun checkValidArtifactType(artifactType: String) { - - serviceTemplate.artifactTypes?.containsKey(artifactType) - ?: throw BluePrintException(format("Failed to node type definition for artifact definition : {}", artifactType)) + open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) { + check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) { + throw BluePrintException(format("Failed to get artifact type ({})'s derived from({}) definition ", artifactTypeName, derivedFrom)) + } } @Throws(BluePrintException::class) - open fun checkValidNodeTypesDerivedFrom(derivedFrom: String) { - + open fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) { + check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) { + throw BluePrintException(format("Failed to get data type ({})'s derived from({}) definition ", dataTypeName, derivedFrom)) + } } - private fun checkPropertyValue(propertyDefinition: PropertyDefinition, jsonNode: JsonNode) { - //log.info("validating path ({}), Property {}, value ({})", paths, propertyDefinition, jsonNode) - } + open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) { + val propertyType = propertyDefinition.type + val isValid: Boolean + + if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) { + isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment) + + } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) { + + isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment) + val entrySchemaType = propertyDefinition.entrySchema?.type + ?: throw BluePrintException(format("Failed to get Entry Schema type for the collection property ({})", propertyName)) + + if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) { + checkPropertyDataType(entrySchemaType, propertyName) + } - private fun checkPropertyDataType(dataType: String, propertyName: String): Boolean { - if (checkDataType(dataType)) { - return true } else { - throw BluePrintException(format("Data type ({}) for the property ({}) not found", dataType, propertyName)) + checkPropertyDataType(propertyType, propertyName) + isValid = true + } + + check(isValid) { + throw BluePrintException(format("property({}) defined of type({}) is not compatable with the value ({})", + propertyName, propertyType, propertyAssignment)) } } + private fun checkPropertyDataType(dataType: String, propertyName: String) { + + val dataType = serviceTemplate.dataTypes?.get(dataType) + ?: throw BluePrintException(format("Data type ({}) for the property ({}) not found", dataType, propertyName)) + + checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom) + + } + private fun checkPrimitiveOrComplex(dataType: String, propertyName: String): Boolean { if (BluePrintTypes.validPrimitiveTypes().contains(dataType) || checkDataType(dataType)) { return true @@ -353,8 +400,4 @@ open class BluePrintValidatorDefaultService : BluePrintValidatorService { return serviceTemplate.dataTypes?.containsKey(key) ?: false } - private fun checkNodeType(key: String): Boolean { - return serviceTemplate.nodeTypes?.containsKey(key) ?: false - } - } \ No newline at end of file -- cgit 1.2.3-korg