3d3122c6149108f928e069b3ab2f53256f925dd6
[ccsdk/cds.git] / ms / controllerblueprints / modules / blueprint-validation / src / main / kotlin / org / onap / ccsdk / cds / controllerblueprints / validation / BluePrintNodeTypeValidatorImpl.kt
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2018 IBM.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.onap.ccsdk.cds.controllerblueprints.validation
19
20 import org.slf4j.LoggerFactory
21 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
22 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
23 import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmpty
24 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
25 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintNodeTypeValidator
26 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintTypeValidatorService
27 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
28 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
29 import org.springframework.beans.factory.config.ConfigurableBeanFactory
30 import org.springframework.context.annotation.Scope
31 import org.springframework.stereotype.Service
32
33
34 @Service("default-node-type-validator")
35 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
36 open class BluePrintNodeTypeValidatorImpl(private val bluePrintTypeValidatorService: BluePrintTypeValidatorService) : BluePrintNodeTypeValidator {
37
38     private val log = LoggerFactory.getLogger(BluePrintServiceTemplateValidatorImpl::class.toString())
39
40     lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
41     lateinit var bluePrintContext: BluePrintContext
42     var paths: MutableList<String> = arrayListOf()
43
44     override fun validate(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTypeName: String, nodeType: NodeType) {
45         log.trace("Validating NodeType($nodeTypeName)")
46         this.bluePrintRuntimeService = bluePrintRuntimeService
47         this.bluePrintContext = bluePrintRuntimeService.bluePrintContext()
48
49         paths.add(nodeTypeName)
50
51         val derivedFrom: String = nodeType.derivedFrom
52         //Check Derived From
53         checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom)
54
55         if (!BluePrintTypes.rootNodeTypes().contains(derivedFrom)) {
56             bluePrintContext.serviceTemplate.nodeTypes?.get(derivedFrom)
57                     ?: throw BluePrintException("Failed to get derivedFrom NodeType($derivedFrom)'s for NodeType($nodeTypeName)")
58         }
59
60         nodeType.attributes?.let {
61             bluePrintTypeValidatorService.validateAttributeDefinitions(bluePrintRuntimeService, nodeType.attributes!!)
62         }
63
64         nodeType.properties?.let {
65             bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, nodeType.properties!!)
66         }
67
68         nodeType.capabilities?.let { validateCapabilityDefinitions(nodeTypeName, nodeType) }
69         nodeType.requirements?.let { validateRequirementDefinitions(nodeTypeName, nodeType) }
70         nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) }
71
72         paths.removeAt(paths.lastIndex)
73     }
74
75     fun checkValidNodeTypesDerivedFrom(nodeTypeName: String, derivedFrom: String) {
76         check(BluePrintTypes.validNodeTypeDerivedFroms.contains(derivedFrom)) {
77             throw BluePrintException("Failed to get node type ($nodeTypeName)'s  derivedFrom($derivedFrom) definition ")
78         }
79     }
80
81     open fun validateCapabilityDefinitions(nodeTypeName: String, nodeType: NodeType) {
82         val capabilities = nodeType.capabilities
83         paths.add("capabilities")
84         capabilities?.forEach { capabilityName, capabilityDefinition ->
85             paths.add(capabilityName)
86
87             validateCapabilityDefinition(nodeTypeName, nodeType, capabilityName, capabilityDefinition)
88
89             paths.removeAt(paths.lastIndex)
90         }
91         paths.removeAt(paths.lastIndex)
92     }
93
94     open fun validateCapabilityDefinition(nodeTypeName: String, nodeType: NodeType, capabilityName: String,
95                                           capabilityDefinition: CapabilityDefinition) {
96         val capabilityType = capabilityDefinition.type
97         check(BluePrintTypes.validCapabilityTypes.contains(capabilityType)) {
98             throw BluePrintException("failed to get CapabilityType($capabilityType) for NodeType($nodeTypeName)")
99         }
100     }
101
102     open fun validateRequirementDefinitions(nodeName: String, nodeType: NodeType) {
103         paths.add("requirements")
104         val requirements = nodeType.requirements
105
106         requirements?.forEach { requirementDefinitionName, requirementDefinition ->
107             paths.add(requirementDefinitionName)
108             validateRequirementDefinition(nodeName, nodeType, requirementDefinitionName, requirementDefinition)
109             paths.removeAt(paths.lastIndex)
110         }
111         paths.removeAt(paths.lastIndex)
112     }
113
114     open fun validateRequirementDefinition(nodeTypeName: String, nodeType: NodeType, requirementDefinitionName: String,
115                                            requirementDefinition: RequirementDefinition) {
116
117         log.info("validating NodeType({}) RequirementDefinition ({}) ", nodeTypeName, requirementDefinitionName)
118         val requirementNodeTypeName = requirementDefinition.node!!
119         val capabilityName = requirementDefinition.capability
120         val relationship = requirementDefinition.relationship!!
121
122         check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
123             throw BluePrintException("failed to get relationship($relationship) for NodeType($nodeTypeName)'s requirement($requirementDefinitionName)")
124         }
125
126         val relationShipNodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(requirementNodeTypeName)
127                 ?: throw BluePrintException("failed to get requirement NodeType($requirementNodeTypeName)'s for requirement($requirementDefinitionName) ")
128
129         relationShipNodeType.capabilities?.get(capabilityName)
130                 ?: throw BluePrintException("failed to get requirement NodeType($requirementNodeTypeName)'s " +
131                         "capability($nodeTypeName) for NodeType ($capabilityName)'s requirement($requirementDefinitionName) ")
132
133     }
134
135     open fun validateInterfaceDefinitions(interfaces: MutableMap<String, InterfaceDefinition>) {
136         paths.add("interfaces")
137         interfaces.forEach { interfaceName, interfaceDefinition ->
138             paths.add(interfaceName)
139             interfaceDefinition.operations?.let { validateOperationDefinitions(interfaceDefinition.operations!!) }
140             paths.removeAt(paths.lastIndex)
141         }
142         paths.removeAt(paths.lastIndex)
143     }
144
145     open fun validateOperationDefinitions(operations: MutableMap<String, OperationDefinition>) {
146         paths.add("operations")
147         operations.forEach { opertaionName, operationDefinition ->
148             paths.add(opertaionName)
149             operationDefinition.implementation?.let { validateImplementation(operationDefinition.implementation!!) }
150
151             operationDefinition.inputs?.let {
152                 bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, operationDefinition.inputs!!)
153             }
154
155             operationDefinition.outputs?.let {
156                 bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, operationDefinition.outputs!!)
157             }
158             paths.removeAt(paths.lastIndex)
159         }
160         paths.removeAt(paths.lastIndex)
161     }
162
163     open fun validateImplementation(implementation: Implementation) {
164         checkNotEmpty(implementation.primary) { "couldn't get implementation" }
165     }
166
167 }