Removed redundant timeout handling for executeCommand
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / blueprints / blueprint-core / src / main / kotlin / org / onap / ccsdk / cds / controllerblueprints / core / dsl / BlueprintTemplateDSLBuilder.kt
1 /*
2  *  Copyright © 2019 IBM.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 package org.onap.ccsdk.cds.controllerblueprints.core.dsl
18
19 import com.fasterxml.jackson.databind.JsonNode
20 import org.onap.ccsdk.cds.controllerblueprints.core.BlueprintConstants
21 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
22 import org.onap.ccsdk.cds.controllerblueprints.core.data.ArtifactDefinition
23 import org.onap.ccsdk.cds.controllerblueprints.core.data.CapabilityAssignment
24 import org.onap.ccsdk.cds.controllerblueprints.core.data.Implementation
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.InterfaceAssignment
26 import org.onap.ccsdk.cds.controllerblueprints.core.data.NodeTemplate
27 import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationAssignment
28 import org.onap.ccsdk.cds.controllerblueprints.core.data.RelationshipTemplate
29 import org.onap.ccsdk.cds.controllerblueprints.core.data.RequirementAssignment
30 import org.onap.ccsdk.cds.controllerblueprints.core.data.TopologyTemplate
31 import org.onap.ccsdk.cds.controllerblueprints.core.data.Workflow
32 import kotlin.reflect.KClass
33 import kotlin.reflect.KMutableProperty1
34 import kotlin.reflect.full.createInstance
35 import kotlin.reflect.jvm.reflect
36
37 open class TopologyTemplateBuilder {
38
39     private var topologyTemplate = TopologyTemplate()
40     var nodeTemplates: MutableMap<String, NodeTemplate>? = null
41     var relationshipTemplates: MutableMap<String, RelationshipTemplate>? = null
42     private var workflows: MutableMap<String, Workflow>? = null
43
44     fun nodeTemplate(id: String, type: String, description: String, block: NodeTemplateBuilder.() -> Unit) {
45         if (nodeTemplates == null) nodeTemplates = hashMapOf()
46         nodeTemplates!![id] = NodeTemplateBuilder(id, type, description).apply(block).build()
47     }
48
49     fun nodeTemplate(nodeTemplate: NodeTemplate) {
50         if (nodeTemplates == null) nodeTemplates = hashMapOf()
51         nodeTemplates!![nodeTemplate.id!!] = nodeTemplate
52     }
53
54     fun relationshipTemplate(
55         id: String,
56         type: String,
57         description: String,
58         block: RelationshipTemplateBuilder.() -> Unit
59     ) {
60         if (relationshipTemplates == null) relationshipTemplates = hashMapOf()
61         relationshipTemplates!![id] = RelationshipTemplateBuilder(id, type, description).apply(block).build()
62     }
63
64     fun relationshipTemplate(relationshipTemplate: RelationshipTemplate) {
65         if (relationshipTemplates == null) relationshipTemplates = hashMapOf()
66         relationshipTemplates!![relationshipTemplate.id!!] = relationshipTemplate
67     }
68
69     fun nodeTemplateOperation(
70         nodeTemplateName: String,
71         type: String,
72         interfaceName: String,
73         description: String,
74         operationBlock: OperationAssignmentBuilder<PropertiesAssignmentBuilder,
75             PropertiesAssignmentBuilder>.() -> Unit
76     ) {
77         if (nodeTemplates == null) nodeTemplates = hashMapOf()
78
79         val nodeTemplateBuilder = NodeTemplateBuilder(nodeTemplateName, type, description)
80         nodeTemplateBuilder.operation(interfaceName, "$description operation", operationBlock)
81         nodeTemplates!![nodeTemplateName] = nodeTemplateBuilder.build()
82     }
83
84     fun workflow(id: String, description: String, block: WorkflowBuilder.() -> Unit) {
85         if (workflows == null) workflows = hashMapOf()
86         workflows!![id] = WorkflowBuilder(id, description).apply(block).build()
87     }
88
89     fun workflow(workflow: Workflow) {
90         if (workflows == null) workflows = hashMapOf()
91         workflows!![workflow.id!!] = workflow
92     }
93
94     // TODO("populate inputs, outputs")
95     fun workflowNodeTemplate(
96         actionName: String,
97         nodeTemplateType: String,
98         description: String,
99         block: NodeTemplateBuilder.() -> Unit
100     ) {
101         if (nodeTemplates == null) nodeTemplates = hashMapOf()
102
103         if (workflows == null) workflows = hashMapOf()
104
105         val workflowBuilder = WorkflowBuilder(actionName, description)
106         workflowBuilder.nodeTemplateStep(actionName, description)
107         // Workflow name is NodeTemplate name
108         workflows!![actionName] = workflowBuilder.build()
109
110         nodeTemplates!![actionName] =
111             NodeTemplateBuilder(actionName, nodeTemplateType, description).apply(block).build()
112     }
113
114     fun build(): TopologyTemplate {
115         topologyTemplate.nodeTemplates = nodeTemplates
116         topologyTemplate.relationshipTemplates = relationshipTemplates
117         topologyTemplate.workflows = workflows
118         return topologyTemplate
119     }
120 }
121
122 open class NodeTemplateBuilder(
123     private val id: String,
124     private val type: String,
125     private val description: String? = ""
126 ) {
127
128     var nodeTemplate: NodeTemplate = NodeTemplate()
129     var properties: MutableMap<String, JsonNode>? = null
130     var interfaces: MutableMap<String, InterfaceAssignment>? = null
131     var artifacts: MutableMap<String, ArtifactDefinition>? = null
132     var capabilities: MutableMap<String, CapabilityAssignment>? = null
133     var requirements: MutableMap<String, RequirementAssignment>? = null
134
135     fun properties(properties: Map<String, JsonNode>) {
136         if (this.properties == null) this.properties = hashMapOf()
137         this.properties!!.putAll(properties)
138     }
139
140     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
141         if (properties == null) properties = hashMapOf()
142         properties = PropertiesAssignmentBuilder().apply(block).build()
143     }
144
145     open fun <Prop : PropertiesAssignmentBuilder> typedProperties(block: Prop.() -> Unit) {
146         if (properties == null) properties = hashMapOf()
147         val instance: Prop = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Prop>).createInstance()
148         properties = instance.apply(block).build()
149     }
150
151     open fun <In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder> typedOperation(
152         interfaceName: String,
153         description: String = "",
154         block: OperationAssignmentBuilder<In, Out>.() -> Unit
155     ) {
156         if (interfaces == null) interfaces = hashMapOf()
157
158         val interfaceAssignment = InterfaceAssignment()
159         val defaultOperationName = BlueprintConstants.DEFAULT_STEP_OPERATION
160         interfaceAssignment.operations = hashMapOf()
161         interfaceAssignment.operations!![defaultOperationName] =
162             OperationAssignmentBuilder<In, Out>(defaultOperationName, description).apply(block).build()
163         interfaces!![interfaceName] = interfaceAssignment
164     }
165
166     fun operation(
167         interfaceName: String,
168         description: String,
169         block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit
170     ) {
171         typedOperation<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(interfaceName, description, block)
172     }
173
174     fun artifact(id: String, type: String, file: String) {
175         if (artifacts == null) artifacts = hashMapOf()
176         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).build()
177     }
178
179     fun artifact(id: String, type: String, file: String, block: ArtifactDefinitionBuilder.() -> Unit) {
180         if (artifacts == null) artifacts = hashMapOf()
181         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).apply(block).build()
182     }
183
184     fun artifacts(artifacts: MutableMap<String, ArtifactDefinition>?) {
185         this.artifacts = artifacts
186     }
187
188     fun capability(id: String, block: CapabilityAssignmentBuilder.() -> Unit) {
189         if (capabilities == null) capabilities = hashMapOf()
190         capabilities!![id] = CapabilityAssignmentBuilder(id).apply(block).build()
191     }
192
193     fun capabilities(capabilities: MutableMap<String, CapabilityAssignment>) {
194         if (this.capabilities == null) this.capabilities = hashMapOf()
195         this.capabilities!!.putAll(capabilities)
196     }
197
198     fun requirement(id: String, capability: String, node: String, relationship: String) {
199         if (requirements == null) requirements = hashMapOf()
200         requirements!![id] = RequirementAssignmentBuilder(id, capability, node, relationship).build()
201     }
202
203     fun requirements(requirements: MutableMap<String, RequirementAssignment>) {
204         if (this.requirements == null) this.requirements = hashMapOf()
205         this.requirements!!.putAll(requirements)
206     }
207
208     open fun build(): NodeTemplate {
209         nodeTemplate.id = id
210         nodeTemplate.type = type
211         nodeTemplate.description = description
212         nodeTemplate.properties = properties
213         nodeTemplate.interfaces = interfaces
214         nodeTemplate.artifacts = artifacts
215         nodeTemplate.capabilities = capabilities
216         nodeTemplate.requirements = requirements
217         return nodeTemplate
218     }
219 }
220
221 open class RelationshipTemplateBuilder(
222     private val id: String,
223     private val type: String,
224     private val description: String? = ""
225 ) {
226
227     var relationshipTemplate: RelationshipTemplate = RelationshipTemplate()
228     var properties: MutableMap<String, JsonNode>? = null
229
230     fun properties(properties: Map<String, JsonNode>) {
231         if (this.properties == null) this.properties = hashMapOf()
232         this.properties!!.putAll(properties)
233     }
234
235     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
236         if (properties == null) properties = hashMapOf()
237         properties = PropertiesAssignmentBuilder().apply(block).build()
238     }
239
240     fun property(id: String, value: Any) {
241         if (properties == null) properties = hashMapOf()
242         properties!![id] = value.asJsonType()
243     }
244
245     fun property(id: String, value: JsonNode) {
246         if (properties == null) properties = hashMapOf()
247         properties!![id] = value
248     }
249
250     fun copy(copy: String) {
251         relationshipTemplate.copy = copy
252     }
253
254     open fun <Prop : PropertiesAssignmentBuilder> typedProperties(block: Prop.() -> Unit) {
255         if (properties == null) properties = hashMapOf()
256         val instance: Prop = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Prop>).createInstance()
257         properties = instance.apply(block).build()
258     }
259
260     open fun build(): RelationshipTemplate {
261         relationshipTemplate.id = id
262         relationshipTemplate.type = type
263         relationshipTemplate.description = description
264         relationshipTemplate.properties = properties
265         return relationshipTemplate
266     }
267 }
268
269 class ArtifactDefinitionBuilder(private val id: String, private val type: String, private val file: String) {
270
271     private var artifactDefinition: ArtifactDefinition = ArtifactDefinition()
272     private var properties: MutableMap<String, JsonNode>? = null
273
274     fun repository(repository: String) {
275         artifactDefinition.repository = repository
276     }
277
278     fun deployPath(deployPath: String) {
279         artifactDefinition.deployPath = deployPath
280     }
281
282     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
283         if (properties == null)
284             properties = hashMapOf()
285         properties = PropertiesAssignmentBuilder().apply(block).build()
286     }
287
288     fun build(): ArtifactDefinition {
289         artifactDefinition.id = id
290         artifactDefinition.type = type
291         artifactDefinition.file = file
292         artifactDefinition.properties = properties
293         return artifactDefinition
294     }
295 }
296
297 open class CapabilityAssignmentBuilder(private val id: String) {
298
299     var capabilityAssignment: CapabilityAssignment = CapabilityAssignment()
300     var attributes: MutableMap<String, JsonNode>? = null
301     var properties: MutableMap<String, JsonNode>? = null
302
303     fun attributes(block: AttributesAssignmentBuilder.() -> Unit) {
304         if (attributes == null) attributes = hashMapOf()
305         attributes = AttributesAssignmentBuilder().apply(block).build()
306     }
307
308     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
309         if (properties == null) properties = hashMapOf()
310         properties = PropertiesAssignmentBuilder().apply(block).build()
311     }
312
313     fun property(id: String, value: Any) {
314         if (properties == null) properties = hashMapOf()
315         properties!![id] = value.asJsonType()
316     }
317
318     fun property(id: String, value: JsonNode) {
319         if (properties == null) properties = hashMapOf()
320         properties!![id] = value
321     }
322
323     open fun build(): CapabilityAssignment {
324         capabilityAssignment.properties = properties
325         capabilityAssignment.attributes = attributes
326         return capabilityAssignment
327     }
328 }
329
330 open class RequirementAssignmentBuilder(
331     private val id: String,
332     private val capability: String,
333     private val node: String,
334     private val relationship: String
335 ) {
336
337     private var requirementAssignment: RequirementAssignment = RequirementAssignment()
338
339     fun build(): RequirementAssignment {
340         requirementAssignment.id = id
341         requirementAssignment.capability = capability
342         requirementAssignment.node = node
343         requirementAssignment.relationship = relationship
344         return requirementAssignment
345     }
346 }
347
348 class InterfaceAssignmentBuilder(private val id: String) {
349
350     private var interfaceAssignment: InterfaceAssignment = InterfaceAssignment()
351     private var operations: MutableMap<String, OperationAssignment>? = null
352
353     fun operation(
354         id: String,
355         description: String? = "",
356         block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit
357     ) {
358         if (operations == null)
359             operations = hashMapOf()
360         operations!![id] = OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(
361             id, description
362         ).apply(block).build()
363     }
364
365     fun build(): InterfaceAssignment {
366         interfaceAssignment.id = id
367         interfaceAssignment.operations = operations
368         return interfaceAssignment
369     }
370 }
371
372 class OperationAssignmentBuilder<In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder>(
373     private val id: String,
374     private val description: String? = ""
375 ) {
376
377     private var operationAssignment: OperationAssignment = OperationAssignment()
378
379     fun implementation(implementation: Implementation?) {
380         operationAssignment.implementation = implementation
381     }
382
383     fun implementation(timeout: Int, operationHost: String? = BlueprintConstants.PROPERTY_SELF) {
384         operationAssignment.implementation = Implementation().apply {
385             this.operationHost = operationHost!!
386             this.timeout = timeout
387         }
388     }
389
390     fun implementation(
391         timeout: Int,
392         operationHost: String? = BlueprintConstants.PROPERTY_SELF,
393         block: ImplementationBuilder.() -> Unit
394     ) {
395         operationAssignment.implementation = ImplementationBuilder(timeout, operationHost!!).apply(block).build()
396     }
397
398     fun inputs(inputs: MutableMap<String, JsonNode>?) {
399         operationAssignment.inputs = inputs
400     }
401
402     fun inputs(block: In.() -> Unit) {
403         val instance: In = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<In>).createInstance()
404         operationAssignment.inputs = instance.apply(block).build()
405     }
406
407     fun outputs(outputs: MutableMap<String, JsonNode>?) {
408         operationAssignment.outputs = outputs
409     }
410
411     fun outputs(block: Out.() -> Unit) {
412         val instance: Out = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Out>).createInstance()
413         operationAssignment.outputs = instance.apply(block).build()
414     }
415
416     fun build(): OperationAssignment {
417         operationAssignment.id = id
418         operationAssignment.description = description
419         return operationAssignment
420     }
421 }
422
423 class ImplementationBuilder(private val timeout: Int, private val operationHost: String) {
424
425     private val implementation = Implementation()
426
427     fun primary(primary: String) {
428         implementation.primary = primary
429     }
430
431     fun dependencies(vararg dependencies: String) {
432         if (implementation.dependencies == null)
433             implementation.dependencies = arrayListOf()
434         dependencies.forEach {
435             implementation.dependencies!!.add(it)
436         }
437     }
438
439     fun build(): Implementation {
440         implementation.timeout = timeout
441         implementation.operationHost = operationHost
442         return implementation
443     }
444 }
445
446 open class PropertiesAssignmentBuilder {
447
448     var properties: MutableMap<String, JsonNode> = hashMapOf()
449
450     fun property(id: String, value: Any) {
451         property(id, value.asJsonType())
452     }
453
454     fun property(id: String, value: JsonNode) {
455         properties[id] = value
456     }
457
458     fun property(kProperty: KMutableProperty1<*, *>, value: JsonNode) {
459         properties[kProperty.name] = value
460     }
461
462     open fun build(): MutableMap<String, JsonNode> {
463         return properties
464     }
465 }
466
467 open class AttributesAssignmentBuilder {
468
469     var attributes: MutableMap<String, JsonNode> = hashMapOf()
470
471     fun attribute(id: String, value: String) {
472         attribute(id, value.asJsonType())
473     }
474
475     fun attribute(id: String, value: JsonNode) {
476         attributes[id] = value
477     }
478
479     fun build(): MutableMap<String, JsonNode> {
480         return attributes
481     }
482 }