08152313b6d7958cbecedb594d41a73c50b85b07
[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.BluePrintException\r
24 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException\r
25 import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactDefinition\r
26 import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate\r
27 import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition\r
28 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
29 import org.slf4j.Logger\r
30 import org.slf4j.LoggerFactory\r
31 /**\r
32  *\r
33  *\r
34  * @author Brinda Santh\r
35  */\r
36 class BluePrintRuntimeService(var bluePrintContext: BluePrintContext, var context: MutableMap<String, Any> = hashMapOf()) {\r
37 \r
38     private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
39 \r
40     /*\r
41         Get the Node Type Definition for the Node Template, Then iterate Node Type Properties and resolve the expressing\r
42      */\r
43     fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, Any?> {\r
44         logger.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)\r
45         val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
46 \r
47         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
48 \r
49         val propertyAssignments: MutableMap<String, Any?> =\r
50                 nodeTemplate.properties as MutableMap<String, Any?>\r
51 \r
52         // Get the Node Type Definitions\r
53         val nodeTypeProperties: MutableMap<String, PropertyDefinition> =\r
54                 bluePrintContext.nodeTypeChainedProperties(nodeTemplate.type)!!\r
55 \r
56         // Iterate Node Type Properties\r
57         nodeTypeProperties.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
58             // Get the Express or Value for the Node Template\r
59             val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
60 \r
61             var resolvedValue: JsonNode = NullNode.getInstance()\r
62             if (propertyAssignment != null) {\r
63                 // Resolve the Expressing\r
64                 val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
65                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
66             } else {\r
67                 // Assign default value to the Operation\r
68                 nodeTypeProperty.defaultValue?.let {\r
69                     resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
70                 }\r
71             }\r
72             // Set for Return of method\r
73             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
74         }\r
75         logger.info("resolved property definition for node template ({}), values ({})", nodeTemplateName, propertyAssignmentValue)\r
76         return propertyAssignmentValue\r
77     }\r
78 \r
79     fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,\r
80                                                     interfaceName: String, operationName: String): MutableMap<String, Any?> {\r
81         logger.info("nodeTemplateInterfaceOperationInputsResolvedExpression for node template ({}),interface name ({}), " +\r
82                 "operationName({})", nodeTemplateName, interfaceName, operationName)\r
83 \r
84         val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
85 \r
86         val propertyAssignments: MutableMap<String, Any> =\r
87                 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName) as? MutableMap<String, Any>\r
88                         ?: throw BluePrintException(String.format("failed to get input definitions for node template (%s), " +\r
89                                 "interface name (%s), operationName(%s)", nodeTemplateName, interfaceName, operationName))\r
90 \r
91         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
92 \r
93         val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =\r
94                 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)\r
95                         ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
96                                 "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
97 \r
98         logger.info("input definition for node template ({}), values ({})", nodeTemplateName, propertyAssignments)\r
99 \r
100         // Iterate Node Type Properties\r
101         nodeTypeInterfaceOperationInputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
102             // Get the Express or Value for the Node Template\r
103             val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
104 \r
105             var resolvedValue: JsonNode = NullNode.getInstance()\r
106             if (propertyAssignment != null) {\r
107                 // Resolve the Expressing\r
108                 val propertyAssignmentExpression = PropertyAssignmentService( context, this)\r
109                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
110             } else {\r
111                 // Assign default value to the Operation\r
112                 nodeTypeProperty.defaultValue?.let {\r
113                     resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
114                 }\r
115             }\r
116             // Set for Return of method\r
117             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
118         }\r
119         logger.info("resolved input assignments for node template ({}), values ({})", nodeTemplateName, propertyAssignmentValue)\r
120 \r
121         return propertyAssignmentValue\r
122     }\r
123 \r
124 \r
125     fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,\r
126                                                      interfaceName: String, operationName: String, componentContext: MutableMap<String, Any?>): Unit {\r
127         logger.info("nodeTemplateInterfaceOperationInputsResolvedExpression for node template ({}),interface name ({}), " +\r
128                 "operationName({})", nodeTemplateName, interfaceName, operationName)\r
129 \r
130         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
131 \r
132         val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =\r
133                 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)\r
134                         ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
135                                 "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
136 \r
137         // Iterate Node Type Properties\r
138         nodeTypeInterfaceOperationOutputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
139 \r
140             val operationOutputPropertyName: String = StringBuilder().append(nodeTemplateName)\r
141                     .append(".").append(interfaceName)\r
142                     .append(".").append(operationName)\r
143                     .append(".").append(nodeTypePropertyName).toString()\r
144             // Get the Value from component context\r
145             val resolvedValue: JsonNode = componentContext[operationOutputPropertyName] as? JsonNode\r
146                     ?: NullNode.getInstance()\r
147             // Store  operation output values into context\r
148             setNodeTemplateOperationPropertyValue(nodeTemplateName, interfaceName, operationName, nodeTypePropertyName, resolvedValue)\r
149             logger.debug("resolved output assignments for node template ({}), property name ({}), value ({})", nodeTemplateName, nodeTypePropertyName, resolvedValue)\r
150         }\r
151     }\r
152 \r
153     fun resolveNodeTemplateArtifact(nodeTemplateName: String,\r
154                                     artifactName: String): String {\r
155         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
156 \r
157         val artifactDefinition: ArtifactDefinition = nodeTemplate.artifacts?.get(artifactName)\r
158                 ?: throw BluePrintProcessorException(String.format("failed to get artifat definition {} from the node template"\r
159                         , artifactName))\r
160         val propertyAssignmentExpression = PropertyAssignmentService( context, this)\r
161         return propertyAssignmentExpression.artifactContent(artifactDefinition)\r
162     }\r
163 \r
164 \r
165     fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode): Unit {\r
166         val path = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
167                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
168         logger.trace("setting input path ({}), values ({})", path, value)\r
169         context[path] = value\r
170     }\r
171 \r
172     fun setWorkflowInputValue(workflowName: String, propertyName: String, value: JsonNode): Unit {\r
173         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_WORKFLOWS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(workflowName)\r
174                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
175                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
176                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
177         context[path] = value\r
178     }\r
179 \r
180     fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode): Unit {\r
181 \r
182         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
183                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
184                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
185         context[path] = value\r
186     }\r
187 \r
188     fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
189                                               value: JsonNode): Unit {\r
190         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
191                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
192                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(operationName)\r
193                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
194                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
195         logger.trace("setting operation property path ({}), values ({})", path, value)\r
196         context[path] = value\r
197     }\r
198 \r
199     fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
200                                            value: JsonNode): Unit {\r
201         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
202                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(interfaceName)\r
203                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(operationName)\r
204                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
205                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
206                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
207         context[path] = value\r
208     }\r
209 \r
210     fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
211                                             value: JsonNode): Unit {\r
212         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
213                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(interfaceName)\r
214                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(operationName)\r
215                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OUTPUTS)\r
216                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
217                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
218         context[path] = value\r
219     }\r
220 \r
221 \r
222     fun getInputValue(propertyName: String): JsonNode {\r
223         val path = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
224                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
225         return context[path] as? JsonNode ?: NullNode.instance\r
226     }\r
227 \r
228     fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String): JsonNode {\r
229         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
230                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
231                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(operationName)\r
232                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
233                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
234         return context[path] as JsonNode\r
235     }\r
236 \r
237     fun getPropertyValue(nodeTemplateName: String, propertyName: String): JsonNode? {\r
238         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
239                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
240                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
241         return context[path] as JsonNode\r
242     }\r
243 \r
244     fun getRequirementPropertyValue(nodeTemplateName: String, requirementName: String, propertyName: String): JsonNode? {\r
245         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
246                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_REQUIREMENTS).append(requirementName)\r
247                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
248                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
249         return context[path] as JsonNode\r
250     }\r
251 \r
252     fun getCapabilityPropertyValue(nodeTemplateName: String, capabilityName: String, propertyName: String): JsonNode? {\r
253         val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
254                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_CAPABILITIES).append(capabilityName)\r
255                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
256                 .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
257         return context[path] as JsonNode\r
258     }\r
259 \r
260     fun assignInputs(jsonNode: JsonNode): Unit {\r
261         logger.info("assignInputs from input JSON ({})", jsonNode.toString())\r
262         bluePrintContext.inputs?.forEach { propertyName, property ->\r
263             val valueNode: JsonNode = jsonNode.at("/" + propertyName) ?: NullNode.getInstance()\r
264             setInputValue(propertyName, property, valueNode)\r
265         }\r
266     }\r
267 \r
268     fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode): Unit {\r
269         logger.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())\r
270         bluePrintContext.workflowByName(workflowName)?.inputs?.forEach { propertyName, property ->\r
271             val valueNode: JsonNode = jsonNode.at("/" + propertyName) ?: NullNode.getInstance()\r
272             setWorkflowInputValue(workflowName, propertyName, valueNode)\r
273         }\r
274     }\r
275 }