2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2018 - 2019 IBM, Bell Canada.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org.onap.ccsdk.cds.controllerblueprints.core.service
20 import com.fasterxml.jackson.databind.JsonNode
21 import com.fasterxml.jackson.databind.node.NullNode
22 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
23 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
24 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
26 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactExpression
27 import org.onap.ccsdk.cds.controllerblueprints.core.data.AttributeDefinition
28 import org.onap.ccsdk.cds.controllerblueprints.core.data.AttributeExpression
29 import org.onap.ccsdk.cds.controllerblueprints.core.data.ExpressionData
30 import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationOutputExpression
31 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
32 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyExpression
33 import org.onap.ccsdk.cds.controllerblueprints.core.format
34 import org.onap.ccsdk.cds.controllerblueprints.core.isComplexType
35 import org.onap.ccsdk.cds.controllerblueprints.core.jsonPathParse
36 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
37 import org.onap.ccsdk.cds.controllerblueprints.core.utils.ResourceResolverUtils
38 import org.slf4j.LoggerFactory
43 * @author Brinda Santh
45 class PropertyAssignmentService(var bluePrintRuntimeService: BluePrintRuntimeService<MutableMap<String, JsonNode>>) {
47 private val log = LoggerFactory.getLogger(this::class.toString())
49 private var bluePrintContext: BluePrintContext = bluePrintRuntimeService.bluePrintContext()
53 If Property Assignment is Expression.
55 Recursively resolve the expression
58 fun resolveAssignmentExpression(
59 nodeTemplateName: String,
60 assignmentName: String,
63 val valueNode: JsonNode
64 log.trace("Assignment ({})", assignment)
65 val expressionData = BluePrintExpressionService.getExpressionData(assignment)
67 if (expressionData.isExpression) {
68 valueNode = resolveExpression(nodeTemplateName, assignmentName, expressionData)
70 valueNode = expressionData.valueNode
75 fun resolveExpression(nodeTemplateName: String, propName: String, expressionData: ExpressionData): JsonNode {
77 var valueNode: JsonNode = NullNode.getInstance()
79 if (expressionData.isExpression) {
80 val command = expressionData.command!!
83 BluePrintConstants.EXPRESSION_GET_INPUT -> {
84 valueNode = bluePrintRuntimeService.getInputValue(expressionData.inputExpression?.propertyName!!)
86 BluePrintConstants.EXPRESSION_GET_ATTRIBUTE -> {
87 valueNode = resolveAttributeExpression(nodeTemplateName, expressionData.attributeExpression!!)
89 BluePrintConstants.EXPRESSION_GET_PROPERTY -> {
90 valueNode = resolvePropertyExpression(nodeTemplateName, expressionData.propertyExpression!!)
92 BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT -> {
93 valueNode = resolveOperationOutputExpression(nodeTemplateName, expressionData.operationOutputExpression!!)
95 BluePrintConstants.EXPRESSION_GET_ARTIFACT -> {
96 valueNode = resolveArtifactExpression(nodeTemplateName, expressionData.artifactExpression!!)
98 BluePrintConstants.EXPRESSION_DSL_REFERENCE -> {
99 valueNode = bluePrintRuntimeService.resolveDSLExpression(expressionData.dslExpression!!.propertyName)
101 BluePrintConstants.EXPRESSION_GET_NODE_OF_TYPE -> {
104 throw BluePrintException(format("for property ({}), command ({}) is not supported ", propName, command))
112 get_attribute: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>,
113 <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ]
115 fun resolveAttributeExpression(nodeTemplateName: String, attributeExpression: AttributeExpression): JsonNode {
116 var valueNode: JsonNode
118 val attributeName = attributeExpression.attributeName
119 val subAttributeName: String? = attributeExpression.subAttributeName
121 var attributeNodeTemplateName = nodeTemplateName
123 * Attributes are dynamic runtime properties information. There are multiple types of Attributes,
124 * ENV : Environment Variables
125 * APP : Application properties ( ie Spring resolved properties )
126 * BPP : Blueprint Properties, Specific to Blue Print execution.
127 * SELF : Current Node Template properties.
129 when (attributeExpression.modelableEntityName) {
130 BluePrintConstants.PROPERTY_ENV -> {
131 val environmentValue = System.getProperty(attributeName)
132 valueNode = environmentValue.asJsonPrimitive()
134 BluePrintConstants.PROPERTY_APP -> {
135 TODO("Get property from application properties")
137 BluePrintConstants.PROPERTY_BPP -> {
138 valueNode = bluePrintRuntimeService.getNodeTemplateAttributeValue(BluePrintConstants.PROPERTY_BPP, attributeName)
139 ?: throw BluePrintException("failed to get env attribute name ($attributeName) ")
142 if (!attributeExpression.modelableEntityName.equals(BluePrintConstants.PROPERTY_SELF, true)) {
143 attributeNodeTemplateName = attributeExpression.modelableEntityName
146 var attributeDefinition: AttributeDefinition = bluePrintContext
147 .nodeTemplateNodeType(attributeNodeTemplateName).attributes?.get(attributeName)
148 ?: throw BluePrintException("failed to get attribute definitions for node template ($attributeNodeTemplateName)'s attribute name ($attributeName) ")
150 valueNode = bluePrintRuntimeService.getNodeTemplateAttributeValue(attributeNodeTemplateName, attributeName)
151 ?: throw BluePrintException("failed to get node template ($attributeNodeTemplateName)'s attribute name ($attributeName) ")
154 if (subAttributeName != null) {
155 if (valueNode.isComplexType())
156 valueNode = valueNode.jsonPathParse(subAttributeName)
162 get_property: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>,
163 <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ]
165 fun resolvePropertyExpression(nodeTemplateName: String, propertyExpression: PropertyExpression): JsonNode {
166 var valueNode: JsonNode
168 val propertyName = propertyExpression.propertyName
169 val subPropertyName: String? = propertyExpression.subPropertyName
171 var propertyNodeTemplateName = nodeTemplateName
173 if (!propertyExpression.modelableEntityName.equals(BluePrintConstants.PROPERTY_SELF, true)) {
174 propertyNodeTemplateName = propertyExpression.modelableEntityName
177 val nodeTemplatePropertyExpression = bluePrintContext.nodeTemplateByName(propertyNodeTemplateName).properties?.get(propertyName)
178 ?: throw BluePrintException(
180 "failed to get property definitions for node template ({})'s property name ({}) ",
186 var propertyDefinition: PropertyDefinition = bluePrintContext.nodeTemplateNodeType(propertyNodeTemplateName).properties?.get(propertyName)!!
189 "node template name ({}), property Name ({}) resolved value ({})",
190 propertyNodeTemplateName,
192 nodeTemplatePropertyExpression
195 // Check it it is a nested expression
196 valueNode = resolveAssignmentExpression(propertyNodeTemplateName, propertyName, nodeTemplatePropertyExpression)
198 if (subPropertyName != null) {
199 if (valueNode.isComplexType())
200 valueNode = valueNode.jsonPathParse(subPropertyName)
206 get_operation_output: <modelable_entity_name>, <interface_name>, <operation_name>, <output_variable_name>
208 fun resolveOperationOutputExpression(nodeTemplateName: String, operationOutputExpression: OperationOutputExpression): JsonNode {
209 var outputNodeTemplateName = nodeTemplateName
210 if (!operationOutputExpression.modelableEntityName.equals("SELF", true)) {
211 outputNodeTemplateName = operationOutputExpression.modelableEntityName
214 var valueNode = bluePrintRuntimeService.getNodeTemplateOperationOutputValue(
215 outputNodeTemplateName,
216 operationOutputExpression.interfaceName, operationOutputExpression.operationName,
217 operationOutputExpression.propertyName
220 val subPropertyName: String? = operationOutputExpression.subPropertyName
221 if (subPropertyName != null) {
222 if (valueNode.isComplexType())
223 valueNode = valueNode.jsonPathParse(subPropertyName)
229 get_artifact: [ <modelable_entity_name>, <artifact_name>, <location>, <remove> ]
231 fun resolveArtifactExpression(nodeTemplateName: String, artifactExpression: ArtifactExpression): JsonNode {
233 var artifactNodeTemplateName = nodeTemplateName
234 if (!artifactExpression.modelableEntityName.equals("SELF", true)) {
235 artifactNodeTemplateName = artifactExpression.modelableEntityName
237 val artifactDefinition: ArtifactDefinition = bluePrintContext.nodeTemplateByName(artifactNodeTemplateName)
238 .artifacts?.get(artifactExpression.artifactName)
239 ?: throw BluePrintException(
241 "failed to get artifact definitions for node template ({})'s " +
242 "artifact name ({}) ", nodeTemplateName, artifactExpression.artifactName
246 return JacksonUtils.jsonNodeFromObject(artifactContent(artifactDefinition))
249 fun artifactContent(artifactDefinition: ArtifactDefinition): String {
250 val bluePrintBasePath: String = bluePrintContext.rootPath
252 if (artifactDefinition.repository != null) {
254 } else if (artifactDefinition.file != null) {
255 return ResourceResolverUtils.getFileContent(artifactDefinition.file, bluePrintBasePath)