0819ed74beff59396325b33b18a0681bbc973f7d
[ccsdk/cds.git] /
1 /*
2  * Copyright © 2017-2018 AT&T Intellectual Property.
3  * Modifications Copyright © 2018-2019 IBM.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 package org.onap.ccsdk.cds.controllerblueprints.core.service
19
20
21 import org.slf4j.LoggerFactory
22 import com.fasterxml.jackson.databind.JsonNode
23 import com.fasterxml.jackson.databind.node.NullNode
24 import com.fasterxml.jackson.databind.node.ObjectNode
25 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
26 import org.onap.ccsdk.cds.controllerblueprints.core.*
27 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
28 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
29 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
30 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
31 import java.io.File
32
33 interface BluePrintRuntimeService<T> {
34
35     fun id(): String
36
37     fun bluePrintContext(): BluePrintContext
38
39     fun getExecutionContext(): T
40
41     fun setExecutionContext(executionContext: T)
42
43     fun put(key: String, value: JsonNode)
44
45     fun get(key: String): JsonNode?
46
47     fun check(key: String): Boolean
48
49     fun cleanRuntime()
50
51     fun getAsString(key: String): String?
52
53     fun getAsBoolean(key: String): Boolean?
54
55     fun getAsInt(key: String): Int?
56
57     fun getAsDouble(key: String): Double?
58
59     fun getBluePrintError(): BluePrintError
60
61     fun setBluePrintError(bluePrintError: BluePrintError)
62
63     fun loadEnvironments(type: String, fileName: String)
64
65     fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
66                                                propertyDefinitions: MutableMap<String, PropertyDefinition>,
67                                                propertyAssignments: MutableMap<String, JsonNode>): MutableMap<String, JsonNode>
68
69     fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap<String, PropertyDefinition>)
70             : MutableMap<String, JsonNode>
71
72     fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap<String, JsonNode>)
73             : MutableMap<String, JsonNode>
74
75     fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode>
76
77     fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String): MutableMap<String,
78             JsonNode>
79
80     fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String, interfaceName: String,
81                                                     operationName: String): MutableMap<String, JsonNode>
82
83     fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String, interfaceName: String,
84                                                      operationName: String): MutableMap<String, JsonNode>
85
86     fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String
87
88     fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition
89
90     fun resolveDSLExpression(dslPropertyName: String): JsonNode
91
92     fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
93
94     fun setWorkflowInputValue(workflowName: String, propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode)
95
96     fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode)
97
98     fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode)
99
100     fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String,
101                                               operationName: String, propertyName: String, value: JsonNode)
102
103     fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
104                                            operationName: String, propertyName: String, value: JsonNode)
105
106     fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
107                                             operationName: String, propertyName: String, value: JsonNode)
108
109     fun getInputValue(propertyName: String): JsonNode
110
111     fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
112                                             operationName: String, propertyName: String): JsonNode
113
114     fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode?
115
116     fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode?
117
118     fun assignInputs(jsonNode: JsonNode)
119
120     fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode)
121
122     fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode>
123
124     fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode
125 }
126
127 /**
128  *
129  *
130  * @author Brinda Santh
131  */
132 open class DefaultBluePrintRuntimeService(private var id: String, private var bluePrintContext: BluePrintContext)
133     : BluePrintRuntimeService<MutableMap<String, JsonNode>> {
134
135     @Transient
136     private val log= LoggerFactory.getLogger(BluePrintRuntimeService::class.toString())
137
138     private var store: MutableMap<String, JsonNode> = hashMapOf()
139
140     private var bluePrintError = BluePrintError()
141
142     init {
143         /**
144          * Load Blueprint Environments Properties
145          */
146         val absoluteEnvFilePath = bluePrintContext.rootPath.plus(File.separator)
147                 .plus(BluePrintConstants.TOSCA_ENVIRONMENTS_DIR)
148         loadEnvironments(BluePrintConstants.PROPERTY_BPP, absoluteEnvFilePath)
149
150     }
151
152     override fun id(): String {
153         return id
154     }
155
156     override fun bluePrintContext(): BluePrintContext {
157         return bluePrintContext
158     }
159
160     override fun getExecutionContext(): MutableMap<String, JsonNode> {
161         return store
162     }
163
164     @Suppress("UNCHECKED_CAST")
165     override fun setExecutionContext(executionContext: MutableMap<String, JsonNode>) {
166         this.store = executionContext
167     }
168
169     override fun put(key: String, value: JsonNode) {
170         store[key] = value
171     }
172
173     override fun get(key: String): JsonNode {
174         return store[key] ?: throw BluePrintProcessorException("failed to get execution property($key)")
175     }
176
177     override fun check(key: String): Boolean {
178         return store.containsKey(key)
179     }
180
181     override fun cleanRuntime() {
182         store.clear()
183     }
184
185     private fun getJsonNode(key: String): JsonNode {
186         return get(key)
187     }
188
189     override fun getAsString(key: String): String? {
190         return get(key).asText()
191     }
192
193     override fun getAsBoolean(key: String): Boolean? {
194         return get(key).asBoolean()
195     }
196
197     override fun getAsInt(key: String): Int? {
198         return get(key).asInt()
199     }
200
201     override fun getAsDouble(key: String): Double? {
202         return get(key).asDouble()
203     }
204
205     override fun getBluePrintError(): BluePrintError {
206         return this.bluePrintError
207     }
208
209     override fun setBluePrintError(bluePrintError: BluePrintError) {
210         this.bluePrintError = bluePrintError
211     }
212
213     override fun loadEnvironments(type: String, fileName: String) {
214         BluePrintMetadataUtils.environmentFileProperties(fileName).forEach { key, value ->
215             setNodeTemplateAttributeValue(type, key.toString(), value.toString()
216                     .asJsonPrimitive())
217         }
218     }
219
220     /**
221      * Resolve any property assignments for the node
222      */
223     override fun resolveNodeTemplatePropertyAssignments(nodeTemplateName: String,
224                                                         propertyDefinitions: MutableMap<String, PropertyDefinition>,
225                                                         propertyAssignments: MutableMap<String, JsonNode>)
226             : MutableMap<String, JsonNode> {
227
228         val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
229
230         propertyDefinitions.forEach { nodeTypePropertyName, nodeTypeProperty ->
231             // Get the Express or Value for the Node Template
232             val propertyAssignment: JsonNode? = propertyAssignments[nodeTypePropertyName]
233
234             var resolvedValue: JsonNode = NullNode.getInstance()
235             if (propertyAssignment != null) {
236                 // Resolve the Expressing
237                 val propertyAssignmentExpression = PropertyAssignmentService(this)
238                 resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName,
239                         nodeTypePropertyName, propertyAssignment)
240             } else {
241                 // Assign default value to the Operation
242                 nodeTypeProperty.defaultValue?.let {
243                     resolvedValue = nodeTypeProperty.defaultValue!!
244                 }
245             }
246             // Set for Return of method
247             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue
248         }
249         return propertyAssignmentValue
250     }
251
252     override fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap<String, PropertyDefinition>)
253             : MutableMap<String, JsonNode> {
254         val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
255
256         propertyDefinitions.forEach { propertyName, propertyDefinition ->
257             val propertyAssignmentExpression = PropertyAssignmentService(this)
258             val expression = propertyDefinition.value ?: propertyDefinition.defaultValue
259             if (expression != null) {
260                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
261                         propertyName, expression)
262             }
263         }
264         return propertyAssignmentValue
265     }
266
267     override fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap<String, JsonNode>)
268             : MutableMap<String, JsonNode> {
269
270         val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
271
272         propertyAssignments.forEach { propertyName, propertyExpression ->
273             val propertyAssignmentExpression = PropertyAssignmentService(this)
274             propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
275                     propertyName, propertyExpression)
276         }
277         return propertyAssignmentValue
278     }
279
280     override fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode> {
281         log.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)
282
283         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
284
285         val propertyAssignments: MutableMap<String, JsonNode> = nodeTemplate.properties!!
286
287         // Get the Node Type Definitions
288         val nodeTypePropertieDefinitions: MutableMap<String, PropertyDefinition> = bluePrintContext
289                 .nodeTypeChainedProperties(nodeTemplate.type)!!
290
291         /**
292          * Resolve the NodeTemplate Property Assignment Values.
293          */
294         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypePropertieDefinitions,
295                 propertyAssignments)
296     }
297
298     override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String):
299             MutableMap<String, JsonNode> {
300         log.info("resolveNodeTemplateCapabilityProperties for node template($nodeTemplateName) capability " +
301                 "($capabilityName)")
302         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
303
304         val propertyAssignments = nodeTemplate.capabilities?.get(capabilityName)?.properties ?: hashMapOf()
305
306         val propertyDefinitions = bluePrintContext.nodeTemplateNodeType(nodeTemplateName)
307                 .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
308
309         /**
310          * Resolve the Capability Property Assignment Values.
311          */
312         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, propertyDefinitions,
313                 propertyAssignments)
314     }
315
316     override fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,
317                                                              interfaceName: String,
318                                                              operationName: String): MutableMap<String, JsonNode> {
319         log.info("resolveNodeTemplateInterfaceOperationInputs for node template ($nodeTemplateName),interface name " +
320                 "($interfaceName), operationName($operationName)")
321
322         val propertyAssignments: MutableMap<String, JsonNode> =
323                 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
324                         ?: hashMapOf()
325
326         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
327
328         val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =
329                 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
330                         ?: hashMapOf()
331
332         log.info("input definition for node template ($nodeTemplateName), values ($propertyAssignments)")
333
334         /**
335          * Resolve the Property Input Assignment Values.
336          */
337         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypeInterfaceOperationInputs,
338                 propertyAssignments)
339
340     }
341
342
343     override fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,
344                                                               interfaceName: String,
345                                                               operationName: String): MutableMap<String, JsonNode> {
346         log.info("resolveNodeTemplateInterfaceOperationOutputs for node template ($nodeTemplateName),interface name " +
347                 "($interfaceName), operationName($operationName)")
348
349         val propertyAssignments: MutableMap<String, JsonNode> =
350                 bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
351                         ?: hashMapOf()
352
353         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
354
355         val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =
356                 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
357                         ?: hashMapOf()
358         /**
359          * Resolve the Property Output Assignment Values.
360          */
361         val propertyAssignmentValue = resolveNodeTemplatePropertyAssignments(nodeTemplateName,
362                 nodeTypeInterfaceOperationOutputs, propertyAssignments)
363
364         // Store  operation output values into context
365         propertyAssignmentValue.forEach { key, value ->
366             setNodeTemplateOperationOutputValue(nodeTemplateName, interfaceName, operationName, key, value)
367         }
368         return propertyAssignmentValue
369     }
370
371     override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {
372         val artifactDefinition: ArtifactDefinition = resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
373         val propertyAssignmentExpression = PropertyAssignmentService(this)
374         return propertyAssignmentExpression.artifactContent(artifactDefinition)
375     }
376
377     override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String, artifactName: String): ArtifactDefinition {
378         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
379
380         return nodeTemplate.artifacts?.get(artifactName)
381                 ?: throw BluePrintProcessorException("failed to get artifat definition($artifactName) from the node " +
382                         "template")
383
384     }
385
386     /**
387      * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json
388      * Type
389      */
390     override fun resolveDSLExpression(dslPropertyName: String): JsonNode {
391         val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName)
392         return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments)
393                 && propertyAssignments is ObjectNode) {
394
395             val rootKeyMap = propertyAssignments.rootFieldsToMap()
396             val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
397             rootKeyMap.forEach { propertyName, propertyValue ->
398                 val propertyAssignmentExpression = PropertyAssignmentService(this)
399                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression
400                         .resolveAssignmentExpression("DSL", propertyName, propertyValue)
401             }
402             propertyAssignmentValue.asJsonNode()
403         } else {
404             propertyAssignments
405         }
406     }
407
408     override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
409         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
410                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
411         log.trace("setting input path ({}), values ({})", path, value)
412         put(path, value)
413     }
414
415     override fun setWorkflowInputValue(workflowName: String, propertyName: String,
416                                        propertyDefinition: PropertyDefinition, value: JsonNode) {
417         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
418                 .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
419                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
420                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
421                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
422         put(path, value)
423     }
424
425     override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
426
427         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
428                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
429                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
430                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
431         put(path, value)
432     }
433
434     override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
435
436         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
437                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
438                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
439                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
440         put(path, value)
441     }
442
443     override fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,
444                                                        value: JsonNode) {
445         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
446                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
447                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
448                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
449                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
450                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
451                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
452                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
453         log.trace("setting operation property path ({}), values ({})", path, value)
454         put(path, value)
455     }
456
457     override fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
458                                                     operationName: String, propertyName: String,
459                                                     value: JsonNode) {
460         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
461                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
462                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
463                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
464                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
465                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
466                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
467                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
468                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
469         put(path, value)
470     }
471
472     override fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
473                                                      operationName: String, propertyName: String,
474                                                      value: JsonNode) {
475         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
476                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
477                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
478                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
479                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
480                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
481                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
482                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
483                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
484         put(path, value)
485     }
486
487
488     override fun getInputValue(propertyName: String): JsonNode {
489         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
490                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
491         return getJsonNode(path)
492     }
493
494     override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
495                                                      operationName: String, propertyName: String): JsonNode {
496         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
497                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
498                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
499                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
500                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
501                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
502                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
503                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
504                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
505         return getJsonNode(path)
506     }
507
508     override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
509         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
510                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
511                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
512                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
513         return getJsonNode(path)
514     }
515
516     override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
517         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
518                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
519                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
520                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
521         return getJsonNode(path)
522     }
523
524     override fun assignInputs(jsonNode: JsonNode) {
525         log.info("assignInputs from input JSON ({})", jsonNode.toString())
526         bluePrintContext.inputs()?.forEach { propertyName, property ->
527             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
528                     ?: NullNode.getInstance()
529             setInputValue(propertyName, property, valueNode)
530         }
531     }
532
533     override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {
534         log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())
535
536         val dynamicInputPropertiesName = "$workflowName-properties"
537
538         bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
539             if (propertyName != dynamicInputPropertiesName) {
540                 val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
541                         ?: NullNode.getInstance()
542                 setInputValue(propertyName, property, valueNode)
543             }
544         }
545         // Load Dynamic data Types
546         val workflowDynamicInputs: JsonNode? = jsonNode.get(dynamicInputPropertiesName)
547
548         workflowDynamicInputs?.let {
549             bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")?.properties?.forEach { propertyName, property ->
550                 val valueNode: JsonNode = workflowDynamicInputs.at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
551                         ?: property.defaultValue
552                         ?: NullNode.getInstance()
553                 setInputValue(propertyName, property, valueNode)
554
555             }
556         }
557     }
558
559     override fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode> {
560         log.info("resolveWorkflowOutputs for workflow($workflowName)")
561         val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf()
562         return resolvePropertyDefinitions("WORKFLOW", outputs)
563     }
564
565     override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {
566
567         val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
568         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
569                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
570                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
571                 .append(BluePrintConstants.PATH_DIVIDER).toString()
572         store.keys.filter {
573             it.startsWith(path)
574         }.map {
575             val key = it.replace(path, "")
576             if (keys.contains(key)) {
577                 val value = store[it] as JsonNode
578                 jsonNode.set(key, value)
579             }
580         }
581         return jsonNode
582     }
583
584
585 }