Migrate "ms/controllerblueprints" from ccsdk/apps
[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 com.att.eelf.configuration.EELFLogger
21 import com.att.eelf.configuration.EELFManager
22 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
23 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
24 import org.onap.ccsdk.cds.controllerblueprints.core.checkNotEmptyOrThrow
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.*
26 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintNodeTypeValidator
27 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintTypeValidatorService
28 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
29 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
30 import org.springframework.beans.factory.config.ConfigurableBeanFactory
31 import org.springframework.context.annotation.Scope
32 import org.springframework.stereotype.Service
33
34
35 @Service("default-node-type-validator")
36 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
37 open class BluePrintNodeTypeValidatorImpl(private val bluePrintTypeValidatorService: BluePrintTypeValidatorService) : BluePrintNodeTypeValidator {
38
39     private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintServiceTemplateValidatorImpl::class.toString())
40
41     lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
42     lateinit var bluePrintContext: BluePrintContext
43     var paths: MutableList<String> = arrayListOf()
44
45     override fun validate(bluePrintRuntimeService: BluePrintRuntimeService<*>, nodeTypeName: String, nodeType: NodeType) {
46         log.trace("Validating NodeType($nodeTypeName)")
47         this.bluePrintRuntimeService = bluePrintRuntimeService
48         this.bluePrintContext = bluePrintRuntimeService.bluePrintContext()
49
50         paths.add(nodeTypeName)
51
52         val derivedFrom: String = nodeType.derivedFrom
53         //Check Derived From
54         checkValidNodeTypesDerivedFrom(nodeTypeName, derivedFrom)
55
56         if (!BluePrintTypes.rootNodeTypes().contains(derivedFrom)) {
57             bluePrintContext.serviceTemplate.nodeTypes?.get(derivedFrom)
58                     ?: throw BluePrintException("Failed to get derivedFrom NodeType($derivedFrom)'s for NodeType($nodeTypeName)")
59         }
60
61         nodeType.attributes?.let {
62             bluePrintTypeValidatorService.validateAttributeDefinitions(bluePrintRuntimeService, nodeType.attributes!!)
63         }
64
65         nodeType.properties?.let {
66             bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, nodeType.properties!!)
67         }
68
69         nodeType.capabilities?.let { validateCapabilityDefinitions(nodeTypeName, nodeType) }
70         nodeType.requirements?.let { validateRequirementDefinitions(nodeTypeName, nodeType) }
71         nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) }
72
73         paths.removeAt(paths.lastIndex)
74     }
75
76     fun checkValidNodeTypesDerivedFrom(nodeTypeName: String, derivedFrom: String) {
77         check(BluePrintTypes.validNodeTypeDerivedFroms.contains(derivedFrom)) {
78             throw BluePrintException("Failed to get node type ($nodeTypeName)'s  derivedFrom($derivedFrom) definition ")
79         }
80     }
81
82     open fun validateCapabilityDefinitions(nodeTypeName: String, nodeType: NodeType) {
83         val capabilities = nodeType.capabilities
84         paths.add("capabilities")
85         capabilities?.forEach { capabilityName, capabilityDefinition ->
86             paths.add(capabilityName)
87
88             validateCapabilityDefinition(nodeTypeName, nodeType, capabilityName, capabilityDefinition)
89
90             paths.removeAt(paths.lastIndex)
91         }
92         paths.removeAt(paths.lastIndex)
93     }
94
95     open fun validateCapabilityDefinition(nodeTypeName: String, nodeType: NodeType, capabilityName: String,
96                                           capabilityDefinition: CapabilityDefinition) {
97         val capabilityType = capabilityDefinition.type
98         check(BluePrintTypes.validCapabilityTypes.contains(capabilityType)) {
99             throw BluePrintException("failed to get CapabilityType($capabilityType) for NodeType($nodeTypeName)")
100         }
101     }
102
103     open fun validateRequirementDefinitions(nodeName: String, nodeType: NodeType) {
104         paths.add("requirements")
105         val requirements = nodeType.requirements
106
107         requirements?.forEach { requirementDefinitionName, requirementDefinition ->
108             paths.add(requirementDefinitionName)
109             validateRequirementDefinition(nodeName, nodeType, requirementDefinitionName, requirementDefinition)
110             paths.removeAt(paths.lastIndex)
111         }
112         paths.removeAt(paths.lastIndex)
113     }
114
115     open fun validateRequirementDefinition(nodeTypeName: String, nodeType: NodeType, requirementDefinitionName: String,
116                                            requirementDefinition: RequirementDefinition) {
117
118         log.info("validating NodeType({}) RequirementDefinition ({}) ", nodeTypeName, requirementDefinitionName)
119         val requirementNodeTypeName = requirementDefinition.node!!
120         val capabilityName = requirementDefinition.capability
121         val relationship = requirementDefinition.relationship!!
122
123         check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
124             throw BluePrintException("failed to get relationship($relationship) for NodeType($nodeTypeName)'s requirement($requirementDefinitionName)")
125         }
126
127         val relationShipNodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(requirementNodeTypeName)
128                 ?: throw BluePrintException("failed to get requirement NodeType($requirementNodeTypeName)'s for requirement($requirementDefinitionName) ")
129
130         relationShipNodeType.capabilities?.get(capabilityName)
131                 ?: throw BluePrintException("failed to get requirement NodeType($requirementNodeTypeName)'s " +
132                         "capability($nodeTypeName) for NodeType ($capabilityName)'s requirement($requirementDefinitionName) ")
133
134     }
135
136     open fun validateInterfaceDefinitions(interfaces: MutableMap<String, InterfaceDefinition>) {
137         paths.add("interfaces")
138         interfaces.forEach { interfaceName, interfaceDefinition ->
139             paths.add(interfaceName)
140             interfaceDefinition.operations?.let { validateOperationDefinitions(interfaceDefinition.operations!!) }
141             paths.removeAt(paths.lastIndex)
142         }
143         paths.removeAt(paths.lastIndex)
144     }
145
146     open fun validateOperationDefinitions(operations: MutableMap<String, OperationDefinition>) {
147         paths.add("operations")
148         operations.forEach { opertaionName, operationDefinition ->
149             paths.add(opertaionName)
150             operationDefinition.implementation?.let { validateImplementation(operationDefinition.implementation!!) }
151
152             operationDefinition.inputs?.let {
153                 bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, operationDefinition.inputs!!)
154             }
155
156             operationDefinition.outputs?.let {
157                 bluePrintTypeValidatorService.validatePropertyDefinitions(bluePrintRuntimeService, operationDefinition.outputs!!)
158             }
159             paths.removeAt(paths.lastIndex)
160         }
161         paths.removeAt(paths.lastIndex)
162     }
163
164     open fun validateImplementation(implementation: Implementation) {
165         checkNotEmptyOrThrow(implementation.primary)
166     }
167
168 }