ba210df104762670feb1601533678a4fbac464a9
[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, Bell Canada.
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.asJsonType())
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             }
241
242             // Set default value if null
243             if (resolvedValue is NullNode) {
244                 nodeTypeProperty.defaultValue?.let { 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 =
374                 resolveNodeTemplateArtifactDefinition(nodeTemplateName, artifactName)
375         val propertyAssignmentExpression = PropertyAssignmentService(this)
376         return propertyAssignmentExpression.artifactContent(artifactDefinition)
377     }
378
379     override fun resolveNodeTemplateArtifactDefinition(nodeTemplateName: String,
380                                                        artifactName: String): ArtifactDefinition {
381         val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)
382
383         return nodeTemplate.artifacts?.get(artifactName)
384                 ?: throw BluePrintProcessorException("failed to get artifact definition($artifactName) from the node " +
385                         "template")
386
387     }
388
389     /**
390      * Read the DSL Property reference, If there is any expression, then resolve those expression and return as Json
391      * Type
392      */
393     override fun resolveDSLExpression(dslPropertyName: String): JsonNode {
394         val propertyAssignments = bluePrintContext.dslPropertiesByName(dslPropertyName)
395         return if (BluePrintExpressionService.checkContainsExpression(propertyAssignments)
396                 && propertyAssignments is ObjectNode) {
397
398             val rootKeyMap = propertyAssignments.rootFieldsToMap()
399             val propertyAssignmentValue: MutableMap<String, JsonNode> = hashMapOf()
400             rootKeyMap.forEach { propertyName, propertyValue ->
401                 val propertyAssignmentExpression = PropertyAssignmentService(this)
402                 propertyAssignmentValue[propertyName] = propertyAssignmentExpression
403                         .resolveAssignmentExpression("DSL", propertyName, propertyValue)
404             }
405             propertyAssignmentValue.asJsonNode()
406         } else {
407             propertyAssignments
408         }
409     }
410
411     override fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode) {
412         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
413                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
414         log.trace("setting input path ({}), values ({})", path, value)
415         put(path, value)
416     }
417
418     override fun setWorkflowInputValue(workflowName: String, propertyName: String,
419                                        propertyDefinition: PropertyDefinition, value: JsonNode) {
420         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_WORKFLOWS)
421                 .append(BluePrintConstants.PATH_DIVIDER).append(workflowName)
422                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
423                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
424                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
425         put(path, value)
426     }
427
428     override fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode) {
429
430         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
431                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
432                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
433                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
434         put(path, value)
435     }
436
437     override fun setNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String, value: JsonNode) {
438
439         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
440                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
441                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
442                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
443         put(path, value)
444     }
445
446     override fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String,
447                                                        operationName: String, propertyName: String,
448                                                        value: JsonNode) {
449         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
450                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
451                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
452                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
453                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
454                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
455                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
456                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
457         log.trace("setting operation property path ({}), values ({})", path, value)
458         put(path, value)
459     }
460
461     override fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String,
462                                                     operationName: String, propertyName: String,
463                                                     value: JsonNode) {
464         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
465                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
466                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
467                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
468                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
469                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
470                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INPUTS)
471                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
472                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
473         put(path, value)
474     }
475
476     override fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
477                                                      operationName: String, propertyName: String,
478                                                      value: JsonNode) {
479         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
480                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
481                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
482                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
483                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
484                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
485                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
486                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
487                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
488         put(path, value)
489     }
490
491
492     override fun getInputValue(propertyName: String): JsonNode {
493         val path = StringBuilder(BluePrintConstants.PATH_INPUTS)
494                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
495         return getJsonNode(path)
496     }
497
498     override fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String,
499                                                      operationName: String, propertyName: String): JsonNode {
500         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
501                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
502                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_INTERFACES)
503                 .append(BluePrintConstants.PATH_DIVIDER).append(interfaceName)
504                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OPERATIONS)
505                 .append(BluePrintConstants.PATH_DIVIDER).append(operationName)
506                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_OUTPUTS)
507                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
508                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
509         return getJsonNode(path)
510     }
511
512     override fun getNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String): JsonNode {
513         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
514                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
515                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_PROPERTIES)
516                 .append(BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()
517         return getJsonNode(path)
518     }
519
520     override fun getNodeTemplateAttributeValue(nodeTemplateName: String, attributeName: String): JsonNode {
521         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
522                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
523                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
524                 .append(BluePrintConstants.PATH_DIVIDER).append(attributeName).toString()
525         return getJsonNode(path)
526     }
527
528     override fun assignInputs(jsonNode: JsonNode) {
529         log.info("assignInputs from input JSON ({})", jsonNode.toString())
530         bluePrintContext.inputs()?.forEach { propertyName, property ->
531             val valueNode: JsonNode = jsonNode.at(BluePrintConstants.PATH_DIVIDER + propertyName)
532                     ?: NullNode.getInstance()
533             setInputValue(propertyName, property, valueNode)
534         }
535     }
536
537     override fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode) {
538         log.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())
539
540         val dynamicInputPropertiesName = "$workflowName-properties"
541
542         bluePrintContext.workflowByName(workflowName).inputs?.forEach { propertyName, property ->
543             if (propertyName != dynamicInputPropertiesName) {
544                 val valueNode: JsonNode = jsonNode
545                         .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
546                         ?: property.defaultValue
547                         ?: NullNode.getInstance()
548                 setInputValue(propertyName, property, valueNode)
549             }
550         }
551         // Load Dynamic data Types
552         val workflowDynamicInputs: JsonNode? = jsonNode.get(dynamicInputPropertiesName)
553
554         workflowDynamicInputs?.let {
555             bluePrintContext.dataTypeByName("dt-$dynamicInputPropertiesName")
556                     ?.properties?.forEach { propertyName, property ->
557                 val valueNode: JsonNode =
558                         workflowDynamicInputs
559                                 .at(BluePrintConstants.PATH_DIVIDER + propertyName).returnNullIfMissing()
560                                 ?: property.defaultValue
561                                 ?: NullNode.getInstance()
562                 setInputValue(propertyName, property, valueNode)
563
564             }
565         }
566     }
567
568     override fun resolveWorkflowOutputs(workflowName: String): MutableMap<String, JsonNode> {
569         log.info("resolveWorkflowOutputs for workflow($workflowName)")
570         val outputs = bluePrintContext.workflowByName(workflowName).outputs ?: mutableMapOf()
571         return resolvePropertyDefinitions("WORKFLOW", outputs)
572     }
573
574     override fun getJsonForNodeTemplateAttributeProperties(nodeTemplateName: String, keys: List<String>): JsonNode {
575
576         val jsonNode: ObjectNode = jacksonObjectMapper().createObjectNode()
577         val path: String = StringBuilder(BluePrintConstants.PATH_NODE_TEMPLATES)
578                 .append(BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)
579                 .append(BluePrintConstants.PATH_DIVIDER).append(BluePrintConstants.PATH_ATTRIBUTES)
580                 .append(BluePrintConstants.PATH_DIVIDER).toString()
581         store.keys.filter {
582             it.startsWith(path)
583         }.map {
584             val key = it.replace(path, "")
585             if (keys.contains(key)) {
586                 val value = store[it] as JsonNode
587                 jsonNode.set(key, value)
588             }
589         }
590         return jsonNode
591     }
592
593
594 }