aboutsummaryrefslogtreecommitdiffstats
path: root/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt
diff options
context:
space:
mode:
Diffstat (limited to 'ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt')
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt711
1 files changed, 711 insertions, 0 deletions
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt
new file mode 100644
index 000000000..8a8ded752
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/service/BluePrintValidatorService.kt
@@ -0,0 +1,711 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ * Modifications Copyright © 2018 IBM.
+ *
+ * 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.controllerblueprints.core.service
+
+import com.fasterxml.jackson.databind.JsonNode
+import com.google.common.base.Preconditions
+import org.apache.commons.lang3.StringUtils
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
+import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.CapabilityAssignment
+import org.onap.ccsdk.cds.controllerblueprints.core.data.CapabilityDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.Implementation
+import org.onap.ccsdk.cds.controllerblueprints.core.data.InterfaceAssignment
+import org.onap.ccsdk.cds.controllerblueprints.core.data.InterfaceDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeType
+import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.RequirementAssignment
+import org.onap.ccsdk.cds.controllerblueprints.core.data.RequirementDefinition
+import org.onap.ccsdk.cds.controllerblueprints.core.data.ServiceTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.data.TopologyTemplate
+import org.onap.ccsdk.cds.controllerblueprints.core.data.Workflow
+import org.onap.ccsdk.cds.controllerblueprints.core.format
+import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
+import org.slf4j.LoggerFactory
+import java.io.Serializable
+
+/**
+ *
+ *
+ * @author Brinda Santh
+ */
+interface BluePrintValidatorService : Serializable {
+
+ @Throws(BluePrintException::class)
+ fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>)
+
+ @Throws(BluePrintException::class)
+ fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>)
+}
+
+@Deprecated("Decomposed implementation moved to blueprint-validation module")
+open class BluePrintValidatorDefaultService : BluePrintValidatorService {
+
+ val log = LoggerFactory.getLogger(BluePrintValidatorDefaultService::class.toString())
+
+ lateinit var bluePrintContext: BluePrintContext
+ lateinit var serviceTemplate: ServiceTemplate
+ lateinit var properties: MutableMap<String, Any>
+ var message: StringBuilder = StringBuilder()
+ private val separator: String = BluePrintConstants.PATH_DIVIDER
+ var paths: MutableList<String> = arrayListOf()
+
+ @Throws(BluePrintException::class)
+ override fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>) {
+ validateBlueprint(bluePrintContext.serviceTemplate, properties)
+ }
+
+ @Throws(BluePrintException::class)
+ override fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>) {
+ this.bluePrintContext = BluePrintContext(serviceTemplate)
+ this.serviceTemplate = serviceTemplate
+ this.properties = properties
+ try {
+ message.appendln("-> Config Blueprint")
+ serviceTemplate.metadata?.let { validateMetadata(serviceTemplate.metadata!!) }
+ serviceTemplate.artifactTypes?.let { validateArtifactTypes(serviceTemplate.artifactTypes!!) }
+ serviceTemplate.dataTypes?.let { validateDataTypes(serviceTemplate.dataTypes!!) }
+ serviceTemplate.nodeTypes?.let { validateNodeTypes(serviceTemplate.nodeTypes!!) }
+ serviceTemplate.topologyTemplate?.let { validateTopologyTemplate(serviceTemplate.topologyTemplate!!) }
+ } catch (e: Exception) {
+ log.error("validation failed in the path : {}", paths.joinToString(separator), e)
+ log.error("validation trace message :{} ", message)
+ throw BluePrintException(
+ e,
+ format("failed to validate blueprint on path ({}) with message {}", paths.joinToString(separator), e.message)
+ )
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateMetadata(metaDataMap: MutableMap<String, String>) {
+ paths.add("metadata")
+
+ val templateName = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_NAME]
+ val templateVersion = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_VERSION]
+ val templateTags = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_TAGS]
+ val templateAuthor = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_AUTHOR]
+
+ Preconditions.checkArgument(StringUtils.isNotBlank(templateName), "failed to get template name metadata")
+ Preconditions.checkArgument(StringUtils.isNotBlank(templateVersion), "failed to get template version metadata")
+ Preconditions.checkArgument(StringUtils.isNotBlank(templateTags), "failed to get template tags metadata")
+ Preconditions.checkArgument(StringUtils.isNotBlank(templateAuthor), "failed to get template author metadata")
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateArtifactTypes(artifactTypes: MutableMap<String, ArtifactType>) {
+ paths.add("artifact_types")
+ artifactTypes.forEach { artifactName, artifactType ->
+ paths.add(artifactName)
+ message.appendln("--> Artifact Type :" + paths.joinToString(separator))
+ artifactType.properties?.let { validatePropertyDefinitions(artifactType.properties!!) }
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateDataTypes(dataTypes: MutableMap<String, DataType>) {
+ paths.add("dataTypes")
+ dataTypes.forEach { dataTypeName, dataType ->
+ paths.add(dataTypeName)
+ message.appendln("--> DataType :" + paths.joinToString(separator))
+ dataType.properties?.let { validatePropertyDefinitions(dataType.properties!!) }
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateNodeTypes(nodeTypes: MutableMap<String, NodeType>) {
+ paths.add("nodeTypes")
+ nodeTypes.forEach { nodeTypeName, nodeType ->
+ // Validate Single Node Type
+ validateNodeType(nodeTypeName, nodeType)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateNodeType(nodeTypeName: String, nodeType: NodeType) {
+ paths.add(nodeTypeName)
+ message.appendln("--> Node Type :" + paths.joinToString(separator))
+ val derivedFrom: String = nodeType.derivedFrom
+ // Check Derived From
+ checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom)
+
+ if (!BluePrintTypes.rootNodeTypes().contains(derivedFrom)) {
+ serviceTemplate.nodeTypes?.get(derivedFrom)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get derivedFrom NodeType({})'s for NodeType({}) ",
+ derivedFrom, nodeTypeName
+ )
+ )
+ }
+
+ nodeType.properties?.let { validatePropertyDefinitions(nodeType.properties!!) }
+ nodeType.capabilities?.let { validateCapabilityDefinitions(nodeTypeName, nodeType) }
+ nodeType.requirements?.let { validateRequirementDefinitions(nodeTypeName, nodeType) }
+ 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 derivedFrom({}) definition ", nodeTypeName, derivedFrom))
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateTopologyTemplate(topologyTemplate: TopologyTemplate) {
+ paths.add("topology")
+ message.appendln("--> Topology Template")
+ topologyTemplate.inputs?.let { validateInputs(topologyTemplate.inputs!!) }
+ topologyTemplate.nodeTemplates?.let { validateNodeTemplates(topologyTemplate.nodeTemplates!!) }
+ topologyTemplate.workflows?.let { validateWorkFlows(topologyTemplate.workflows!!) }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateInputs(inputs: MutableMap<String, PropertyDefinition>) {
+ paths.add("inputs")
+ message.appendln("---> Input :" + paths.joinToString(separator))
+ validatePropertyDefinitions(inputs)
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateNodeTemplates(nodeTemplates: MutableMap<String, NodeTemplate>) {
+ paths.add("nodeTemplates")
+ nodeTemplates.forEach { nodeTemplateName, nodeTemplate ->
+ validateNodeTemplate(nodeTemplateName, nodeTemplate)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateNodeTemplate(nodeTemplateName: String, nodeTemplate: NodeTemplate) {
+ paths.add(nodeTemplateName)
+ message.appendln("---> NodeTemplate :" + paths.joinToString(separator))
+ val type: String = nodeTemplate.type
+
+ val nodeType: NodeType = serviceTemplate.nodeTypes?.get(type)
+ ?: throw BluePrintException(format("Failed to get NodeType({}) definition for NodeTemplate({})", type, nodeTemplateName))
+
+ nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }
+ nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }
+ nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeType, nodeTemplateName, nodeTemplate) }
+ nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, nodeTemplateName, nodeTemplate) }
+ nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, nodeTemplateName, nodeTemplate) }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {
+ paths.add("artifacts")
+ artifacts.forEach { artifactDefinitionName, artifactDefinition ->
+ paths.add(artifactDefinitionName)
+ message.appendln("Validating artifact " + paths.joinToString(separator))
+ val type: String = artifactDefinition.type
+ ?: throw BluePrintException(format("type is missing for ArtifactDefinition({})", artifactDefinitionName))
+ // Check Artifact Type
+ checkValidArtifactType(artifactDefinitionName, type)
+
+ val file: String = artifactDefinition.file
+ ?: throw BluePrintException(format("file is missing for ArtifactDefinition({})", artifactDefinitionName))
+
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateWorkFlows(workflows: MutableMap<String, Workflow>) {
+ paths.add("workflows")
+ workflows.forEach { workflowName, workflow ->
+
+ // Validate Single workflow
+ validateWorkFlow(workflowName, workflow)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateWorkFlow(workflowName: String, workflow: Workflow) {
+ paths.add(workflowName)
+ message.appendln("---> Workflow :" + paths.joinToString(separator))
+ // Step Validation Start
+ paths.add("steps")
+ workflow.steps?.forEach { stepName, _ ->
+ paths.add(stepName)
+ message.appendln("----> Steps :" + paths.joinToString(separator))
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ // Step Validation Ends
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validatePropertyDefinitions(properties: MutableMap<String, PropertyDefinition>) {
+ paths.add("properties")
+ properties.forEach { propertyName, propertyDefinition ->
+ paths.add(propertyName)
+ val dataType: String = propertyDefinition.type
+ when {
+ BluePrintTypes.validPrimitiveTypes().contains(dataType) -> {
+ // Do Nothing
+ }
+ BluePrintTypes.validCollectionTypes().contains(dataType) -> {
+ val entrySchemaType: String = propertyDefinition.entrySchema?.type
+ ?: throw BluePrintException(format("Entry schema for DataType ({}) for the property ({}) not found", dataType, propertyName))
+ checkPrimitiveOrComplex(entrySchemaType, propertyName)
+ }
+ else -> checkPropertyDataType(dataType, propertyName)
+ }
+ message.appendln("property " + paths.joinToString(separator) + " of type " + dataType)
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validatePropertyAssignments(
+ nodeTypeProperties: MutableMap<String, PropertyDefinition>,
+ properties: MutableMap<String, JsonNode>
+ ) {
+ properties.forEach { propertyName, propertyAssignment ->
+ val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]
+ ?: throw BluePrintException(format("failed to get definition for the property ({})", propertyName))
+
+ validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ 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)
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateCapabilityAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
+ val capabilities = nodeTemplate.capabilities
+ paths.add("capabilities")
+ capabilities?.forEach { capabilityName, capabilityAssignment ->
+ paths.add(capabilityName)
+
+ val capabilityDefinition = nodeType.capabilities?.get(capabilityName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) capability definition ({}) " +
+ "from NodeType({}) ",
+ nodeTemplateName, capabilityName, nodeTemplate.type
+ )
+ )
+
+ validateCapabilityAssignment(nodeTemplateName, capabilityName, capabilityDefinition, capabilityAssignment)
+
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateCapabilityAssignment(
+ nodeTemplateName: String,
+ capabilityName: String,
+ capabilityDefinition: CapabilityDefinition,
+ capabilityAssignment: CapabilityAssignment
+ ) {
+
+ capabilityAssignment.properties?.let { validatePropertyAssignments(capabilityDefinition.properties!!, capabilityAssignment.properties!!) }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
+ val requirements = nodeTemplate.requirements
+ paths.add("requirements")
+ requirements?.forEach { requirementName, requirementAssignment ->
+ paths.add(requirementName)
+ val requirementDefinition = nodeType.requirements?.get(requirementName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) requirement definition ({}) from" +
+ " NodeType({}) ",
+ nodeTemplateName, requirementName, nodeTemplate.type
+ )
+ )
+ // Validate Requirement Assignment
+ validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateRequirementAssignment(
+ nodeTemplateName: String,
+ requirementAssignmentName: String,
+ requirementDefinition: RequirementDefinition,
+ requirementAssignment: RequirementAssignment
+ ) {
+ log.info("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName, requirementAssignmentName)
+ val requirementNodeTemplateName = requirementAssignment.node!!
+ val capabilityName = requirementAssignment.capability
+ val relationship = requirementAssignment.relationship!!
+
+ check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
+ throw BluePrintException(
+ format(
+ "Failed to get relationship type ({}) for NodeTemplate({})'s requirement({}) ",
+ relationship, nodeTemplateName, requirementAssignmentName
+ )
+ )
+ }
+
+ val relationShipNodeTemplate = serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get requirement NodeTemplate({})'s for NodeTemplate({}) requirement({}) ",
+ requirementNodeTemplateName, nodeTemplateName, requirementAssignmentName
+ )
+ )
+
+ relationShipNodeTemplate.capabilities?.get(capabilityName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get requirement NodeTemplate({})'s capability({}) for NodeTemplate ({})'s requirement({}) ",
+ requirementNodeTemplateName, capabilityName, nodeTemplateName, requirementAssignmentName
+ )
+ )
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
+
+ val interfaces = nodeTemplate.interfaces
+ paths.add("interfaces")
+ interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->
+ paths.add(interfaceAssignmentName)
+ val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) interface definition ({}) from" +
+ " NodeType({}) ",
+ nodeTemplateName, interfaceAssignmentName, nodeTemplate.type
+ )
+ )
+
+ validateInterfaceAssignment(
+ nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
+ interfaceAssignment
+ )
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateInterfaceAssignment(
+ nodeTemplateName: String,
+ interfaceAssignmentName: String,
+ interfaceDefinition: InterfaceDefinition,
+ interfaceAssignment: InterfaceAssignment
+ ) {
+
+ val operations = interfaceAssignment.operations
+ operations?.let {
+ validateInterfaceOperationsAssignment(
+ nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
+ interfaceAssignment
+ )
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateInterfaceOperationsAssignment(
+ nodeTemplateName: String,
+ interfaceAssignmentName: String,
+ interfaceDefinition: InterfaceDefinition,
+ interfaceAssignment: InterfaceAssignment
+ ) {
+
+ val operations = interfaceAssignment.operations
+ operations?.let {
+ it.forEach { operationAssignmentName, operationAssignments ->
+
+ val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) operation definition ({}) ",
+ nodeTemplateName, operationAssignmentName
+ )
+ )
+
+ log.info(
+ "Validation NodeTemplate({}) Interface({}) Operation ({})", nodeTemplateName,
+ interfaceAssignmentName, operationAssignmentName
+ )
+
+ val inputs = operationAssignments.inputs
+ val outputs = operationAssignments.outputs
+
+ inputs?.forEach { propertyName, propertyAssignment ->
+ val propertyDefinition = operationDefinition.inputs?.get(propertyName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) operation definition ({}) " +
+ "property definition({})",
+ nodeTemplateName, operationAssignmentName, propertyName
+ )
+ )
+ // Check the property values with property definition
+ validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
+ }
+
+ outputs?.forEach { propertyName, propertyAssignment ->
+ val propertyDefinition = operationDefinition.outputs?.get(propertyName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get NodeTemplate({}) operation definition ({}) " +
+ "output property definition({})",
+ nodeTemplateName, operationAssignmentName,
+ propertyName
+ )
+ )
+ // Check the property values with property definition
+ validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
+ }
+ }
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateCapabilityDefinitions(nodeTypeName: String, nodeType: NodeType) {
+ val capabilities = nodeType.capabilities
+ paths.add("capabilities")
+ capabilities?.forEach { capabilityName, capabilityDefinition ->
+ paths.add(capabilityName)
+
+ validateCapabilityDefinition(nodeTypeName, nodeType, capabilityName, capabilityDefinition)
+
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateCapabilityDefinition(
+ nodeTypeName: String,
+ nodeType: NodeType,
+ capabilityName: String,
+ capabilityDefinition: CapabilityDefinition
+ ) {
+ val capabilityType = capabilityDefinition.type
+ check(BluePrintTypes.validCapabilityTypes.contains(capabilityType)) {
+ throw BluePrintException(
+ format(
+ "Failed to get CapabilityType({}) for NodeType({})",
+ capabilityType, nodeTypeName
+ )
+ )
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateRequirementDefinitions(nodeName: String, nodeType: NodeType) {
+ paths.add("requirements")
+ val requirements = nodeType.requirements
+
+ requirements?.forEach { requirementDefinitionName, requirementDefinition ->
+ paths.add(requirementDefinitionName)
+ message.appendln("Validating : " + paths.joinToString(separator))
+ validateRequirementDefinition(nodeName, nodeType, requirementDefinitionName, requirementDefinition)
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateRequirementDefinition(
+ nodeTypeName: String,
+ nodeType: NodeType,
+ requirementDefinitionName: String,
+ requirementDefinition: RequirementDefinition
+ ) {
+
+ log.info("Validating NodeType({}) RequirementDefinition ({}) ", nodeTypeName, requirementDefinitionName)
+ val requirementNodeTypeName = requirementDefinition.node!!
+ val capabilityName = requirementDefinition.capability
+ val relationship = requirementDefinition.relationship!!
+
+ check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
+ throw BluePrintException(
+ format(
+ "Failed to get relationship({}) for NodeType({})'s requirement({}) ",
+ relationship, nodeTypeName, requirementDefinitionName
+ )
+ )
+ }
+
+ val relationShipNodeType = serviceTemplate.nodeTypes?.get(requirementNodeTypeName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get requirement NodeType({})'s for requirement({}) ",
+ requirementNodeTypeName, requirementDefinitionName
+ )
+ )
+
+ relationShipNodeType.capabilities?.get(capabilityName)
+ ?: throw BluePrintException(
+ format(
+ "Failed to get requirement NodeType({})'s capability({}) for NodeType ({})'s requirement({}) ",
+ requirementNodeTypeName, capabilityName, nodeTypeName, requirementDefinitionName
+ )
+ )
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateInterfaceDefinitions(interfaces: MutableMap<String, InterfaceDefinition>) {
+ paths.add("interfaces")
+ interfaces.forEach { interfaceName, interfaceDefinition ->
+ paths.add(interfaceName)
+ message.appendln("Validating : " + paths.joinToString(separator))
+ interfaceDefinition.operations?.let { validateOperationDefinitions(interfaceDefinition.operations!!) }
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateOperationDefinitions(operations: MutableMap<String, OperationDefinition>) {
+ paths.add("operations")
+ operations.forEach { opertaionName, operationDefinition ->
+ paths.add(opertaionName)
+ message.appendln("Validating : " + paths.joinToString(separator))
+ operationDefinition.implementation?.let { validateImplementation(operationDefinition.implementation!!) }
+ operationDefinition.inputs?.let { validatePropertyDefinitions(operationDefinition.inputs!!) }
+ operationDefinition.outputs?.let { validatePropertyDefinitions(operationDefinition.outputs!!) }
+ paths.removeAt(paths.lastIndex)
+ }
+ paths.removeAt(paths.lastIndex)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun validateImplementation(implementation: Implementation) {
+ checkNotEmpty(implementation.primary) { "couldn't get implementation" }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) {
+
+ val artifactType = serviceTemplate.artifactTypes?.get(artifactTypeName)
+ ?: throw BluePrintException("failed to artifactType($artifactTypeName) for ArtifactDefinition($artifactDefinitionName)")
+
+ checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom)
+ }
+
+ @Throws(BluePrintException::class)
+ open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) {
+ check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) {
+ throw BluePrintException("failed to get artifactType($artifactTypeName)'s derivedFrom($derivedFrom) definition")
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {
+ check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {
+ throw BluePrintException(format("Failed to get DataType({})'s derivedFrom({}) definition ", dataTypeName, derivedFrom))
+ }
+ }
+
+ @Throws(BluePrintException::class)
+ open fun checkValidRelationshipTypeDerivedFrom(relationshipTypeName: String, derivedFrom: String) {
+ check(BluePrintTypes.validRelationShipDerivedFroms.contains(derivedFrom)) {
+ throw BluePrintException(format("Failed to get relationship type ({})'s derivedFrom({}) definition ", relationshipTypeName, derivedFrom))
+ }
+ }
+
+ 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)) {
+
+ val entrySchemaType = propertyDefinition.entrySchema?.type
+ ?: throw BluePrintException(format("Failed to get EntrySchema type for the collection property ({})", propertyName))
+
+ if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {
+ checkPropertyDataType(entrySchemaType, propertyName)
+ }
+ isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)
+ } else {
+ checkPropertyDataType(propertyType, propertyName)
+ isValid = true
+ }
+
+ check(isValid) {
+ throw BluePrintException(
+ format(
+ "property({}) defined of type({}) is not comptable with the value ({})",
+ propertyName, propertyType, propertyAssignment
+ )
+ )
+ }
+ }
+
+ private fun checkPropertyDataType(dataTypeName: String, propertyName: String) {
+
+ val dataType = serviceTemplate.dataTypes?.get(dataTypeName)
+ ?: throw BluePrintException(format("DataType ({}) for the property ({}) not found", dataTypeName, propertyName))
+
+ checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)
+ }
+
+ private fun checkPrimitiveOrComplex(dataType: String, propertyName: String): Boolean {
+ if (BluePrintTypes.validPrimitiveTypes().contains(dataType) || checkDataType(dataType)) {
+ return true
+ } else {
+ throw BluePrintException(format("DataType({}) for the property({}) is not valid", dataType, propertyName))
+ }
+ }
+
+ private fun checkDataType(key: String): Boolean {
+ return serviceTemplate.dataTypes?.containsKey(key) ?: false
+ }
+}