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