2485abdb5fb9837d718ff1f706d433f3e2418e31
[ccsdk/cds.git] /
1 /*\r
2  * Copyright © 2017-2018 AT&T Intellectual Property.\r
3  * Modifications Copyright © 2018 IBM.\r
4  *\r
5  * Licensed under the Apache License, Version 2.0 (the "License");\r
6  * you may not use this file except in compliance with the License.\r
7  * You may obtain a copy of the License at\r
8  *\r
9  *     http://www.apache.org/licenses/LICENSE-2.0\r
10  *\r
11  * Unless required by applicable law or agreed to in writing, software\r
12  * distributed under the License is distributed on an "AS IS" BASIS,\r
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14  * See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  */\r
17 \r
18 package org.onap.ccsdk.apps.controllerblueprints.core.service\r
19 \r
20 \r
21 import com.fasterxml.jackson.databind.JsonNode\r
22 import com.fasterxml.jackson.databind.node.NullNode\r
23 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
25 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException\r
26 import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactDefinition\r
27 import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate\r
28 import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition\r
29 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
30 import com.att.eelf.configuration.EELFLogger\r
31 import com.att.eelf.configuration.EELFManager\r
32 import com.fasterxml.jackson.databind.node.ObjectNode\r
33 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper\r
34 \r
35 /**\r
36  *\r
37  *\r
38  * @author Brinda Santh\r
39  */\r
40 open class BluePrintRuntimeService(var bluePrintContext: BluePrintContext, var context: MutableMap<String, Any> = hashMapOf()) {\r
41 \r
42     private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintRuntimeService::class.toString())\r
43 \r
44     /*\r
45         Get the Node Type Definition for the Node Template, Then iterate Node Type Properties and resolve the expressing\r
46      */\r
47     open fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, Any?> {\r
48         log.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)\r
49         val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
50 \r
51         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
52 \r
53         val propertyAssignments: MutableMap<String, Any?> =\r
54                 nodeTemplate.properties as MutableMap<String, Any?>\r
55 \r
56         // Get the Node Type Definitions\r
57         val nodeTypeProperties: MutableMap<String, PropertyDefinition> =\r
58                 bluePrintContext.nodeTypeChainedProperties(nodeTemplate.type)!!\r
59 \r
60         // Iterate Node Type Properties\r
61         nodeTypeProperties.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
62             // Get the Express or Value for the Node Template\r
63             val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
64 \r
65             var resolvedValue: JsonNode = NullNode.getInstance()\r
66             if (propertyAssignment != null) {\r
67                 // Resolve the Expressing\r
68                 val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
69                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
70             } else {\r
71                 // Assign default value to the Operation\r
72                 nodeTypeProperty.defaultValue?.let { defaultValue ->\r
73                     resolvedValue = defaultValue\r
74                 }\r
75             }\r
76             // Set for Return of method\r
77             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
78         }\r
79         log.info("resolved property definition for node template ({}), values ({})", nodeTemplateName, propertyAssignmentValue)\r
80         return propertyAssignmentValue\r
81     }\r
82 \r
83     open fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,\r
84                                                          interfaceName: String, operationName: String): MutableMap<String, Any?> {\r
85         log.info("resolveNodeTemplateInterfaceOperationInputs for node template ({}),interface name ({}), " +\r
86                 "operationName({})", nodeTemplateName, interfaceName, operationName)\r
87 \r
88         val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
89 \r
90         val propertyAssignments: MutableMap<String, Any> =\r
91                 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName) as? MutableMap<String, Any>\r
92                         ?: throw BluePrintException(String.format("failed to get input definitions for node template (%s), " +\r
93                                 "interface name (%s), operationName(%s)", nodeTemplateName, interfaceName, operationName))\r
94 \r
95         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
96 \r
97         val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =\r
98                 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)\r
99                         ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
100                                 "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
101 \r
102         log.info("input definition for node template ({}), values ({})", nodeTemplateName, propertyAssignments)\r
103 \r
104         // Iterate Node Type Properties\r
105         nodeTypeInterfaceOperationInputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
106             // Get the Express or Value for the Node Template\r
107             val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
108 \r
109             var resolvedValue: JsonNode = NullNode.getInstance()\r
110             if (propertyAssignment != null) {\r
111                 // Resolve the Expressing\r
112                 val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
113                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
114             } else {\r
115                 // Assign default value to the Operation\r
116                 nodeTypeProperty.defaultValue?.let {\r
117                     resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
118                 }\r
119             }\r
120             // Set for Return of method\r
121             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
122         }\r
123         log.trace("resolved input assignments for node template ({}), values ({})", nodeTemplateName,\r
124                 propertyAssignmentValue)\r
125 \r
126         return propertyAssignmentValue\r
127     }\r
128 \r
129 \r
130     open fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,\r
131                                                           interfaceName: String, operationName: String): MutableMap<String, Any?>  {\r
132         log.info("resolveNodeTemplateInterfaceOperationOutputs for node template ({}),interface name ({}), " +\r
133                 "operationName({})", nodeTemplateName, interfaceName, operationName)\r
134 \r
135         val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
136 \r
137         val propertyAssignments: MutableMap<String, Any> =\r
138                 bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName) as? MutableMap<String, Any>\r
139                         ?: throw BluePrintException(String.format("failed to get output definitions for node template (%s), " +\r
140                                 "interface name (%s), operationName(%s)", nodeTemplateName, interfaceName, operationName))\r
141 \r
142         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
143 \r
144         val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =\r
145                 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)\r
146                         ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
147                                 "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
148 \r
149         // Iterate Node Type Properties\r
150         nodeTypeInterfaceOperationOutputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
151 \r
152             // Get the Express or Value for the Node Template\r
153             val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
154 \r
155             var resolvedValue: JsonNode = NullNode.getInstance()\r
156             if (propertyAssignment != null) {\r
157                 // Resolve the Expressing\r
158                 val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
159                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
160             } else {\r
161                 // Assign default value to the Operation\r
162                 nodeTypeProperty.defaultValue?.let {\r
163                     resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
164                 }\r
165             }\r
166             // Set for Return of method\r
167             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
168 \r
169             // Store  operation output values into context\r
170             setNodeTemplateOperationOutputValue(nodeTemplateName, interfaceName, operationName, nodeTypePropertyName, resolvedValue)\r
171             log.trace("resolved output assignments for node template ({}), property name ({}), value ({})", nodeTemplateName, nodeTypePropertyName, resolvedValue)\r
172         }\r
173         return propertyAssignmentValue\r
174     }\r
175 \r
176     open fun resolveNodeTemplateArtifact(nodeTemplateName: String,\r
177                                          artifactName: String): String {\r
178         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
179 \r
180         val artifactDefinition: ArtifactDefinition = nodeTemplate.artifacts?.get(artifactName)\r
181                 ?: throw BluePrintProcessorException(String.format("failed to get artifat definition {} from the node template"\r
182                         , artifactName))\r
183         val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
184         return propertyAssignmentExpression.artifactContent(artifactDefinition)\r
185     }\r
186 \r
187 \r
188     open fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {\r
189         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)\r
190                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
191         log.trace("setting input path ({}), values ({})", path, value)\r
192         context[path] = value\r
193     }\r
194 \r
195     open fun setWorkflowInputValue(workflowName: String, propertyName: String, value: JsonNode) {\r
196         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS).append(BluePrintConstants.PATH_DIVIDER).append(workflowName)\r
197                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)\r
198                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
199                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
200         context[path] = value\r
201     }\r
202 \r
203     open fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {\r
204 \r
205         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
206                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
207                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
208         context[path] = value\r
209     }\r
210 \r
211     open fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {\r
212 \r
213         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
214                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)\r
215                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()\r
216         context[path] = value\r
217     }\r
218 \r
219     open fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
220                                                    value: JsonNode) {\r
221         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
222                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES).append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
223                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS).append(BluePrintConstants.PATH_DIVIDER).append(operationName)\r
224                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
225                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
226         log.trace("setting operation property path ({}), values ({})", path, value)\r
227         context[path] = value\r
228     }\r
229 \r
230     open fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
231                                                 value: JsonNode) {\r
232         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
233                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES).append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
234                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS).append(BluePrintConstants.PATH_DIVIDER).append(operationName)\r
235                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)\r
236                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
237                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
238         context[path] = value\r
239     }\r
240 \r
241     open fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
242                                                  value: JsonNode) {\r
243         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
244                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES).append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
245                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS).append(BluePrintConstants.PATH_DIVIDER).append(operationName)\r
246                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)\r
247                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
248                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
249         context[path] = value\r
250     }\r
251 \r
252 \r
253     open fun getInputValue(propertyName: String): JsonNode {\r
254         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)\r
255                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
256         return context[path] as? JsonNode ?: NullNode.instance\r
257     }\r
258 \r
259     open fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String): JsonNode {\r
260         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
261                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES).append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
262                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS).append(BluePrintConstants.PATH_DIVIDER).append(operationName)\r
263                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS).append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
264                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
265         return context[path] as JsonNode\r
266     }\r
267 \r
268     open fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode? {\r
269         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
270                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
271                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
272         return context[path] as JsonNode\r
273     }\r
274 \r
275     open fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode? {\r
276         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
277                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)\r
278                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()\r
279         return context[path] as JsonNode\r
280     }\r
281 \r
282     open fun getNodeTemplateRequirementPropertyValue(nodeTemplateName: String, requirementName: String, propertyName:\r
283     String): JsonNode? {\r
284         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
285                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_REQUIREMENTS).append(requirementName)\r
286                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
287                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
288         return context[path] as JsonNode\r
289     }\r
290 \r
291     open fun getNodeTemplateCapabilityPropertyValue(nodeTemplateName: String, capabilityName: String, propertyName:\r
292     String): JsonNode? {\r
293         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
294                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_CAPABILITIES).append(capabilityName)\r
295                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)\r
296                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
297         return context[path] as JsonNode\r
298     }\r
299 \r
300     open fun assignInputs(jsonNode: JsonNode) {\r
301         log.info("assignInputs from input JSON ({})", jsonNode.toString())\r
302         bluePrintContext.inputs?.forEach { propertyName, property ->\r
303             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)\r
304                     ?: NullNode.getInstance()\r
305             setInputValue(propertyName, property, valueNode)\r
306         }\r
307     }\r
308 \r
309     open fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {\r
310         log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())\r
311         bluePrintContext.workflowByName(workflowName)?.inputs?.forEach { propertyName, _ ->\r
312             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)\r
313                     ?: NullNode.getInstance()\r
314             setWorkflowInputValue(workflowName, propertyName, valueNode)\r
315         }\r
316     }\r
317 \r
318     open fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {\r
319 \r
320         val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()\r
321         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES).append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
322                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)\r
323                 .append(BluePrintConstants.PATH_DIVIDER).toString()\r
324         context.keys.filter {\r
325             it.startsWith(path)\r
326         }.map {\r
327             val key = it.replace(path, "")\r
328             if (keys.contains(key)) {\r
329                 val value = context[it] as JsonNode\r
330                 jsonNode.set(key, value)\r
331             }\r
332         }\r
333         return jsonNode\r
334     }\r
335 \r
336 \r
337 }