2 * Copyright © 2017-2018 AT&T Intellectual Property.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.apps.controllerblueprints.core.validation
19 import com.att.eelf.configuration.EELFLogger
20 import com.att.eelf.configuration.EELFManager
21 import com.fasterxml.jackson.databind.JsonNode
22 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
23 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintValidationError
25 import org.onap.ccsdk.apps.controllerblueprints.core.data.*
26 import org.onap.ccsdk.apps.controllerblueprints.core.format
27 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintNodeTemplateValidator
28 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintTypeValidatorService
29 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext
30 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintExpressionService
31 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
34 open class BluePrintNodeTemplateValidatorImpl(private val bluePrintTypeValidatorService: BluePrintTypeValidatorService) : BluePrintNodeTemplateValidator {
36 private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintNodeTemplateValidatorImpl::class.toString())
38 var bluePrintContext: BluePrintContext? = null
39 var error: BluePrintValidationError? = null
40 var paths: MutableList<String> = arrayListOf()
42 override fun validate(bluePrintContext: BluePrintContext, error: BluePrintValidationError, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
44 paths.add(nodeTemplateName)
46 val type: String = nodeTemplate.type
48 val nodeType: NodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(type)
49 ?: throw BluePrintException("Failed to get NodeType($type) definition for NodeTemplate($nodeTemplateName)")
51 nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }
52 nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }
53 nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeType, nodeTemplateName, nodeTemplate) }
54 nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, nodeTemplateName, nodeTemplate) }
55 nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, nodeTemplateName, nodeTemplate) }
57 paths.removeAt(paths.lastIndex)
60 @Throws(BluePrintException::class)
61 open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {
62 paths.add("artifacts")
63 artifacts.forEach { artifactDefinitionName, artifactDefinition ->
64 paths.add(artifactDefinitionName)
65 val type: String = artifactDefinition.type
66 ?: throw BluePrintException("type is missing for ArtifactDefinition$artifactDefinitionName)")
67 // Check Artifact Type
68 checkValidArtifactType(artifactDefinitionName, type)
70 val file: String = artifactDefinition.file
71 ?: throw BluePrintException("file is missing for ArtifactDefinition($artifactDefinitionName)")
73 paths.removeAt(paths.lastIndex)
75 paths.removeAt(paths.lastIndex)
79 @Throws(BluePrintException::class)
80 open fun validatePropertyAssignments(nodeTypeProperties: MutableMap<String, PropertyDefinition>,
81 properties: MutableMap<String, JsonNode>) {
82 properties.forEach { propertyName, propertyAssignment ->
83 val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]
84 ?: throw BluePrintException("failed to get definition for the property ($propertyName)")
86 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
91 @Throws(BluePrintException::class)
92 open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition,
93 propertyAssignment: JsonNode) {
94 // Check and Validate if Expression Node
95 val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)
96 if (!expressionData.isExpression) {
97 checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)
101 @Throws(BluePrintException::class)
102 open fun validateCapabilityAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
103 val capabilities = nodeTemplate.capabilities
104 paths.add("capabilities")
105 capabilities?.forEach { capabilityName, capabilityAssignment ->
106 paths.add(capabilityName)
108 val capabilityDefinition = nodeType.capabilities?.get(capabilityName)
109 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) capability definition ($capabilityName) " +
110 "from NodeType(${nodeTemplate.type})")
112 validateCapabilityAssignment(nodeTemplateName, capabilityName, capabilityDefinition, capabilityAssignment)
114 paths.removeAt(paths.lastIndex)
116 paths.removeAt(paths.lastIndex)
119 @Throws(BluePrintException::class)
120 open fun validateCapabilityAssignment(nodeTemplateName: String, capabilityName: String,
121 capabilityDefinition: CapabilityDefinition, capabilityAssignment: CapabilityAssignment) {
123 capabilityAssignment.properties?.let { validatePropertyAssignments(capabilityDefinition.properties!!, capabilityAssignment.properties!!) }
127 @Throws(BluePrintException::class)
128 open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
129 val requirements = nodeTemplate.requirements
130 paths.add("requirements")
131 requirements?.forEach { requirementName, requirementAssignment ->
132 paths.add(requirementName)
133 val requirementDefinition = nodeType.requirements?.get(requirementName)
134 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) requirement definition ($requirementName) from" +
135 " NodeType(${nodeTemplate.type})")
136 // Validate Requirement Assignment
137 validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)
138 paths.removeAt(paths.lastIndex)
140 paths.removeAt(paths.lastIndex)
144 @Throws(BluePrintException::class)
145 open fun validateRequirementAssignment(nodeTemplateName: String, requirementAssignmentName: String,
146 requirementDefinition: RequirementDefinition, requirementAssignment: RequirementAssignment) {
147 log.info("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName, requirementAssignmentName)
148 val requirementNodeTemplateName = requirementAssignment.node!!
149 val capabilityName = requirementAssignment.capability
150 val relationship = requirementAssignment.relationship!!
152 check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
153 throw BluePrintException("Failed to get relationship type ($relationship) for NodeTemplate($nodeTemplateName)'s requirement($requirementAssignmentName)")
156 val relationShipNodeTemplate = bluePrintContext!!.serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)
157 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
158 "for NodeTemplate($nodeTemplateName) requirement($requirementAssignmentName)")
160 relationShipNodeTemplate.capabilities?.get(capabilityName)
161 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
162 "capability($capabilityName) for NodeTemplate ($nodeTemplateName)'s requirement($requirementAssignmentName)")
167 @Throws(BluePrintException::class)
168 open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
170 val interfaces = nodeTemplate.interfaces
171 paths.add("interfaces")
172 interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->
173 paths.add(interfaceAssignmentName)
174 val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)
175 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) interface definition ($interfaceAssignmentName) from" +
176 " NodeType(${nodeTemplate.type})")
178 validateInterfaceAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
180 paths.removeAt(paths.lastIndex)
182 paths.removeAt(paths.lastIndex)
187 @Throws(BluePrintException::class)
188 open fun validateInterfaceAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
189 interfaceDefinition: InterfaceDefinition,
190 interfaceAssignment: InterfaceAssignment) {
192 val operations = interfaceAssignment.operations
194 validateInterfaceOperationsAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
200 @Throws(BluePrintException::class)
201 open fun validateInterfaceOperationsAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
202 interfaceDefinition: InterfaceDefinition,
203 interfaceAssignment: InterfaceAssignment) {
205 val operations = interfaceAssignment.operations
207 it.forEach { operationAssignmentName, operationAssignments ->
209 val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)
210 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName)")
212 log.info("Validation NodeTemplate({}) Interface({}) Operation ({})", nodeTemplateName,
213 interfaceAssignmentName, operationAssignmentName)
215 val inputs = operationAssignments.inputs
216 val outputs = operationAssignments.outputs
218 inputs?.forEach { propertyName, propertyAssignment ->
219 val propertyDefinition = operationDefinition.inputs?.get(propertyName)
220 ?: throw BluePrintException("Failed to get NodeTemplate(nodeTemplateName) operation " +
221 "definition (operationAssignmentName) property definition(propertyName)")
222 // Check the property values with property definition
223 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
226 outputs?.forEach { propertyName, propertyAssignment ->
227 val propertyDefinition = operationDefinition.outputs?.get(propertyName)
228 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName) " +
229 "output property definition($propertyName)")
230 // Check the property values with property definition
231 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
239 open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) {
241 val artifactType = bluePrintContext!!.serviceTemplate.artifactTypes?.get(artifactTypeName)
242 ?: throw BluePrintException("failed to artifactType($artifactTypeName) for ArtifactDefinition($artifactDefinitionName)")
244 checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom)
247 @Throws(BluePrintException::class)
248 open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) {
249 check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) {
250 throw BluePrintException("failed to get artifactType($artifactTypeName)'s derivedFrom($derivedFrom) definition")
254 open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) {
255 val propertyType = propertyDefinition.type
258 if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {
259 isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)
261 } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {
263 val entrySchemaType = propertyDefinition.entrySchema?.type
264 ?: throw BluePrintException(format("Failed to get EntrySchema type for the collection property ({})", propertyName))
266 if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {
267 checkPropertyDataType(entrySchemaType, propertyName)
269 isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)
271 checkPropertyDataType(propertyType, propertyName)
276 throw BluePrintException("property(propertyName) defined of type(propertyType) is not comptable with the value (propertyAssignment)")
280 private fun checkPropertyDataType(dataTypeName: String, propertyName: String) {
282 val dataType = bluePrintContext!!.serviceTemplate.dataTypes?.get(dataTypeName)
283 ?: throw BluePrintException("DataType ($dataTypeName) for the property ($propertyName) not found")
285 checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)
289 private fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {
290 check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {
291 throw BluePrintException("Failed to get DataType($dataTypeName)'s derivedFrom($derivedFrom) definition ")