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) {
43 log.trace("Validating NodeTemplate($nodeTemplateName)")
44 this.bluePrintContext = bluePrintContext
47 paths.add(nodeTemplateName)
49 val type: String = nodeTemplate.type
51 val nodeType: NodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(type)
52 ?: throw BluePrintException("Failed to get NodeType($type) definition for NodeTemplate($nodeTemplateName)")
54 nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }
55 nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeType, nodeTemplateName, nodeTemplate) }
56 nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, nodeTemplateName, nodeTemplate) }
57 nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, nodeTemplateName, nodeTemplate) }
58 nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }
60 paths.removeAt(paths.lastIndex)
63 @Throws(BluePrintException::class)
64 open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {
65 paths.add("artifacts")
66 artifacts.forEach { artifactDefinitionName, artifactDefinition ->
67 paths.add(artifactDefinitionName)
68 val type: String = artifactDefinition.type
69 ?: throw BluePrintException("type is missing for ArtifactDefinition$artifactDefinitionName)")
70 // Check Artifact Type
71 checkValidArtifactType(artifactDefinitionName, type)
73 val file: String = artifactDefinition.file
74 ?: throw BluePrintException("file is missing for ArtifactDefinition($artifactDefinitionName)")
76 paths.removeAt(paths.lastIndex)
78 paths.removeAt(paths.lastIndex)
82 @Throws(BluePrintException::class)
83 open fun validatePropertyAssignments(nodeTypeProperties: MutableMap<String, PropertyDefinition>,
84 properties: MutableMap<String, JsonNode>) {
85 properties.forEach { propertyName, propertyAssignment ->
86 val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]
87 ?: throw BluePrintException("failed to get definition for the property ($propertyName)")
89 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
94 @Throws(BluePrintException::class)
95 open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition,
96 propertyAssignment: JsonNode) {
97 // Check and Validate if Expression Node
98 val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)
99 if (!expressionData.isExpression) {
100 checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)
104 @Throws(BluePrintException::class)
105 open fun validateCapabilityAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
106 val capabilities = nodeTemplate.capabilities
107 paths.add("capabilities")
108 capabilities?.forEach { capabilityName, capabilityAssignment ->
109 paths.add(capabilityName)
111 val capabilityDefinition = nodeType.capabilities?.get(capabilityName)
112 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) capability definition ($capabilityName) " +
113 "from NodeType(${nodeTemplate.type})")
115 validateCapabilityAssignment(nodeTemplateName, capabilityName, capabilityDefinition, capabilityAssignment)
117 paths.removeAt(paths.lastIndex)
119 paths.removeAt(paths.lastIndex)
122 @Throws(BluePrintException::class)
123 open fun validateCapabilityAssignment(nodeTemplateName: String, capabilityName: String,
124 capabilityDefinition: CapabilityDefinition, capabilityAssignment: CapabilityAssignment) {
126 capabilityAssignment.properties?.let { validatePropertyAssignments(capabilityDefinition.properties!!, capabilityAssignment.properties!!) }
130 @Throws(BluePrintException::class)
131 open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
132 val requirements = nodeTemplate.requirements
133 paths.add("requirements")
134 requirements?.forEach { requirementName, requirementAssignment ->
135 paths.add(requirementName)
136 val requirementDefinition = nodeType.requirements?.get(requirementName)
137 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) requirement definition ($requirementName) from" +
138 " NodeType(${nodeTemplate.type})")
139 // Validate Requirement Assignment
140 validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)
141 paths.removeAt(paths.lastIndex)
143 paths.removeAt(paths.lastIndex)
147 @Throws(BluePrintException::class)
148 open fun validateRequirementAssignment(nodeTemplateName: String, requirementAssignmentName: String,
149 requirementDefinition: RequirementDefinition, requirementAssignment: RequirementAssignment) {
150 log.info("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName, requirementAssignmentName)
151 val requirementNodeTemplateName = requirementAssignment.node!!
152 val capabilityName = requirementAssignment.capability
153 val relationship = requirementAssignment.relationship!!
155 check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
156 throw BluePrintException("Failed to get relationship type ($relationship) for NodeTemplate($nodeTemplateName)'s requirement($requirementAssignmentName)")
159 val relationShipNodeTemplate = bluePrintContext!!.serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)
160 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
161 "for NodeTemplate($nodeTemplateName) requirement($requirementAssignmentName)")
163 relationShipNodeTemplate.capabilities?.get(capabilityName)
164 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
165 "capability($capabilityName) for NodeTemplate ($nodeTemplateName)'s requirement($requirementAssignmentName)")
170 @Throws(BluePrintException::class)
171 open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
173 val interfaces = nodeTemplate.interfaces
174 paths.add("interfaces")
175 interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->
176 paths.add(interfaceAssignmentName)
177 val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)
178 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) interface definition ($interfaceAssignmentName) from" +
179 " NodeType(${nodeTemplate.type})")
181 validateInterfaceAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
183 paths.removeAt(paths.lastIndex)
185 paths.removeAt(paths.lastIndex)
190 @Throws(BluePrintException::class)
191 open fun validateInterfaceAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
192 interfaceDefinition: InterfaceDefinition,
193 interfaceAssignment: InterfaceAssignment) {
195 val operations = interfaceAssignment.operations
197 validateInterfaceOperationsAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
203 @Throws(BluePrintException::class)
204 open fun validateInterfaceOperationsAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
205 interfaceDefinition: InterfaceDefinition,
206 interfaceAssignment: InterfaceAssignment) {
208 val operations = interfaceAssignment.operations
210 it.forEach { operationAssignmentName, operationAssignments ->
212 val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)
213 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName)")
215 log.info("Validation NodeTemplate({}) Interface({}) Operation ({})", nodeTemplateName,
216 interfaceAssignmentName, operationAssignmentName)
218 val inputs = operationAssignments.inputs
219 val outputs = operationAssignments.outputs
221 inputs?.forEach { propertyName, propertyAssignment ->
222 val propertyDefinition = operationDefinition.inputs?.get(propertyName)
223 ?: throw BluePrintException("Failed to get NodeTemplate(nodeTemplateName) operation " +
224 "definition (operationAssignmentName) property definition(propertyName)")
225 // Check the property values with property definition
226 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
229 outputs?.forEach { propertyName, propertyAssignment ->
230 val propertyDefinition = operationDefinition.outputs?.get(propertyName)
231 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName) " +
232 "output property definition($propertyName)")
233 // Check the property values with property definition
234 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
242 open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) {
244 val artifactType = bluePrintContext!!.serviceTemplate.artifactTypes?.get(artifactTypeName)
245 ?: throw BluePrintException("failed to artifactType($artifactTypeName) for ArtifactDefinition($artifactDefinitionName)")
247 checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom)
250 @Throws(BluePrintException::class)
251 open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) {
252 check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) {
253 throw BluePrintException("failed to get artifactType($artifactTypeName)'s derivedFrom($derivedFrom) definition")
257 open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) {
258 val propertyType = propertyDefinition.type
261 if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {
262 isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)
264 } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {
266 val entrySchemaType = propertyDefinition.entrySchema?.type
267 ?: throw BluePrintException(format("Failed to get EntrySchema type for the collection property ({})", propertyName))
269 if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {
270 checkPropertyDataType(entrySchemaType, propertyName)
272 isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)
274 checkPropertyDataType(propertyType, propertyName)
279 throw BluePrintException("property(propertyName) defined of type(propertyType) is not comptable with the value (propertyAssignment)")
283 private fun checkPropertyDataType(dataTypeName: String, propertyName: String) {
285 val dataType = bluePrintContext!!.serviceTemplate.dataTypes?.get(dataTypeName)
286 ?: throw BluePrintException("DataType ($dataTypeName) for the property ($propertyName) not found")
288 checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)
292 private fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {
293 check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {
294 throw BluePrintException("Failed to get DataType($dataTypeName)'s derivedFrom($derivedFrom) definition ")