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.*
28 import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactDefinition
29 import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate
30 import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition
31 import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils
34 interface BluePrintRuntimeService<T> {
38 fun bluePrintContext(): BluePrintContext
40 fun getExecutionContext(): T
42 fun setExecutionContext(executionContext: T)
44 fun put(key: String, value: JsonNode)
46 fun get(key: String): JsonNode?
48 fun check(key: String): Boolean
52 fun getAsString(key: String): String?
54 fun getAsBoolean(key: String): Boolean?
56 fun getAsInt(key: String): Int?
58 fun getAsDouble(key: String): Double?
60 fun getBluePrintError(): BluePrintError
62 fun setBluePrintError(bluePrintError: BluePrintError)
64 fun loadEnvironments(type: String, fileName: String)
66 fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
67 propertyDefinitions: MutableMap<String, PropertyDefinition>,
68 propertyAssignments: MutableMap<String, JsonNode>): MutableMap<String, JsonNode>
70 fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode>
72 fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap<String,
75 fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String, interfaceName: String,
76 operationName: String): MutableMap<String, JsonNode>
78 fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String, interfaceName: String,
79 operationName: String): MutableMap<String, JsonNode>
81 fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String
83 fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition
85 fun resolveDSLExpression(dslPropertyName: String): JsonNode
87 fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
89 fun setWorkflowInputValue(workflowName: String, propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
91 fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode)
93 fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode)
95 fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String,
96 operationName: String, propertyName: String, value: JsonNode)
98 fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
99 operationName: String, propertyName: String, value: JsonNode)
101 fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
102 operationName: String, propertyName: String, value: JsonNode)
104 fun getInputValue(propertyName: String): JsonNode
106 fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
107 operationName: String, propertyName: String): JsonNode
109 fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode?
111 fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode?
113 fun assignInputs(jsonNode: JsonNode)
115 fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode)
117 fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode
123 * @author Brinda Santh
125 open class DefaultBluePrintRuntimeService(private var id: String, private var bluePrintContext: BluePrintContext)
126 : BluePrintRuntimeService<MutableMap<String, JsonNode>> {
129 private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintRuntimeService::class.toString())
131 private var store: MutableMap<String, JsonNode> = hashMapOf()
133 private var bluePrintError = BluePrintError()
137 * Load Blueprint Environments Properties
139 val absoluteEnvFilePath = bluePrintContext.rootPath.plus(File.separator)
140 .plus(BluePrintConstants.TOSCA_ENVIRONMENTS_DIR)
141 loadEnvironments(BluePrintConstants.PROPERTY_BPP, absoluteEnvFilePath)
145 override fun id(): String {
149 override fun bluePrintContext(): BluePrintContext {
150 return bluePrintContext
153 override fun getExecutionContext(): MutableMap<String, JsonNode> {
157 @Suppress("UNCHECKED_CAST")
158 override fun setExecutionContext(executionContext: MutableMap<String, JsonNode>) {
159 this.store = executionContext
162 override fun put(key: String, value: JsonNode) {
166 override fun get(key: String): JsonNode {
167 return store[key] ?: throw BluePrintProcessorException("failed to get execution property($key)")
170 override fun check(key: String): Boolean {
171 return store.containsKey(key)
174 override fun cleanRuntime() {
178 private fun getJsonNode(key: String): JsonNode {
182 override fun getAsString(key: String): String? {
183 return get(key).asText()
186 override fun getAsBoolean(key: String): Boolean? {
187 return get(key).asBoolean()
190 override fun getAsInt(key: String): Int? {
191 return get(key).asInt()
194 override fun getAsDouble(key: String): Double? {
195 return get(key).asDouble()
198 override fun getBluePrintError(): BluePrintError {
199 return this.bluePrintError
202 override fun setBluePrintError(bluePrintError: BluePrintError) {
203 this.bluePrintError = bluePrintError
206 override fun loadEnvironments(type: String, fileName: String) {
207 BluePrintMetadataUtils.environmentFileProperties(fileName).forEach { key, value ->
208 setNodeTemplateAttributeValue(type, key.toString(), value.toString()
214 * Resolve any property assignments for the node
216 override fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
217 propertyDefinitions: MutableMap<String, PropertyDefinition>,
218 propertyAssignments: MutableMap<String, JsonNode>)
219 : MutableMap<String, JsonNode> {
221 val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
223 propertyDefinitions.forEach { nodeTypePropertyName, nodeTypeProperty ->
224 // Get the Express or Value for the Node Template
225 val propertyAssignment: JsonNode? = propertyAssignments[nodeTypePropertyName]
227 var resolvedValue: JsonNode = NullNode.getInstance()
228 if (propertyAssignment != null) {
229 // Resolve the Expressing
230 val propertyAssignmentExpression = PropertyAssignmentService(this)
231 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName,
232 nodeTypePropertyName, propertyAssignment)
234 // Assign default value to the Operation
235 nodeTypeProperty.defaultValue?.let {
236 resolvedValue = nodeTypeProperty.defaultValue!!
239 // Set for Return of method
240 propertyAssignmentValue[nodeTypePropertyName] = resolvedValue
242 return propertyAssignmentValue
245 override fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode> {
246 log.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)
248 val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
250 val propertyAssignments: MutableMap<String, JsonNode> = nodeTemplate.properties!!
252 // Get the Node Type Definitions
253 val nodeTypePropertieDefinitions: MutableMap<String, PropertyDefinition> = bluePrintContext
254 .nodeTypeChainedProperties(nodeTemplate.type)!!
257 * Resolve the NodeTemplate Property Assignment Values.
259 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypePropertieDefinitions,
263 override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String):
264 MutableMap<String, JsonNode> {
265 log.info("resolveNodeTemplateCapabilityProperties for node template($nodeTemplateName) capability " +
267 val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
269 val propertyAssignments = nodeTemplate.capabilities?.get(capabilityName)?.properties ?: hashMapOf()
271 val propertyDefinitions = bluePrintContext.nodeTemplateNodeType(nodeTemplateName)
272 .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
275 * Resolve the Capability Property Assignment Values.
277 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, propertyDefinitions,
281 override fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,
282 interfaceName: String,
283 operationName: String): MutableMap<String, JsonNode> {
284 log.info("resolveNodeTemplateInterfaceOperationInputs for node template ($nodeTemplateName),interface name " +
285 "($interfaceName), operationName($operationName)")
287 val propertyAssignments: MutableMap<String, JsonNode> =
288 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
291 val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
293 val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =
294 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
297 log.info("input definition for node template ($nodeTemplateName), values ($propertyAssignments)")
300 * Resolve the Property Input Assignment Values.
302 return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypeInterfaceOperationInputs,
308 override fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,
309 interfaceName: String,
310 operationName: String): MutableMap<String, JsonNode> {
311 log.info("resolveNodeTemplateInterfaceOperationOutputs for node template ($nodeTemplateName),interface name " +
312 "($interfaceName), operationName($operationName)")
314 val propertyAssignments: MutableMap<String, JsonNode> =
315 bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
318 val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
320 val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =
321 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
324 * Resolve the Property Output Assignment Values.
326 val propertyAssignmentValue = resolveNodeTemplatePropertyAssignments(nodeTemplateName,
327 nodeTypeInterfaceOperationOutputs, propertyAssignments)
329 // Store operation output values into context
330 propertyAssignmentValue.forEach { key, value ->
331 setNodeTemplateOperationOutputValue(nodeTemplateName, interfaceName, operationName, key, value)
333 return propertyAssignmentValue
336 override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {
337 val artifactDefinition: ArtifactDefinition = resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
338 val propertyAssignmentExpression = PropertyAssignmentService(this)
339 return propertyAssignmentExpression.artifactContent(artifactDefinition)
342 override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition {
343 val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
345 return nodeTemplate.artifacts?.get(artifactName)
346 ?: throw BluePrintProcessorException("failed to get artifat definition($artifactName) from the node " +
352 * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json
355 override fun resolveDSLExpression(dslPropertyName: String): JsonNode {
356 val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName)
357 return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments)
358 && propertyAssignments is ObjectNode) {
360 val rootKeyMap = propertyAssignments.rootFieldsToMap()
361 val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
362 rootKeyMap.forEach { propertyName, propertyValue ->
363 val propertyAssignmentExpression = PropertyAssignmentService(this)
364 propertyAssignmentValue[propertyName] = propertyAssignmentExpression
365 .resolveAssignmentExpression("DSL", propertyName, propertyValue)
367 propertyAssignmentValue.asJsonNode()
373 override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
374 val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
375 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
376 log.trace("setting input path ({}), values ({})", path, value)
380 override fun setWorkflowInputValue(workflowName: String, propertyName: String,
381 propertyDefinition: PropertyDefinition, value: JsonNode) {
382 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
383 .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
384 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
385 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
386 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
390 override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
392 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
393 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
394 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
395 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
399 override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
401 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
402 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
403 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
404 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
408 override fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,
410 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
411 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
412 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
413 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
414 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
415 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
416 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
417 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
418 log.trace("setting operation property path ({}), values ({})", path, value)
422 override fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
423 operationName: String, propertyName: String,
425 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
426 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
427 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
428 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
429 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
430 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
431 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
432 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
433 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
437 override fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
438 operationName: String, propertyName: String,
440 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
441 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
442 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
443 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
444 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
445 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
446 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
447 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
448 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
453 override fun getInputValue(propertyName: String): JsonNode {
454 val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
455 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
456 return getJsonNode(path)
459 override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
460 operationName: String, propertyName: String): JsonNode {
461 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
462 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
463 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
464 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
465 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
466 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
467 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
468 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
469 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
470 return getJsonNode(path)
473 override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
474 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
475 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
476 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
477 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
478 return getJsonNode(path)
481 override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
482 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
483 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
484 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
485 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
486 return getJsonNode(path)
489 override fun assignInputs(jsonNode: JsonNode) {
490 log.info("assignInputs from input JSON ({})", jsonNode.toString())
491 bluePrintContext.inputs()?.forEach { propertyName, property ->
492 val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
493 ?: NullNode.getInstance()
494 setInputValue(propertyName, property, valueNode)
498 override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {
499 log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())
501 val dynamicInputPropertiesName = "$workflowName-properties"
503 bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
504 if (propertyName != dynamicInputPropertiesName) {
505 val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
506 ?: NullNode.getInstance()
507 setInputValue(propertyName, property, valueNode)
510 // Load Dynamic data Types
511 val workflowDynamicInputs: JsonNode? = jsonNode.get(dynamicInputPropertiesName)
513 workflowDynamicInputs?.let {
514 bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")?.properties?.forEach { propertyName, property ->
515 val valueNode: JsonNode = workflowDynamicInputs.at(BluePrintConstants.PATH_DIVIDER + propertyName)
516 ?: NullNode.getInstance()
517 setInputValue(propertyName, property, valueNode)
523 override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {
525 val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
526 val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
527 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
528 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
529 .append(BluePrintConstants.PATH_DIVIDER).toString()
533 val key = it.replace(path, "")
534 if (keys.contains(key)) {
535 val value = store[it] as JsonNode
536 jsonNode.set(key, value)