Add dynamic-properties as python script arg
[ccsdk/cds.git] / ms / controllerblueprints / modules / 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.*
23 import kotlin.reflect.KClass
24 import kotlin.reflect.full.createInstance
25 import kotlin.reflect.jvm.reflect
26
27 class TopologyTemplateBuilder {
28     private var topologyTemplate = TopologyTemplate()
29     private var nodeTemplates: MutableMap<String, NodeTemplate>? = null
30     private var workflows: MutableMap<String, Workflow>? = null
31
32     fun nodeTemplate(id: String, type: String, description: String, block: NodeTemplateBuilder.() -> Unit) {
33         if (nodeTemplates == null)
34             nodeTemplates = hashMapOf()
35         nodeTemplates!![id] = NodeTemplateBuilder(id, type, description).apply(block).build()
36     }
37
38     fun nodeTemplate(nodeTemplate: NodeTemplate) {
39         if (nodeTemplates == null)
40             nodeTemplates = hashMapOf()
41         nodeTemplates!![nodeTemplate.id!!] = nodeTemplate
42     }
43
44     fun nodeTemplateOperation(nodeTemplateName: String, type: String, interfaceName: String, description: String,
45                               operationBlock: OperationAssignmentBuilder<PropertiesAssignmentBuilder,
46                                       PropertiesAssignmentBuilder>.() -> Unit) {
47         if (nodeTemplates == null)
48             nodeTemplates = hashMapOf()
49
50         val nodeTemplateBuilder = NodeTemplateBuilder(nodeTemplateName, type, description)
51         nodeTemplateBuilder.operation(interfaceName, "$description operation", operationBlock)
52         nodeTemplates!![nodeTemplateName] = nodeTemplateBuilder.build()
53     }
54
55     fun workflow(id: String, description: String, block: WorkflowBuilder.() -> Unit) {
56         if (workflows == null)
57             workflows = hashMapOf()
58         workflows!![id] = WorkflowBuilder(id, description).apply(block).build()
59     }
60
61     fun workflow(workflow: Workflow) {
62         if (workflows == null)
63             workflows = hashMapOf()
64         workflows!![workflow.id!!] = workflow
65     }
66
67     //TODO("populate inputs, outputs")
68     fun workflowNodeTemplate(actionName: String,
69                              nodeTemplateType: String, description: String, block: NodeTemplateBuilder.() -> Unit) {
70         if (nodeTemplates == null)
71             nodeTemplates = hashMapOf()
72
73         if (workflows == null)
74             workflows = hashMapOf()
75
76         val workflowBuilder = WorkflowBuilder(actionName, description)
77         workflowBuilder.nodeTemplateStep(actionName, description)
78         // Workflow name is NodeTemplate name
79         workflows!![actionName] = workflowBuilder.build()
80
81         nodeTemplates!![actionName] = NodeTemplateBuilder(actionName, nodeTemplateType, description).apply(block).build()
82     }
83
84     fun build(): TopologyTemplate {
85         topologyTemplate.nodeTemplates = nodeTemplates
86         topologyTemplate.workflows = workflows
87         return topologyTemplate
88     }
89 }
90
91 open class NodeTemplateBuilder(private val id: String,
92                                private val type: String,
93                                private val description: String? = "") {
94     private var nodeTemplate: NodeTemplate = NodeTemplate()
95     private var properties: MutableMap<String, JsonNode>? = null
96     private var interfaces: MutableMap<String, InterfaceAssignment>? = null
97     private var artifacts: MutableMap<String, ArtifactDefinition>? = null
98     private var capabilities: MutableMap<String, CapabilityAssignment>? = null
99     private var requirements: MutableMap<String, RequirementAssignment>? = null
100
101     fun properties(properties: MutableMap<String, JsonNode>?) {
102         this.properties = properties
103     }
104
105     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
106         if (properties == null)
107             properties = hashMapOf()
108         properties = PropertiesAssignmentBuilder().apply(block).build()
109     }
110
111     open fun <In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder> typedOperation(
112             interfaceName: String, description: String = "",
113             block: OperationAssignmentBuilder<In, Out>.() -> Unit) {
114         if (interfaces == null)
115             interfaces = hashMapOf()
116
117         val interfaceAssignment = InterfaceAssignment()
118         val defaultOperationName = BluePrintConstants.DEFAULT_STEP_OPERATION
119         interfaceAssignment.operations = hashMapOf()
120         interfaceAssignment.operations!![defaultOperationName] =
121                 OperationAssignmentBuilder<In, Out>(defaultOperationName, description).apply(block).build()
122         interfaces!![interfaceName] = interfaceAssignment
123     }
124
125     fun operation(interfaceName: String, description: String,
126                   block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit) {
127         typedOperation<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(interfaceName, description, block)
128     }
129
130     fun artifact(id: String, type: String, file: String) {
131         if (artifacts == null)
132             artifacts = hashMapOf()
133         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).build()
134     }
135
136     fun artifact(id: String, type: String, file: String, block: ArtifactDefinitionBuilder.() -> Unit) {
137         if (artifacts == null)
138             artifacts = hashMapOf()
139         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).apply(block).build()
140     }
141
142     fun artifacts(artifacts: MutableMap<String, ArtifactDefinition>?) {
143         this.artifacts = artifacts
144     }
145
146     fun capability(id: String, block: CapabilityAssignmentBuilder.() -> Unit) {
147         if (capabilities == null)
148             capabilities = hashMapOf()
149         capabilities!![id] = CapabilityAssignmentBuilder(id).apply(block).build()
150     }
151
152     fun capabilities(capabilities: MutableMap<String, CapabilityAssignment>?) {
153         this.capabilities = capabilities
154     }
155
156     fun requirement(id: String, capability: String, node: String, relationship: String) {
157         if (requirements == null)
158             requirements = hashMapOf()
159         requirements!![id] = RequirementAssignmentBuilder(id, capability, node, relationship).build()
160     }
161
162     fun requirements(requirements: MutableMap<String, RequirementAssignment>?) {
163         this.requirements = requirements
164     }
165
166     fun build(): NodeTemplate {
167         nodeTemplate.id = id
168         nodeTemplate.type = type
169         nodeTemplate.description = description
170         nodeTemplate.properties = properties
171         nodeTemplate.interfaces = interfaces
172         nodeTemplate.artifacts = artifacts
173         nodeTemplate.capabilities = capabilities
174         nodeTemplate.requirements = requirements
175         return nodeTemplate
176     }
177 }
178
179 class ArtifactDefinitionBuilder(private val id: String, private val type: String, private val file: String) {
180
181     private var artifactDefinition: ArtifactDefinition = ArtifactDefinition()
182     private var properties: MutableMap<String, JsonNode>? = null
183
184     fun repository(repository: String) {
185         artifactDefinition.repository = repository
186     }
187
188     fun deployPath(deployPath: String) {
189         artifactDefinition.deployPath = deployPath
190     }
191
192     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
193         if (properties == null)
194             properties = hashMapOf()
195         properties = PropertiesAssignmentBuilder().apply(block).build()
196     }
197
198     fun build(): ArtifactDefinition {
199         artifactDefinition.id = id
200         artifactDefinition.type = type
201         artifactDefinition.file = file
202         artifactDefinition.properties = properties
203         return artifactDefinition
204     }
205 }
206
207 open class CapabilityAssignmentBuilder(private val id: String) {
208     var capabilityAssignment: CapabilityAssignment = CapabilityAssignment()
209     var attributes: MutableMap<String, JsonNode>? = null
210     var properties: MutableMap<String, JsonNode>? = null
211
212     fun attributes(block: AttributesAssignmentBuilder.() -> Unit) {
213         if (attributes == null)
214             attributes = hashMapOf()
215         attributes = AttributesAssignmentBuilder().apply(block).build()
216     }
217
218     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
219         if (properties == null)
220             properties = hashMapOf()
221         properties = PropertiesAssignmentBuilder().apply(block).build()
222     }
223
224     fun build(): CapabilityAssignment {
225         capabilityAssignment.properties = properties
226         capabilityAssignment.attributes = attributes
227         return capabilityAssignment
228     }
229 }
230
231 open class RequirementAssignmentBuilder(private val id: String, private val capability: String,
232                                         private val node: String,
233                                         private val relationship: String) {
234     private var requirementAssignment: RequirementAssignment = RequirementAssignment()
235
236     fun build(): RequirementAssignment {
237         requirementAssignment.id = id
238         requirementAssignment.capability = capability
239         requirementAssignment.node = node
240         requirementAssignment.relationship = relationship
241         return requirementAssignment
242     }
243 }
244
245 class InterfaceAssignmentBuilder(private val id: String) {
246
247     private var interfaceAssignment: InterfaceAssignment = InterfaceAssignment()
248     private var operations: MutableMap<String, OperationAssignment>? = null
249
250     fun operation(id: String, description: String? = "",
251                   block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit) {
252         if (operations == null)
253             operations = hashMapOf()
254         operations!![id] = OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(
255                 id, description).apply(block).build()
256     }
257
258     fun build(): InterfaceAssignment {
259         interfaceAssignment.id = id
260         interfaceAssignment.operations = operations
261         return interfaceAssignment
262     }
263 }
264
265 class OperationAssignmentBuilder<In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder>(
266         private val id: String,
267         private val description: String? = "") {
268
269     private var operationAssignment: OperationAssignment = OperationAssignment()
270
271     fun implementation(implementation: Implementation?) {
272         operationAssignment.implementation = implementation
273     }
274
275     fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF) {
276         operationAssignment.implementation = Implementation().apply {
277             this.operationHost = operationHost!!
278             this.timeout = timeout
279         }
280     }
281
282     fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF,
283                        block: ImplementationBuilder.() -> Unit) {
284         operationAssignment.implementation = ImplementationBuilder(timeout, operationHost!!).apply(block).build()
285     }
286
287     fun inputs(inputs: MutableMap<String, JsonNode>?) {
288         operationAssignment.inputs = inputs
289     }
290
291     fun inputs(block: In.() -> Unit) {
292         val instance: In = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<In>).createInstance()
293         operationAssignment.inputs = instance.apply(block).build()
294     }
295
296     fun outputs(outputs: MutableMap<String, JsonNode>?) {
297         operationAssignment.outputs = outputs
298     }
299
300     fun outputs(block: Out.() -> Unit) {
301         val instance: Out = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Out>).createInstance()
302         operationAssignment.outputs = instance.apply(block).build()
303     }
304
305     fun build(): OperationAssignment {
306         operationAssignment.id = id
307         operationAssignment.description = description
308         return operationAssignment
309     }
310 }
311
312 class ImplementationBuilder(private val timeout: Int, private val operationHost: String) {
313     private val implementation = Implementation()
314
315     fun primary(primary: String) {
316         implementation.primary = primary
317     }
318
319     fun dependencies(vararg dependencies: String) {
320         if (implementation.dependencies == null)
321             implementation.dependencies = arrayListOf()
322         dependencies.forEach {
323             implementation.dependencies!!.add(it)
324         }
325     }
326
327     fun build(): Implementation {
328         implementation.timeout = timeout
329         implementation.operationHost = operationHost
330         return implementation
331     }
332 }
333
334 open class PropertiesAssignmentBuilder {
335     var properties: MutableMap<String, JsonNode> = hashMapOf()
336
337     fun property(id: String, value: Any) {
338         property(id, value.asJsonType())
339     }
340
341     fun property(id: String, value: JsonNode) {
342         properties[id] = value
343     }
344
345     open fun build(): MutableMap<String, JsonNode> {
346         return properties
347     }
348 }
349
350 open class AttributesAssignmentBuilder {
351     var attributes: MutableMap<String, JsonNode> = hashMapOf()
352
353     fun attribute(id: String, value: String) {
354         attribute(id, value.asJsonType())
355     }
356
357     fun attribute(id: String, value: JsonNode) {
358         attributes[id] = value
359     }
360
361     fun build(): MutableMap<String, JsonNode> {
362         return attributes
363     }
364 }