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