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