Merge "Renamed template options and reordered"
[ccsdk/cds.git] / ms / controllerblueprints / modules / blueprint-core / src / main / kotlin / org / onap / ccsdk / cds / 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.cds.controllerblueprints.core.service
19
20
21 import com.fasterxml.jackson.databind.JsonNode
22 import com.fasterxml.jackson.databind.node.NullNode
23 import com.fasterxml.jackson.databind.node.ObjectNode
24 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
25 import org.onap.ccsdk.cds.controllerblueprints.core.*
26 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
27 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
28 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
29 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
30 import org.slf4j.LoggerFactory
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,
95                               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 = LoggerFactory.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             }
242
243             // Set default value if null
244             if (resolvedValue is NullNode) {
245                 nodeTypeProperty.defaultValue?.let { resolvedValue = nodeTypeProperty.defaultValue!! }
246             }
247
248             // Set for Return of method
249             propertyAssignmentValue[nodeTypePropertyName] = resolvedValue
250         }
251         return propertyAssignmentValue
252     }
253
254     override fun resolvePropertyDefinitions(name: String, propertyDefinitions: MutableMap<String, PropertyDefinition>)
255             : MutableMap<String, JsonNode> {
256         val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
257
258         propertyDefinitions.forEach { propertyName, propertyDefinition ->
259             val propertyAssignmentExpression = PropertyAssignmentService(this)
260             val expression = propertyDefinition.value ?: propertyDefinition.defaultValue
261             if (expression != null) {
262                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
263                         propertyName, expression)
264             }
265         }
266         return propertyAssignmentValue
267     }
268
269     override fun resolvePropertyAssignments(name: String, propertyAssignments: MutableMap<String, JsonNode>)
270             : MutableMap<String, JsonNode> {
271
272         val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
273
274         propertyAssignments.forEach { propertyName, propertyExpression ->
275             val propertyAssignmentExpression = PropertyAssignmentService(this)
276             propertyAssignmentValue[propertyName] = propertyAssignmentExpression.resolveAssignmentExpression(name,
277                     propertyName, propertyExpression)
278         }
279         return propertyAssignmentValue
280     }
281
282     override fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, JsonNode> {
283         log.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)
284
285         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
286
287         val propertyAssignments: MutableMap<String, JsonNode> = nodeTemplate.properties!!
288
289         // Get the Node Type Definitions
290         val nodeTypePropertieDefinitions: MutableMap<String, PropertyDefinition> = bluePrintContext
291                 .nodeTypeChainedProperties(nodeTemplate.type)!!
292
293         /**
294          * Resolve the NodeTemplate Property Assignment Values.
295          */
296         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypePropertieDefinitions,
297                 propertyAssignments)
298     }
299
300     override fun resolveNodeTemplateCapabilityProperties(nodeTemplateName: String, capabilityName: String):
301             MutableMap<String, JsonNode> {
302         log.info("resolveNodeTemplateCapabilityProperties for node template($nodeTemplateName) capability " +
303                 "($capabilityName)")
304         val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
305
306         val propertyAssignments = nodeTemplate.capabilities?.get(capabilityName)?.properties ?: hashMapOf()
307
308         val propertyDefinitions = bluePrintContext.nodeTemplateNodeType(nodeTemplateName)
309                 .capabilities?.get(capabilityName)?.properties ?: hashMapOf()
310
311         /**
312          * Resolve the Capability Property Assignment Values.
313          */
314         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, propertyDefinitions,
315                 propertyAssignments)
316     }
317
318     override fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,
319                                                              interfaceName: String,
320                                                              operationName: String): MutableMap<String, JsonNode> {
321         log.info("resolveNodeTemplateInterfaceOperationInputs for node template ($nodeTemplateName),interface name " +
322                 "($interfaceName), operationName($operationName)")
323
324         val propertyAssignments: MutableMap<String, JsonNode> =
325                 bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName)
326                         ?: hashMapOf()
327
328         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
329
330         val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =
331                 bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)
332                         ?: hashMapOf()
333
334         log.info("input definition for node template ($nodeTemplateName), values ($propertyAssignments)")
335
336         /**
337          * Resolve the Property Input Assignment Values.
338          */
339         return resolveNodeTemplatePropertyAssignments(nodeTemplateName, nodeTypeInterfaceOperationInputs,
340                 propertyAssignments)
341
342     }
343
344
345     override fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,
346                                                               interfaceName: String,
347                                                               operationName: String): MutableMap<String, JsonNode> {
348         log.info("resolveNodeTemplateInterfaceOperationOutputs for node template ($nodeTemplateName),interface name " +
349                 "($interfaceName), operationName($operationName)")
350
351         val propertyAssignments: MutableMap<String, JsonNode> =
352                 bluePrintContext.nodeTemplateInterfaceOperationOutputs(nodeTemplateName, interfaceName, operationName)
353                         ?: hashMapOf()
354
355         val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type
356
357         val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =
358                 bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)
359                         ?: hashMapOf()
360         /**
361          * Resolve the Property Output Assignment Values.
362          */
363         val propertyAssignmentValue = resolveNodeTemplatePropertyAssignments(nodeTemplateName,
364                 nodeTypeInterfaceOperationOutputs, propertyAssignments)
365
366         // Store  operation output values into context
367         propertyAssignmentValue.forEach { key, value ->
368             setNodeTemplateOperationOutputValue(nodeTemplateName, interfaceName, operationName, key, value)
369         }
370         return propertyAssignmentValue
371     }
372
373     override fun resolveNodeTemplateArtifact(nodeTemplateName: String, artifactName: String): String {
374         val artifactDefinition: ArtifactDefinition =
375                 resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
376         val propertyAssignmentExpression = PropertyAssignmentService(this)
377         return propertyAssignmentExpression.artifactContent(artifactDefinition)
378     }
379
380     override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String,
381                                                        artifactName: String): ArtifactDefinition {
382         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
383
384         return nodeTemplate.artifacts?.get(artifactName)
385                 ?: throw BluePrintProcessorException("failed to get artifact definition($artifactName) from the node " +
386                         "template")
387
388     }
389
390     /**
391      * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json
392      * Type
393      */
394     override fun resolveDSLExpression(dslPropertyName: String): JsonNode {
395         val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName)
396         return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments)
397                 && propertyAssignments is ObjectNode) {
398
399             val rootKeyMap = propertyAssignments.rootFieldsToMap()
400             val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
401             rootKeyMap.forEach { propertyName, propertyValue ->
402                 val propertyAssignmentExpression = PropertyAssignmentService(this)
403                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression
404                         .resolveAssignmentExpression("DSL", propertyName, propertyValue)
405             }
406             propertyAssignmentValue.asJsonNode()
407         } else {
408             propertyAssignments
409         }
410     }
411
412     override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
413         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
414                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
415         log.trace("setting input path ({}), values ({})", path, value)
416         put(path, value)
417     }
418
419     override fun setWorkflowInputValue(workflowName: String, propertyName: String,
420                                        propertyDefinition: PropertyDefinition, value: JsonNode) {
421         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
422                 .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
423                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
424                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
425                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
426         put(path, value)
427     }
428
429     override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
430
431         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
432                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
433                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
434                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
435         put(path, value)
436     }
437
438     override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
439
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         put(path, value)
445     }
446
447     override fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String,
448                                                        operationName: String, propertyName: String,
449                                                        value: JsonNode) {
450         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
451                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
452                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
453                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
454                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
455                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
456                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
457                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
458         log.trace("setting operation property path ({}), values ({})", path, value)
459         put(path, value)
460     }
461
462     override fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
463                                                     operationName: String, propertyName: String,
464                                                     value: JsonNode) {
465         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
466                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
467                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
468                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
469                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
470                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
471                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
472                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
473                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
474         put(path, value)
475     }
476
477     override fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
478                                                      operationName: String, propertyName: String,
479                                                      value: JsonNode) {
480         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
481                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
482                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
483                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
484                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
485                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
486                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
487                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
488                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
489         put(path, value)
490     }
491
492
493     override fun getInputValue(propertyName: String): JsonNode {
494         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
495                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
496         return getJsonNode(path)
497     }
498
499     override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
500                                                      operationName: String, propertyName: String): JsonNode {
501         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
502                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
503                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
504                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
505                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
506                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
507                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
508                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
509                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
510         return getJsonNode(path)
511     }
512
513     override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
514         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
515                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
516                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
517                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
518         return getJsonNode(path)
519     }
520
521     override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
522         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
523                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
524                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
525                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
526         return getJsonNode(path)
527     }
528
529     override fun assignInputs(jsonNode: JsonNode) {
530         log.info("assignInputs from input JSON ({})", jsonNode.toString())
531         bluePrintContext.inputs()?.forEach { propertyName, property ->
532             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
533                     ?: NullNode.getInstance()
534             setInputValue(propertyName, property, valueNode)
535         }
536     }
537
538     override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {
539         log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())
540
541         val dynamicInputPropertiesName = "$workflowName-properties"
542
543         bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
544             if (propertyName != dynamicInputPropertiesName) {
545                 val valueNode: JsonNode = jsonNode
546                         .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
547                         ?: property.defaultValue
548                         ?: NullNode.getInstance()
549                 setInputValue(propertyName, property, valueNode)
550             }
551         }
552         // Load Dynamic data Types
553         val workflowDynamicInputs: JsonNode? = jsonNode.get(dynamicInputPropertiesName)
554
555         workflowDynamicInputs?.let {
556             bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")
557                     ?.properties?.forEach { propertyName, property ->
558                 val valueNode: JsonNode =
559                         workflowDynamicInputs
560                                 .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
561                                 ?: property.defaultValue
562                                 ?: NullNode.getInstance()
563                 setInputValue(propertyName, property, valueNode)
564
565             }
566         }
567     }
568
569     override fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode> {
570         log.info("resolveWorkflowOutputs for workflow($workflowName)")
571         val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf()
572         return resolvePropertyDefinitions("WORKFLOW", outputs)
573     }
574
575     override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {
576
577         val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
578         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
579                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
580                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
581                 .append(BluePrintConstants.PATH_DIVIDER).toString()
582         store.keys.filter {
583             it.startsWith(path)
584         }.map {
585             val key = it.replace(path, "")
586             if (keys.contains(key)) {
587                 val value = store[it] as JsonNode
588                 jsonNode.set(key, value)
589             }
590         }
591         return jsonNode
592     }
593
594
595 }