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