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