Revert "Renaming Files having BluePrint to have Blueprint"
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / blueprints / blueprint-validation / src / main / kotlin / org / onap / ccsdk / cds / controllerblueprints / validation / utils / PropertyAssignmentValidationUtils.kt
1 /*
2  *  Copyright © 2019 IBM.
3  *  Modifications Copyright © 2019 Bell Canada.
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.utils
19
20 import com.fasterxml.jackson.databind.JsonNode
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.data.PropertyDefinition
24 import org.onap.ccsdk.cds.controllerblueprints.core.format
25 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
26 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintExpressionService
27 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
28
29 open class PropertyAssignmentValidationUtils(private val bluePrintContext: BluePrintContext) {
30
31     // Property Definition holds both Definitons and Expression in same construct
32     open fun validatePropertyDefinitionNAssignments(propertyDefinitions: MutableMap<String, PropertyDefinition>) {
33         propertyDefinitions.forEach { propertyName, propertyDefinition ->
34             validatePropertyDefinitionNAssignment(propertyName, propertyDefinition)
35         }
36     }
37
38     // Property Definition holds both Definitons and Expression in same construct
39     open fun validatePropertyDefinitionNAssignment(propertyName: String, propertyDefinition: PropertyDefinition) {
40         // Check and Validate if Expression Node
41         checkNotNull(propertyDefinition.value) {
42             throw BluePrintException("couldn't get 'value' property from PropertyDefinition($propertyName)")
43         }
44         val propertyAssignment = propertyDefinition.value!!
45         val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)
46         if (!expressionData.isExpression) {
47             checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)
48         }
49     }
50
51     open fun validatePropertyAssignments(
52         nodeTypeProperties: MutableMap<String, PropertyDefinition>,
53         properties: MutableMap<String, JsonNode>
54     ) {
55         properties.forEach { propertyName, propertyAssignment ->
56             val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]
57                 ?: throw BluePrintException("validatePropertyAssignments failed to get definition for the property ($propertyName)")
58
59             validatePropertyAssignment(propertyName, propertyDefinition, propertyAssignment)
60         }
61     }
62
63     open fun validatePropertyAssignment(
64         propertyName: String,
65         propertyDefinition: PropertyDefinition,
66         propertyAssignment: JsonNode
67     ) {
68         // Check and Validate if Expression Node
69         val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)
70         if (!expressionData.isExpression) {
71             checkPropertyValue(propertyName, propertyDefinition, propertyAssignment)
72         }
73     }
74
75     open fun checkPropertyValue(propertyName: String, propertyDefinition: PropertyDefinition, propertyAssignment: JsonNode) {
76         val propertyType = propertyDefinition.type
77         val isValid: Boolean
78
79         if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {
80             isValid = JacksonUtils.checkJsonNodeValueOfPrimitiveType(propertyType, propertyAssignment)
81         } else if (BluePrintTypes.validComplexTypes().contains(propertyType)) {
82             isValid = true
83         } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {
84
85             val entrySchemaType = propertyDefinition.entrySchema?.type
86                 ?: throw BluePrintException(format("Failed to get EntrySchema type for the collection property ({})", propertyName))
87
88             if (!BluePrintTypes.validPropertyTypes().contains(entrySchemaType)) {
89                 checkPropertyDataType(entrySchemaType, propertyName)
90             }
91             isValid = JacksonUtils.checkJsonNodeValueOfCollectionType(propertyType, propertyAssignment)
92         } else {
93             checkPropertyDataType(propertyType, propertyName)
94             isValid = true
95         }
96
97         check(isValid) {
98             throw BluePrintException("property($propertyName) defined of type($propertyType) is not compatible with the value ($propertyAssignment)")
99         }
100     }
101
102     open fun checkPropertyDataType(dataTypeName: String, propertyName: String) {
103
104         val dataType = bluePrintContext.serviceTemplate.dataTypes?.get(dataTypeName)
105             ?: throw BluePrintException("DataType ($dataTypeName) for the property ($propertyName) not found")
106
107         checkValidDataTypeDerivedFrom(propertyName, dataType.derivedFrom)
108     }
109
110     open fun checkValidDataTypeDerivedFrom(dataTypeName: String, derivedFrom: String) {
111         check(BluePrintTypes.validDataTypeDerivedFroms.contains(derivedFrom)) {
112             throw BluePrintException("Failed to get DataType($dataTypeName)'s  derivedFrom($derivedFrom) definition ")
113         }
114     }
115 }