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.data.*
25 import org.onap.ccsdk.apps.controllerblueprints.core.format
26 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintNodeTemplateValidator
27 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintTypeValidatorService
28 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext
29 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintExpressionService
30 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
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 lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
39 lateinit var bluePrintContext: BluePrintContext
40 var paths: MutableList<String> = arrayListOf()
42 override fun validate(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
43 log.info("Validating NodeTemplate($nodeTemplateName)")
45 this.bluePrintRuntimeService = bluePrintRuntimeService
46 this.bluePrintContext = bluePrintRuntimeService.bluePrintContext()
48 paths.add(nodeTemplateName)
50 val type: String = nodeTemplate.type
52 val nodeType: NodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(type)
53 ?: throw BluePrintException("Failed to get NodeType($type) definition for NodeTemplate($nodeTemplateName)")
55 nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }
56 nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeType, nodeTemplateName, nodeTemplate) }
57 nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, nodeTemplateName, nodeTemplate) }
58 nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, nodeTemplateName, nodeTemplate) }
59 nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }
61 paths.removeAt(paths.lastIndex)
64 @Throws(BluePrintException::class)
65 open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {
66 paths.add("artifacts")
67 artifacts.forEach { artifactDefinitionName, artifactDefinition ->
68 paths.add(artifactDefinitionName)
69 val type: String = artifactDefinition.type
70 ?: throw BluePrintException("type is missing for ArtifactDefinition$artifactDefinitionName)")
71 // Check Artifact Type
72 checkValidArtifactType(artifactDefinitionName, type)
74 val file: String = artifactDefinition.file
75 ?: throw BluePrintException("file is missing for ArtifactDefinition($artifactDefinitionName)")
77 paths.removeAt(paths.lastIndex)
79 paths.removeAt(paths.lastIndex)
83 @Throws(BluePrintException::class)
84 open fun validatePropertyAssignments(nodeTypeProperties: MutableMap<String, PropertyDefinition>,
85 properties: MutableMap<String, JsonNode>) {
86 properties.forEach { propertyName, propertyAssignment ->
87 val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]
88 ?: throw BluePrintException("failed to get definition for the property ($propertyName)")
90 validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
95 @Throws(BluePrintException::class)
96 open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition,
97 propertyAssignment: JsonNode) {
98 // Check and Validate if Expression Node
99 val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)
100 if (!expressionData.isExpression) {
101 checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)
105 @Throws(BluePrintException::class)
106 open fun validateCapabilityAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
107 val capabilities = nodeTemplate.capabilities
108 paths.add("capabilities")
109 capabilities?.forEach { capabilityName, capabilityAssignment ->
110 paths.add(capabilityName)
112 val capabilityDefinition = nodeType.capabilities?.get(capabilityName)
113 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) capability definition ($capabilityName) " +
114 "from NodeType(${nodeTemplate.type})")
116 validateCapabilityAssignment(nodeTemplateName, capabilityName, capabilityDefinition, capabilityAssignment)
118 paths.removeAt(paths.lastIndex)
120 paths.removeAt(paths.lastIndex)
123 @Throws(BluePrintException::class)
124 open fun validateCapabilityAssignment(nodeTemplateName: String, capabilityName: String,
125 capabilityDefinition: CapabilityDefinition, capabilityAssignment: CapabilityAssignment) {
127 capabilityAssignment.properties?.let { validatePropertyAssignments(capabilityDefinition.properties!!, capabilityAssignment.properties!!) }
131 @Throws(BluePrintException::class)
132 open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
133 val requirements = nodeTemplate.requirements
134 paths.add("requirements")
135 requirements?.forEach { requirementName, requirementAssignment ->
136 paths.add(requirementName)
137 val requirementDefinition = nodeType.requirements?.get(requirementName)
138 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) requirement definition ($requirementName) from" +
139 " NodeType(${nodeTemplate.type})")
140 // Validate Requirement Assignment
141 validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)
142 paths.removeAt(paths.lastIndex)
144 paths.removeAt(paths.lastIndex)
148 @Throws(BluePrintException::class)
149 open fun validateRequirementAssignment(nodeTemplateName: String, requirementAssignmentName: String,
150 requirementDefinition: RequirementDefinition, requirementAssignment: RequirementAssignment) {
151 log.info("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName, requirementAssignmentName)
152 val requirementNodeTemplateName = requirementAssignment.node!!
153 val capabilityName = requirementAssignment.capability
154 val relationship = requirementAssignment.relationship!!
156 check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
157 throw BluePrintException("Failed to get relationship type ($relationship) for NodeTemplate($nodeTemplateName)'s requirement($requirementAssignmentName)")
160 val relationShipNodeTemplate = bluePrintContext.serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)
161 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
162 "for NodeTemplate($nodeTemplateName) requirement($requirementAssignmentName)")
164 relationShipNodeTemplate.capabilities?.get(capabilityName)
165 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
166 "capability($capabilityName) for NodeTemplate ($nodeTemplateName)'s requirement($requirementAssignmentName)")
171 @Throws(BluePrintException::class)
172 open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
174 val interfaces = nodeTemplate.interfaces
175 paths.add("interfaces")
176 interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->
177 paths.add(interfaceAssignmentName)
178 val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)
179 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) interface definition ($interfaceAssignmentName) from" +
180 " NodeType(${nodeTemplate.type})")
182 validateInterfaceAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
184 paths.removeAt(paths.lastIndex)
186 paths.removeAt(paths.lastIndex)
191 @Throws(BluePrintException::class)
192 open fun validateInterfaceAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
193 interfaceDefinition: InterfaceDefinition,
194 interfaceAssignment: InterfaceAssignment) {
196 val operations = interfaceAssignment.operations
198 validateInterfaceOperationsAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
204 @Throws(BluePrintException::class)
205 open fun validateInterfaceOperationsAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
206 interfaceDefinition: InterfaceDefinition,
207 interfaceAssignment: InterfaceAssignment) {
209 val operations = interfaceAssignment.operations
211 it.forEach { operationAssignmentName, operationAssignments ->
213 val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)
214 ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName)")
216 log.info("Validation NodeTemplate($nodeTemplateName) Interface($interfaceAssignmentName) Operation ($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 get 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 ")