2b11589d4d2bebab94462fd33e561a245b7069fb
[ccsdk/cds.git] /
1 /*\r
2  * Copyright © 2017-2018 AT&T Intellectual Property.\r
3  * Modifications Copyright © 2018 IBM.\r
4  *\r
5  * Licensed under the Apache License, Version 2.0 (the "License");\r
6  * you may not use this file except in compliance with the License.\r
7  * You may obtain a copy of the License at\r
8  *\r
9  *     http://www.apache.org/licenses/LICENSE-2.0\r
10  *\r
11  * Unless required by applicable law or agreed to in writing, software\r
12  * distributed under the License is distributed on an "AS IS" BASIS,\r
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14  * See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  */\r
17 \r
18 package org.onap.ccsdk.apps.controllerblueprints.core.service\r
19 \r
20 import com.fasterxml.jackson.databind.JsonNode\r
21 import com.google.common.base.Preconditions\r
22 import org.apache.commons.lang3.StringUtils\r
23 import org.onap.ccsdk.apps.controllerblueprints.core.*\r
24 import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
25 import com.att.eelf.configuration.EELFLogger\r
26 import com.att.eelf.configuration.EELFManager\r
27 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
28 import java.io.Serializable\r
29 \r
30 /**\r
31  *\r
32  *\r
33  * @author Brinda Santh\r
34  */\r
35 interface BluePrintValidatorService : Serializable {\r
36 \r
37     @Throws(BluePrintException::class)\r
38     fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>)\r
39 \r
40     @Throws(BluePrintException::class)\r
41     fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>)\r
42 }\r
43 \r
44 open class BluePrintValidatorDefaultService : BluePrintValidatorService {\r
45 \r
46     val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintValidatorDefaultService::class.toString())\r
47 \r
48     lateinit var bluePrintContext: BluePrintContext\r
49     lateinit var serviceTemplate: ServiceTemplate\r
50     lateinit var properties: MutableMap<String, Any>\r
51     var message: StringBuilder = StringBuilder()\r
52     private val separator: String = BluePrintConstants.PATH_DIVIDER\r
53     var paths: MutableList<String> = arrayListOf()\r
54 \r
55     @Throws(BluePrintException::class)\r
56     override fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>) {\r
57         validateBlueprint(bluePrintContext.serviceTemplate, properties)\r
58     }\r
59 \r
60     @Throws(BluePrintException::class)\r
61     override fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>) {\r
62         this.bluePrintContext = BluePrintContext(serviceTemplate)\r
63         this.serviceTemplate = serviceTemplate\r
64         this.properties = properties\r
65         try {\r
66             message.appendln("-> Config Blueprint")\r
67             serviceTemplate.metadata?.let { validateMetadata(serviceTemplate.metadata!!) }\r
68             serviceTemplate.artifactTypes?.let { validateArtifactTypes(serviceTemplate.artifactTypes!!) }\r
69             serviceTemplate.dataTypes?.let { validateDataTypes(serviceTemplate.dataTypes!!) }\r
70             serviceTemplate.nodeTypes?.let { validateNodeTypes(serviceTemplate.nodeTypes!!) }\r
71             serviceTemplate.topologyTemplate?.let { validateTopologyTemplate(serviceTemplate.topologyTemplate!!) }\r
72         } catch (e: Exception) {\r
73             log.error("validation failed in the path : {}", paths.joinToString(separator), e)\r
74             log.error("validation trace message :{} ", message)\r
75             throw BluePrintException(e,\r
76                     format("failed to validate blueprint on path ({}) with message {}"\r
77                             , paths.joinToString(separator), e.message))\r
78         }\r
79     }\r
80 \r
81     @Throws(BluePrintException::class)\r
82     open fun validateMetadata(metaDataMap: MutableMap<String, String>) {\r
83         paths.add("metadata")\r
84 \r
85         val templateName = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_NAME]\r
86         val templateVersion = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_VERSION]\r
87         val templateTags = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_TAGS]\r
88         val templateAuthor = metaDataMap[BluePrintConstants.METADATA_TEMPLATE_AUTHOR]\r
89 \r
90         Preconditions.checkArgument(StringUtils.isNotBlank(templateName), "failed to get template name metadata")\r
91         Preconditions.checkArgument(StringUtils.isNotBlank(templateVersion), "failed to get template version metadata")\r
92         Preconditions.checkArgument(StringUtils.isNotBlank(templateTags), "failed to get template tags metadata")\r
93         Preconditions.checkArgument(StringUtils.isNotBlank(templateAuthor), "failed to get template author metadata")\r
94         paths.removeAt(paths.lastIndex)\r
95     }\r
96 \r
97     @Throws(BluePrintException::class)\r
98     open fun validateArtifactTypes(artifactTypes: MutableMap<String, ArtifactType>) {\r
99         paths.add("artifact_types")\r
100         artifactTypes.forEach { artifactName, artifactType ->\r
101             paths.add(artifactName)\r
102             message.appendln("--> Artifact Type :" + paths.joinToString(separator))\r
103             artifactType.properties?.let { validatePropertyDefinitions(artifactType.properties!!) }\r
104             paths.removeAt(paths.lastIndex)\r
105         }\r
106         paths.removeAt(paths.lastIndex)\r
107     }\r
108 \r
109     @Throws(BluePrintException::class)\r
110     open fun validateDataTypes(dataTypes: MutableMap<String, DataType>) {\r
111         paths.add("dataTypes")\r
112         dataTypes.forEach { dataTypeName, dataType ->\r
113             paths.add(dataTypeName)\r
114             message.appendln("--> DataType :" + paths.joinToString(separator))\r
115             dataType.properties?.let { validatePropertyDefinitions(dataType.properties!!) }\r
116             paths.removeAt(paths.lastIndex)\r
117         }\r
118         paths.removeAt(paths.lastIndex)\r
119     }\r
120 \r
121     @Throws(BluePrintException::class)\r
122     open fun validateNodeTypes(nodeTypes: MutableMap<String, NodeType>) {\r
123         paths.add("nodeTypes")\r
124         nodeTypes.forEach { nodeTypeName, nodeType ->\r
125             // Validate Single Node Type\r
126             validateNodeType(nodeTypeName, nodeType)\r
127         }\r
128         paths.removeAt(paths.lastIndex)\r
129     }\r
130 \r
131     @Throws(BluePrintException::class)\r
132     open fun validateNodeType(nodeTypeName: String, nodeType: NodeType) {\r
133         paths.add(nodeTypeName)\r
134         message.appendln("--> Node Type :" + paths.joinToString(separator))\r
135         val derivedFrom: String = nodeType.derivedFrom\r
136         //Check Derived From\r
137         checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom)\r
138 \r
139         if(!BluePrintTypes.rootNodeTypes().contains(derivedFrom)){\r
140             serviceTemplate.nodeTypes?.get(derivedFrom)\r
141                     ?: throw BluePrintException(format("Failed to get derivedFrom NodeType({})'s for NodeType({}) ",\r
142                             derivedFrom, nodeTypeName))\r
143         }\r
144 \r
145         nodeType.properties?.let { validatePropertyDefinitions(nodeType.properties!!) }\r
146         nodeType.requirements?.let { validateRequirementDefinitions(nodeTypeName, nodeType) }\r
147         nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) }\r
148         paths.removeAt(paths.lastIndex)\r
149     }\r
150 \r
151     @Throws(BluePrintException::class)\r
152     open fun checkValidNodeTypesDerivedFrom(nodeTypeName: String, derivedFrom: String) {\r
153         check(BluePrintTypes.validNodeTypeDerivedFroms.contains(derivedFrom)) {\r
154             throw BluePrintException(format("Failed to get node type ({})'s  derivedFrom({}) definition ", nodeTypeName, derivedFrom))\r
155         }\r
156     }\r
157 \r
158     @Throws(BluePrintException::class)\r
159     open fun validateTopologyTemplate(topologyTemplate: TopologyTemplate) {\r
160         paths.add("topology")\r
161         message.appendln("--> Topology Template")\r
162         topologyTemplate.inputs?.let { validateInputs(topologyTemplate.inputs!!) }\r
163         topologyTemplate.nodeTemplates?.let { validateNodeTemplates(topologyTemplate.nodeTemplates!!) }\r
164         topologyTemplate.workflows?.let { validateWorkFlows(topologyTemplate.workflows!!) }\r
165         paths.removeAt(paths.lastIndex)\r
166     }\r
167 \r
168     @Throws(BluePrintException::class)\r
169     open fun validateInputs(inputs: MutableMap<String, PropertyDefinition>) {\r
170         paths.add("inputs")\r
171         message.appendln("---> Input :" + paths.joinToString(separator))\r
172         validatePropertyDefinitions(inputs)\r
173         paths.removeAt(paths.lastIndex)\r
174     }\r
175 \r
176     @Throws(BluePrintException::class)\r
177     open fun validateNodeTemplates(nodeTemplates: MutableMap<String, NodeTemplate>) {\r
178         paths.add("nodeTemplates")\r
179         nodeTemplates.forEach { nodeTemplateName, nodeTemplate ->\r
180             validateNodeTemplate(nodeTemplateName, nodeTemplate)\r
181         }\r
182         paths.removeAt(paths.lastIndex)\r
183     }\r
184 \r
185     @Throws(BluePrintException::class)\r
186     open fun validateNodeTemplate(nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
187         paths.add(nodeTemplateName)\r
188         message.appendln("---> NodeTemplate :" + paths.joinToString(separator))\r
189         val type: String = nodeTemplate.type\r
190 \r
191         val nodeType: NodeType = serviceTemplate.nodeTypes?.get(type)\r
192                 ?: throw BluePrintException(format("Failed to get NodeType({}) definition for NodeTemplate({})", type, nodeTemplateName))\r
193 \r
194         nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }\r
195         nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }\r
196         nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeTemplate.capabilities!!) }\r
197         nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, nodeTemplateName, nodeTemplate) }\r
198         nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, nodeTemplateName, nodeTemplate) }\r
199         paths.removeAt(paths.lastIndex)\r
200     }\r
201 \r
202     @Throws(BluePrintException::class)\r
203     open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {\r
204         paths.add("artifacts")\r
205         artifacts.forEach { artifactDefinitionName, artifactDefinition ->\r
206             paths.add(artifactDefinitionName)\r
207             message.appendln("Validating artifact " + paths.joinToString(separator))\r
208             val type: String = artifactDefinition.type\r
209                     ?: throw BluePrintException(format("type is missing for ArtifactDefinition({})", artifactDefinitionName))\r
210             // Check Artifact Type\r
211             checkValidArtifactType(artifactDefinitionName, type)\r
212 \r
213             val file: String = artifactDefinition.file\r
214                     ?: throw BluePrintException(format("file is missing for ArtifactDefinition({})", artifactDefinitionName))\r
215 \r
216             paths.removeAt(paths.lastIndex)\r
217         }\r
218         paths.removeAt(paths.lastIndex)\r
219     }\r
220 \r
221     @Throws(BluePrintException::class)\r
222     open fun validateWorkFlows(workflows: MutableMap<String, Workflow>) {\r
223         paths.add("workflows")\r
224         workflows.forEach { workflowName, workflow ->\r
225 \r
226             // Validate Single workflow\r
227             validateWorkFlow(workflowName, workflow)\r
228         }\r
229         paths.removeAt(paths.lastIndex)\r
230     }\r
231 \r
232     @Throws(BluePrintException::class)\r
233     open fun validateWorkFlow(workflowName: String, workflow: Workflow) {\r
234         paths.add(workflowName)\r
235         message.appendln("---> Workflow :" + paths.joinToString(separator))\r
236         // Step Validation Start\r
237         paths.add("steps")\r
238         workflow.steps?.forEach { stepName, step ->\r
239             paths.add(stepName)\r
240             message.appendln("----> Steps :" + paths.joinToString(separator))\r
241             paths.removeAt(paths.lastIndex)\r
242         }\r
243         paths.removeAt(paths.lastIndex)\r
244         // Step Validation Ends\r
245         paths.removeAt(paths.lastIndex)\r
246     }\r
247 \r
248     @Throws(BluePrintException::class)\r
249     open fun validatePropertyDefinitions(properties: MutableMap<String, PropertyDefinition>) {\r
250         paths.add("properties")\r
251         properties.forEach { propertyName, propertyDefinition ->\r
252             paths.add(propertyName)\r
253             val dataType: String = propertyDefinition.type\r
254             when {\r
255                 BluePrintTypes.validPrimitiveTypes().contains(dataType) -> {\r
256                     // Do Nothing\r
257                 }\r
258                 BluePrintTypes.validCollectionTypes().contains(dataType) -> {\r
259                     val entrySchemaType: String = propertyDefinition.entrySchema?.type\r
260                             ?: throw BluePrintException(format("Entry schema for DataType ({}) for the property ({}) not found", dataType, propertyName))\r
261                     checkPrimitiveOrComplex(entrySchemaType, propertyName)\r
262                 }\r
263                 else -> checkPropertyDataType(dataType, propertyName)\r
264             }\r
265             message.appendln("property " + paths.joinToString(separator) + " of type " + dataType)\r
266             paths.removeAt(paths.lastIndex)\r
267         }\r
268         paths.removeAt(paths.lastIndex)\r
269     }\r
270 \r
271     @Throws(BluePrintException::class)\r
272     open fun validatePropertyAssignments(nodeTypeProperties: MutableMap<String, PropertyDefinition>,\r
273                                          properties: MutableMap<String, JsonNode>) {\r
274         properties.forEach { propertyName, propertyAssignment ->\r
275             val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]\r
276                     ?: throw BluePrintException(format("failed to get definition for the property ({})", propertyName))\r
277 \r
278             validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)\r
279 \r
280         }\r
281     }\r
282 \r
283     @Throws(BluePrintException::class)\r
284     open fun validatePropertyAssignment(propertyName: String, propertyDefinition: PropertyDefinition,\r
285                                         propertyAssignment: JsonNode) {\r
286         // Check and Validate if Expression Node\r
287         val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)\r
288         if (!expressionData.isExpression) {\r
289             checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)\r
290         }\r
291     }\r
292 \r
293     @Throws(BluePrintException::class)\r
294     open fun validateCapabilityAssignments(capabilities: MutableMap<String, CapabilityAssignment>) {\r
295 \r
296     }\r
297 \r
298     @Throws(BluePrintException::class)\r
299     open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
300         val requirements = nodeTemplate.requirements\r
301         paths.add("requirements")\r
302         requirements?.forEach { requirementName, requirementAssignment ->\r
303             paths.add(requirementName)\r
304             val requirementDefinition = nodeType.requirements?.get(requirementName)\r
305                     ?: throw BluePrintException(format("Failed to get NodeTemplate({}) requirement definition ({}) from" +\r
306                             " NodeType({}) ", nodeTemplateName, requirementName, nodeTemplate.type))\r
307             // Validate Requirement Assignment\r
308             validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)\r
309             paths.removeAt(paths.lastIndex)\r
310         }\r
311         paths.removeAt(paths.lastIndex)\r
312 \r
313     }\r
314 \r
315     @Throws(BluePrintException::class)\r
316     open fun validateRequirementAssignment(nodeTemplateName: String, requirementAssignmentName: String,\r
317                                            requirementDefinition: RequirementDefinition, requirementAssignment: RequirementAssignment) {\r
318         log.info("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName, requirementAssignmentName)\r
319         val requirementNodeTemplateName = requirementAssignment.node!!\r
320         val capabilityName = requirementAssignment.capability\r
321         val relationship = requirementAssignment.relationship!!\r
322 \r
323         check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {\r
324             throw BluePrintException(format("Failed to get relationship type ({}) for NodeTemplate({})'s requirement({}) ",\r
325                     relationship, nodeTemplateName, requirementAssignmentName))\r
326         }\r
327 \r
328         val relationShipNodeTemplate = serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)\r
329                 ?: throw BluePrintException(format("Failed to get requirement NodeTemplate({})'s for NodeTemplate({}) requirement({}) ",\r
330                         requirementNodeTemplateName, nodeTemplateName, requirementAssignmentName))\r
331 \r
332         relationShipNodeTemplate.capabilities?.get(capabilityName)\r
333                 ?: throw BluePrintException(format("Failed to get requirement NodeTemplate({})'s capability({}) for NodeTemplate ({})'s requirement({}) ",\r
334                         requirementNodeTemplateName, capabilityName, nodeTemplateName, requirementAssignmentName))\r
335 \r
336 \r
337     }\r
338 \r
339     @Throws(BluePrintException::class)\r
340     open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
341 \r
342         val interfaces = nodeTemplate.interfaces\r
343         paths.add("interfaces")\r
344         interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->\r
345             paths.add(interfaceAssignmentName)\r
346             val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)\r
347                     ?: throw BluePrintException(format("Failed to get NodeTemplate({}) interface definition ({}) from" +\r
348                             " NodeType({}) ", nodeTemplateName, interfaceAssignmentName, nodeTemplate.type))\r
349 \r
350             validateInterfaceAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,\r
351                     interfaceAssignment)\r
352             paths.removeAt(paths.lastIndex)\r
353         }\r
354         paths.removeAt(paths.lastIndex)\r
355 \r
356 \r
357     }\r
358 \r
359     @Throws(BluePrintException::class)\r
360     open fun validateInterfaceAssignment(nodeTemplateName: String, interfaceAssignmentName: String,\r
361                                          interfaceDefinition: InterfaceDefinition,\r
362                                          interfaceAssignment: InterfaceAssignment) {\r
363 \r
364         val operations = interfaceAssignment.operations\r
365         operations?.let {\r
366             validateInterfaceOperationsAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,\r
367                     interfaceAssignment)\r
368         }\r
369 \r
370     }\r
371 \r
372     @Throws(BluePrintException::class)\r
373     open fun validateInterfaceOperationsAssignment(nodeTemplateName: String, interfaceAssignmentName: String,\r
374                                                    interfaceDefinition: InterfaceDefinition,\r
375                                                    interfaceAssignment: InterfaceAssignment) {\r
376 \r
377         val operations = interfaceAssignment.operations\r
378         operations?.let {\r
379             it.forEach { operationAssignmentName, operationAssignments ->\r
380 \r
381                 val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)\r
382                         ?: throw BluePrintException(format("Failed to get NodeTemplate({}) operation definition ({}) ",\r
383                                 nodeTemplateName, operationAssignmentName))\r
384 \r
385                 log.info("Validation NodeTemplate({}) Interface({}) Operation ({})", nodeTemplateName,\r
386                         interfaceAssignmentName, operationAssignmentName)\r
387 \r
388                 val inputs = operationAssignments.inputs\r
389                 val outputs = operationAssignments.outputs\r
390 \r
391                 inputs?.forEach { propertyName, propertyAssignment ->\r
392                     val propertyDefinition = operationDefinition.inputs?.get(propertyName)\r
393                             ?: throw BluePrintException(format("Failed to get NodeTemplate({}) operation definition ({}) " +\r
394                                     "property definition({})", nodeTemplateName, operationAssignmentName, propertyName))\r
395                     // Check the property values with property definition\r
396                     validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)\r
397                 }\r
398 \r
399             }\r
400         }\r
401 \r
402     }\r
403 \r
404     @Throws(BluePrintException::class)\r
405     open fun validateRequirementDefinitions(nodeName: String, nodeType: NodeType) {\r
406         paths.add("requirements")\r
407         val requirements = nodeType.requirements\r
408 \r
409         requirements?.forEach { requirementDefinitionName, requirementDefinition ->\r
410             paths.add(requirementDefinitionName)\r
411             message.appendln("Validating : " + paths.joinToString(separator))\r
412             validateRequirementDefinition(nodeName, nodeType, requirementDefinitionName, requirementDefinition)\r
413             paths.removeAt(paths.lastIndex)\r
414         }\r
415         paths.removeAt(paths.lastIndex)\r
416     }\r
417 \r
418     @Throws(BluePrintException::class)\r
419     open fun validateRequirementDefinition(nodeTypeName: String, nodeType: NodeType, requirementDefinitionName: String,\r
420                                            requirementDefinition: RequirementDefinition) {\r
421 \r
422         log.info("Validating NodeType({}) RequirementDefinition ({}) ", nodeTypeName, requirementDefinitionName)\r
423         val requirementNodeTypeName = requirementDefinition.node!!\r
424         val capabilityName = requirementDefinition.capability\r
425         val relationship = requirementDefinition.relationship!!\r
426 \r
427         check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {\r
428             throw BluePrintException(format("Failed to get relationship({}) for NodeType({})'s requirement({}) ",\r
429                     relationship, nodeTypeName, requirementDefinitionName))\r
430         }\r
431 \r
432         val relationShipNodeType = serviceTemplate.nodeTypes?.get(requirementNodeTypeName)\r
433                 ?: throw BluePrintException(format("Failed to get requirement NodeType({})'s for requirement({}) ",\r
434                         requirementNodeTypeName, requirementDefinitionName))\r
435 \r
436         relationShipNodeType.capabilities?.get(capabilityName)\r
437                 ?: throw BluePrintException(format("Failed to get requirement NodeType({})'s capability({}) for NodeType ({})'s requirement({}) ",\r
438                         requirementNodeTypeName, capabilityName, nodeTypeName, requirementDefinitionName))\r
439 \r
440     }\r
441 \r
442 \r
443     @Throws(BluePrintException::class)\r
444     open fun validateInterfaceDefinitions(interfaces: MutableMap<String, InterfaceDefinition>) {\r
445         paths.add("interfaces")\r
446         interfaces.forEach { interfaceName, interfaceDefinition ->\r
447             paths.add(interfaceName)\r
448             message.appendln("Validating : " + paths.joinToString(separator))\r
449             interfaceDefinition.operations?.let { validateOperationDefinitions(interfaceDefinition.operations!!) }\r
450             paths.removeAt(paths.lastIndex)\r
451         }\r
452         paths.removeAt(paths.lastIndex)\r
453     }\r
454 \r
455     @Throws(BluePrintException::class)\r
456     open fun validateOperationDefinitions(operations: MutableMap<String, OperationDefinition>) {\r
457         paths.add("operations")\r
458         operations.forEach { opertaionName, operationDefinition ->\r
459             paths.add(opertaionName)\r
460             message.appendln("Validating : " + paths.joinToString(separator))\r
461             operationDefinition.implementation?.let { validateImplementation(operationDefinition.implementation!!) }\r
462             operationDefinition.inputs?.let { validatePropertyDefinitions(operationDefinition.inputs!!) }\r
463             operationDefinition.outputs?.let { validatePropertyDefinitions(operationDefinition.outputs!!) }\r
464             paths.removeAt(paths.lastIndex)\r
465         }\r
466         paths.removeAt(paths.lastIndex)\r
467     }\r
468 \r
469     @Throws(BluePrintException::class)\r
470     open fun validateImplementation(implementation: Implementation) {\r
471         checkNotEmptyNThrow(implementation.primary)\r
472     }\r
473 \r
474     @Throws(BluePrintException::class)\r
475     open fun checkValidArtifactType(artifactDefinitionName: String, artifactTypeName: String) {\r
476 \r
477         val artifactType = serviceTemplate.artifactTypes?.get(artifactTypeName)\r
478                 ?: throw BluePrintException(format("Failed to ArtifactType for ArtifactDefinition : {}", artifactDefinitionName))\r
479 \r
480         checkValidArtifactTypeDerivedFrom(artifactTypeName, artifactType.derivedFrom)\r
481     }\r
482 \r
483     @Throws(BluePrintException::class)\r
484     open fun checkValidArtifactTypeDerivedFrom(artifactTypeName: String, derivedFrom: String) {\r
485         check(BluePrintTypes.validArtifactTypeDerivedFroms.contains(derivedFrom)) {\r
486             throw BluePrintException(format("Failed to get ArtifactType ({})'s  derivedFrom({}) definition ", artifactTypeName, derivedFrom))\r
487         }\r
488     }\r
489 \r
490     @Throws(BluePrintException::class)\r
491     open fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {\r
492         check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {\r
493             throw BluePrintException(format("Failed to get DataType ({})'s  derivedFrom({}) definition ", dataTypeName, derivedFrom))\r
494         }\r
495     }\r
496 \r
497     @Throws(BluePrintException::class)\r
498     open fun checkValidRelationshipTypeDerivedFrom(relationshipTypeName: String, derivedFrom: String) {\r
499         check(BluePrintTypes.validRelationShipDerivedFroms.contains(derivedFrom)) {\r
500             throw BluePrintException(format("Failed to get relationship type ({})'s  derivedFrom({}) definition ", relationshipTypeName, derivedFrom))\r
501         }\r
502     }\r
503 \r
504     open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) {\r
505         val propertyType = propertyDefinition.type\r
506         val isValid: Boolean\r
507 \r
508         if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {\r
509             isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)\r
510 \r
511         } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {\r
512 \r
513             val entrySchemaType = propertyDefinition.entrySchema?.type\r
514                     ?: throw BluePrintException(format("Failed to get EntrySchema type for the collection property ({})", propertyName))\r
515 \r
516             if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {\r
517                 checkPropertyDataType(entrySchemaType, propertyName)\r
518             }\r
519             isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)\r
520         } else {\r
521             checkPropertyDataType(propertyType, propertyName)\r
522             isValid = true\r
523         }\r
524 \r
525         check(isValid) {\r
526             throw BluePrintException(format("property({}) defined of type({}) is not comptable with the value ({})",\r
527                     propertyName, propertyType, propertyAssignment))\r
528         }\r
529     }\r
530 \r
531     private fun checkPropertyDataType(dataType: String, propertyName: String) {\r
532 \r
533         val dataType = serviceTemplate.dataTypes?.get(dataType)\r
534                 ?: throw BluePrintException(format("DataType ({}) for the property ({}) not found", dataType, propertyName))\r
535 \r
536         checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)\r
537 \r
538     }\r
539 \r
540     private fun checkPrimitiveOrComplex(dataType: String, propertyName: String): Boolean {\r
541         if (BluePrintTypes.validPrimitiveTypes().contains(dataType) || checkDataType(dataType)) {\r
542             return true\r
543         } else {\r
544             throw BluePrintException(format("DataType ({}) for the property ({}) is not valid", dataType))\r
545         }\r
546     }\r
547 \r
548     private fun checkDataType(key: String): Boolean {\r
549         return serviceTemplate.dataTypes?.containsKey(key) ?: false\r
550     }\r
551 \r
552 }