2 * Copyright © 2017-2018 AT&T Intellectual Property.
3 * Modifications Copyright © 2018 IBM.
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.apps.controllerblueprints.core.service
21 import com.att.eelf.configuration.EELFLogger
22 import com.att.eelf.configuration.EELFManager
23 import com.fasterxml.jackson.databind.JsonNode
24 import com.fasterxml.jackson.databind.node.NullNode
25 import com.fasterxml.jackson.databind.node.ObjectNode
26 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
27 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants
28 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintError
29 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
30 import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactDefinition
31 import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate
32 import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition
33 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
35 interface BluePrintRuntimeService<T> {
39 fun bluePrintContext(): BluePrintContext
41 fun getExecutionContext(): T
43 fun setExecutionContext(executionContext: T)
45 fun put(key: String, value: JsonNode)
47 fun get(key: String): JsonNode?
49 fun check(key: String): Boolean
53 fun getAsString(key: String): String?
55 fun getAsBoolean(key: String): Boolean?
57 fun getAsInt(key: String): Int?
59 fun getAsDouble(key: String): Double?
61 fun getBluePrintError(): BluePrintError
63 fun setBluePrintError(bluePrintError: BluePrintError)
65 fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
66 propertyDefinitions: MutableMap<String, PropertyDefinition>,
67 propertyAssignments: MutableMap<String, JsonNode>): MutableMap<String, JsonNode>
69 fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode>
71 fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap<String,
74 fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String, interfaceName: String,
75 operationName: String): MutableMap<String, JsonNode>
77 fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String, interfaceName: String,
78 operationName: String): MutableMap<String, JsonNode>
80 fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String
82 fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition
84 fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
86 fun setWorkflowInputValue(workflowName: String, propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
88 fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode)
90 fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode)
92 fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String,
93 operationName: String, propertyName: String, value: JsonNode)
95 fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
96 operationName: String, propertyName: String, value: JsonNode)
98 fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
99 operationName: String, propertyName: String, value: JsonNode)
101 fun getInputValue(propertyName: String): JsonNode
103 fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
104 operationName: String, propertyName: String): JsonNode
106 fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode?
108 fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode?
110 fun assignInputs(jsonNode: JsonNode)
112 fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode)
114 fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode
120 * @author Brinda Santh
122 open class DefaultBluePrintRuntimeService(private var id: String, private var bluePrintContext: BluePrintContext)
123 : BluePrintRuntimeService<MutableMap<String, JsonNode>> {
126 private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintRuntimeService::class.toString())
128 private var store: MutableMap<String, JsonNode> = hashMapOf()
130 private var bluePrintError = BluePrintError()
132 override fun id(): String {
136 override fun bluePrintContext(): BluePrintContext {
137 return bluePrintContext
140 override fun getExecutionContext(): MutableMap<String, JsonNode> {
144 @Suppress("UNCHECKED_CAST")
145 override fun setExecutionContext(executionContext: MutableMap<String, JsonNode>) {
146 this.store = executionContext
149 override fun put(key: String, value: JsonNode) {
153 override fun get(key: String): JsonNode {
154 return store[key] ?: throw BluePrintProcessorException("failed to get execution property($key)")
157 override fun check(key: String): Boolean {
158 return store.containsKey(key)
161 override fun cleanRuntime() {
165 private fun getJsonNode(key: String): JsonNode {
169 override fun getAsString(key: String): String? {
170 return get(key).asText()
173 override fun getAsBoolean(key: String): Boolean? {
174 return get(key).asBoolean()
177 override fun getAsInt(key: String): Int? {
178 return get(key).asInt()
181 override fun getAsDouble(key: String): Double? {
182 return get(key).asDouble()
185 override fun getBluePrintError(): BluePrintError {
186 return this.bluePrintError
189 override fun setBluePrintError(bluePrintError: BluePrintError) {
190 this.bluePrintError = bluePrintError
194 * Resolve any property assignments for the node
196 override fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
197 propertyDefinitions: MutableMap<String, PropertyDefinition>,
198 propertyAssignments: MutableMap<String, JsonNode>)
199 : MutableMap<String, JsonNode> {
201 val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
203 propertyDefinitions.forEach { nodeTypePropertyName, nodeTypeProperty ->
204 // Get the Express or Value for the Node Template
205 val propertyAssignment: JsonNode? = propertyAssignments[nodeTypePropertyName]
207 var resolvedValue: JsonNode = NullNode.getInstance()
208 if (propertyAssignment != null) {
209 // Resolve the Expressing
210 val propertyAssignmentExpression = PropertyAssignmentService(this)
211 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName,
212 nodeTypePropertyName, propertyAssignment)
214 // Assign default value to the Operation
215 nodeTypeProperty.defaultValue?.let {
216 resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)
219 // Set for Return of method
220 propertyAssignmentValue[nodeTypePropertyName] = resolvedValue
222 return propertyAssignmentValue
225 override fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode> {
226 log.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)
228 val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
230 val propertyAssignments: MutableMap<String, JsonNode> = nodeTemplate.properties!!
232 // Get the Node Type Definitions
233 val nodeTypePropertieDefinitions: MutableMap<String, PropertyDefinition> = bluePrintContext
234 .nodeTypeChainedProperties(nodeTemplate.type)!!
237 * Resolve the NodeTemplate Property Assignment Values.
239 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypePropertieDefinitions,
243 override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String):
244 MutableMap<String, JsonNode> {
245 log.info("resolveNodeTemplateCapabilityProperties for node template($nodeTemplateName) capability " +
247 val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
249 val propertyAssignments = nodeTemplate.capabilities?.get(capabilityName)?.properties ?: hashMapOf()
251 val propertyDefinitions = bluePrintContext.nodeTemplateNodeType(nodeTemplateName)
252 .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
255 * Resolve the Capability Property Assignment Values.
257 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, propertyDefinitions,
261 override fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,
262 interfaceName: String,
263 operationName: String): MutableMap<String, JsonNode> {
264 log.info("resolveNodeTemplateInterfaceOperationInputs for node template ($nodeTemplateName),interface name " +
265 "($interfaceName), operationName($operationName)")
267 val propertyAssignments: MutableMap<String, JsonNode> =
268 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
271 val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
273 val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =
274 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
277 log.info("input definition for node template ($nodeTemplateName), values ($propertyAssignments)")
280 * Resolve the Property Input Assignment Values.
282 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypeInterfaceOperationInputs,
288 override fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,
289 interfaceName: String,
290 operationName: String): MutableMap<String, JsonNode> {
291 log.info("resolveNodeTemplateInterfaceOperationOutputs for node template ($nodeTemplateName),interface name " +
292 "($interfaceName), operationName($operationName)")
294 val propertyAssignments: MutableMap<String, JsonNode> =
295 bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
298 val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
300 val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =
301 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
304 * Resolve the Property Output Assignment Values.
306 val propertyAssignmentValue = resolveNodeTemplatePropertyAssignments(nodeTemplateName,
307 nodeTypeInterfaceOperationOutputs, propertyAssignments)
309 // Store operation output values into context
310 propertyAssignmentValue.forEach { key, value ->
311 setNodeTemplateOperationOutputValue(nodeTemplateName, interfaceName, operationName, key, value)
313 return propertyAssignmentValue
316 override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {
317 val artifactDefinition: ArtifactDefinition = resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
318 val propertyAssignmentExpression = PropertyAssignmentService(this)
319 return propertyAssignmentExpression.artifactContent(artifactDefinition)
322 override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition {
323 val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
325 return nodeTemplate.artifacts?.get(artifactName)
326 ?: throw BluePrintProcessorException("failed to get artifat definition($artifactName) from the node " +
331 override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
332 val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
333 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
334 log.trace("setting input path ({}), values ({})", path, value)
338 override fun setWorkflowInputValue(workflowName: String, propertyName: String,
339 propertyDefinition: PropertyDefinition, value: JsonNode) {
340 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
341 .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
342 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
343 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
344 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
348 override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
350 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
351 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
352 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
353 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
357 override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
359 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
360 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
361 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
362 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
366 override fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,
368 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
369 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
370 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
371 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
372 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
373 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
374 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
375 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
376 log.trace("setting operation property path ({}), values ({})", path, value)
380 override fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
381 operationName: String, propertyName: String,
383 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
384 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
385 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
386 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
387 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
388 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
389 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
390 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
391 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
395 override fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
396 operationName: String, propertyName: String,
398 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
399 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
400 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
401 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
402 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
403 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
404 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
405 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
406 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
411 override fun getInputValue(propertyName: String): JsonNode {
412 val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
413 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
414 return getJsonNode(path)
417 override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
418 operationName: String, propertyName: String): JsonNode {
419 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
420 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
421 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
422 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
423 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
424 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
425 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
426 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
427 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
428 return getJsonNode(path)
431 override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
432 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
433 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
434 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
435 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
436 return getJsonNode(path)
439 override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
440 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
441 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
442 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
443 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
444 return getJsonNode(path)
447 override fun assignInputs(jsonNode: JsonNode) {
448 log.info("assignInputs from input JSON ({})", jsonNode.toString())
449 bluePrintContext.inputs?.forEach { propertyName, property ->
450 val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
451 ?: NullNode.getInstance()
452 setInputValue(propertyName, property, valueNode)
456 override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {
457 log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())
459 val dynamicInputPropertiesName = "$workflowName-properties"
461 bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
462 if (propertyName != dynamicInputPropertiesName) {
463 val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
464 ?: NullNode.getInstance()
465 setInputValue(propertyName, property, valueNode)
468 // Load Dynamic data Types
469 val workflowDynamicInputs: JsonNode? = jsonNode.get(dynamicInputPropertiesName)
471 workflowDynamicInputs?.let {
472 bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")?.properties?.forEach { propertyName, property ->
473 val valueNode: JsonNode = workflowDynamicInputs.at(BluePrintConstants.PATH_DIVIDER + propertyName)
474 ?: NullNode.getInstance()
475 setInputValue(propertyName, property, valueNode)
481 override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {
483 val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
484 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
485 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
486 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
487 .append(BluePrintConstants.PATH_DIVIDER).toString()
491 val key = it.replace(path, "")
492 if (keys.contains(key)) {
493 val value = store[it] as JsonNode
494 jsonNode.set(key, value)