dbcd879aee4ea5d809cbab069fe866caf3612506
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2018-2019 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.data.*
25 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintNodeTemplateValidator
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.onap.ccsdk.cds.controllerblueprints.validation.utils.PropertyAssignmentValidationUtils
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-template-validator")
36 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
37 open class BluePrintNodeTemplateValidatorImpl(private val bluePrintTypeValidatorService: BluePrintTypeValidatorService) : BluePrintNodeTemplateValidator {
38
39     private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintNodeTemplateValidatorImpl::class.toString())
40
41     lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
42     lateinit var bluePrintContext: BluePrintContext
43     lateinit var propertyAssignmentValidationUtils: PropertyAssignmentValidationUtils
44     var paths: MutableList<String> = arrayListOf()
45
46     override fun validate(bluePrintRuntimeService: BluePrintRuntimeService<*>, name: String, nodeTemplate: NodeTemplate) {
47         log.debug("Validating NodeTemplate($name)")
48
49         this.bluePrintRuntimeService = bluePrintRuntimeService
50         this.bluePrintContext = bluePrintRuntimeService.bluePrintContext()
51
52         propertyAssignmentValidationUtils = PropertyAssignmentValidationUtils(bluePrintContext)
53
54         paths.add(name)
55
56         val type: String = nodeTemplate.type
57
58         val nodeType: NodeType = bluePrintContext.serviceTemplate.nodeTypes?.get(type)
59                 ?: throw BluePrintException("Failed to get NodeType($type) definition for NodeTemplate($name)")
60
61         nodeTemplate.properties?.let {
62             propertyAssignmentValidationUtils
63                     .validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!)
64         }
65         nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeType, name, nodeTemplate) }
66         nodeTemplate.requirements?.let { validateRequirementAssignments(nodeType, name, nodeTemplate) }
67         nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeType, name, nodeTemplate) }
68         nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }
69
70         // Perform Extension Validation
71         validateExtension("$type-node-template-validator", name, nodeTemplate)
72
73         paths.removeAt(paths.lastIndex)
74     }
75
76     @Throws(BluePrintException::class)
77     open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {
78         paths.add("artifacts")
79         artifacts.forEach { artifactDefinitionName, artifactDefinition ->
80             bluePrintTypeValidatorService.validateArtifactDefinition(bluePrintRuntimeService,
81                     artifactDefinitionName, artifactDefinition)
82         }
83         paths.removeAt(paths.lastIndex)
84     }
85
86     @Throws(BluePrintException::class)
87     open fun validateCapabilityAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
88         val capabilities = nodeTemplate.capabilities
89         paths.add("capabilities")
90         capabilities?.forEach { capabilityName, capabilityAssignment ->
91             paths.add(capabilityName)
92
93             val capabilityDefinition = nodeType.capabilities?.get(capabilityName)
94                     ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) capability definition ($capabilityName) " +
95                             "from NodeType(${nodeTemplate.type})")
96
97             validateCapabilityAssignment(nodeTemplateName, capabilityName, capabilityDefinition, capabilityAssignment)
98
99             paths.removeAt(paths.lastIndex)
100         }
101         paths.removeAt(paths.lastIndex)
102     }
103
104     @Throws(BluePrintException::class)
105     open fun validateCapabilityAssignment(nodeTemplateName: String, capabilityName: String,
106                                           capabilityDefinition: CapabilityDefinition, capabilityAssignment: CapabilityAssignment) {
107
108         capabilityAssignment.properties?.let {
109             propertyAssignmentValidationUtils
110                     .validatePropertyAssignments(capabilityDefinition.properties!!, capabilityAssignment.properties!!)
111         }
112
113     }
114
115     @Throws(BluePrintException::class)
116     open fun validateRequirementAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
117         val requirements = nodeTemplate.requirements
118         paths.add("requirements")
119         requirements?.forEach { requirementName, requirementAssignment ->
120             paths.add(requirementName)
121             val requirementDefinition = nodeType.requirements?.get(requirementName)
122                     ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) requirement definition ($requirementName) from" +
123                             " NodeType(${nodeTemplate.type})")
124             // Validate Requirement Assignment
125             validateRequirementAssignment(nodeTemplateName, requirementName, requirementDefinition, requirementAssignment)
126             paths.removeAt(paths.lastIndex)
127         }
128         paths.removeAt(paths.lastIndex)
129
130     }
131
132     @Throws(BluePrintException::class)
133     open fun validateRequirementAssignment(nodeTemplateName: String, requirementAssignmentName: String,
134                                            requirementDefinition: RequirementDefinition, requirementAssignment: RequirementAssignment) {
135         log.debug("Validating NodeTemplate({}) requirement assignment ({}) ", nodeTemplateName,
136                 requirementAssignmentName)
137         val requirementNodeTemplateName = requirementAssignment.node!!
138         val capabilityName = requirementAssignment.capability
139         val relationship = requirementAssignment.relationship!!
140
141         check(BluePrintTypes.validRelationShipDerivedFroms.contains(relationship)) {
142             throw BluePrintException("Failed to get relationship type ($relationship) for NodeTemplate($nodeTemplateName)'s requirement($requirementAssignmentName)")
143         }
144
145         val relationShipNodeTemplate = bluePrintContext.serviceTemplate.topologyTemplate?.nodeTemplates?.get(requirementNodeTemplateName)
146                 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
147                         "for NodeTemplate($nodeTemplateName) requirement($requirementAssignmentName)")
148
149         relationShipNodeTemplate.capabilities?.get(capabilityName)
150                 ?: throw BluePrintException("Failed to get requirement NodeTemplate($requirementNodeTemplateName)'s " +
151                         "capability($capabilityName) for NodeTemplate ($nodeTemplateName)'s requirement($requirementAssignmentName)")
152
153
154     }
155
156     @Throws(BluePrintException::class)
157     open fun validateInterfaceAssignments(nodeType: NodeType, nodeTemplateName: String, nodeTemplate: NodeTemplate) {
158
159         val interfaces = nodeTemplate.interfaces
160         paths.add("interfaces")
161         interfaces?.forEach { interfaceAssignmentName, interfaceAssignment ->
162             paths.add(interfaceAssignmentName)
163             val interfaceDefinition = nodeType.interfaces?.get(interfaceAssignmentName)
164                     ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) interface definition ($interfaceAssignmentName) from" +
165                             " NodeType(${nodeTemplate.type})")
166
167             validateInterfaceAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
168                     interfaceAssignment)
169             paths.removeAt(paths.lastIndex)
170         }
171         paths.removeAt(paths.lastIndex)
172
173
174     }
175
176     @Throws(BluePrintException::class)
177     open fun validateInterfaceAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
178                                          interfaceDefinition: InterfaceDefinition,
179                                          interfaceAssignment: InterfaceAssignment) {
180
181         val operations = interfaceAssignment.operations
182         operations?.let {
183             validateInterfaceOperationsAssignment(nodeTemplateName, interfaceAssignmentName, interfaceDefinition,
184                     interfaceAssignment)
185         }
186
187     }
188
189     @Throws(BluePrintException::class)
190     open fun validateInterfaceOperationsAssignment(nodeTemplateName: String, interfaceAssignmentName: String,
191                                                    interfaceDefinition: InterfaceDefinition,
192                                                    interfaceAssignment: InterfaceAssignment) {
193
194         val operations = interfaceAssignment.operations
195         operations?.let {
196             it.forEach { operationAssignmentName, operationAssignments ->
197
198                 val operationDefinition = interfaceDefinition.operations?.get(operationAssignmentName)
199                         ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName)")
200
201                 log.debug("Validation NodeTemplate($nodeTemplateName) Interface($interfaceAssignmentName) Operation " +
202                         "($operationAssignmentName)")
203
204                 val inputs = operationAssignments.inputs
205                 val outputs = operationAssignments.outputs
206
207                 inputs?.forEach { propertyName, propertyAssignment ->
208                     val propertyDefinition = operationDefinition.inputs?.get(propertyName)
209                             ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation " +
210                                     "definition ($operationAssignmentName) property definition($propertyName)")
211                     // Check the property values with property definition
212                     propertyAssignmentValidationUtils
213                             .validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
214                 }
215
216                 outputs?.forEach { propertyName, propertyAssignment ->
217                     val propertyDefinition = operationDefinition.outputs?.get(propertyName)
218                             ?: throw BluePrintException("Failed to get NodeTemplate($nodeTemplateName) operation definition ($operationAssignmentName) " +
219                                     "output property definition($propertyName)")
220                     // Check the property values with property definition
221                     propertyAssignmentValidationUtils
222                             .validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
223                 }
224
225             }
226         }
227
228     }
229
230
231     private fun validateExtension(referencePrefix: String, name: String, nodeTemplate: NodeTemplate) {
232         val customValidator = bluePrintTypeValidatorService
233                 .bluePrintValidator(referencePrefix, BluePrintNodeTemplateValidator::class.java)
234
235         customValidator?.let {
236             it.validate(bluePrintRuntimeService, name, nodeTemplate)
237         }
238     }
239
240 }