Merge "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 <Prop : PropertiesAssignmentBuilder> typedProperties(block: Prop.() -> Unit) {
112         if (properties == null)
113             properties = hashMapOf()
114         val instance: Prop = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Prop>).createInstance()
115         properties = instance.apply(block).build()
116     }
117
118     open fun <In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder> typedOperation(
119             interfaceName: String, description: String = "",
120             block: OperationAssignmentBuilder<In, Out>.() -> Unit) {
121         if (interfaces == null)
122             interfaces = hashMapOf()
123
124         val interfaceAssignment = InterfaceAssignment()
125         val defaultOperationName = BluePrintConstants.DEFAULT_STEP_OPERATION
126         interfaceAssignment.operations = hashMapOf()
127         interfaceAssignment.operations!![defaultOperationName] =
128                 OperationAssignmentBuilder<In, Out>(defaultOperationName, description).apply(block).build()
129         interfaces!![interfaceName] = interfaceAssignment
130     }
131
132     fun operation(interfaceName: String, description: String,
133                   block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit) {
134         typedOperation<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(interfaceName, description, block)
135     }
136
137     fun artifact(id: String, type: String, file: String) {
138         if (artifacts == null)
139             artifacts = hashMapOf()
140         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).build()
141     }
142
143     fun artifact(id: String, type: String, file: String, block: ArtifactDefinitionBuilder.() -> Unit) {
144         if (artifacts == null)
145             artifacts = hashMapOf()
146         artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).apply(block).build()
147     }
148
149     fun artifacts(artifacts: MutableMap<String, ArtifactDefinition>?) {
150         this.artifacts = artifacts
151     }
152
153     fun capability(id: String, block: CapabilityAssignmentBuilder.() -> Unit) {
154         if (capabilities == null)
155             capabilities = hashMapOf()
156         capabilities!![id] = CapabilityAssignmentBuilder(id).apply(block).build()
157     }
158
159     fun capabilities(capabilities: MutableMap<String, CapabilityAssignment>?) {
160         this.capabilities = capabilities
161     }
162
163     fun requirement(id: String, capability: String, node: String, relationship: String) {
164         if (requirements == null)
165             requirements = hashMapOf()
166         requirements!![id] = RequirementAssignmentBuilder(id, capability, node, relationship).build()
167     }
168
169     fun requirements(requirements: MutableMap<String, RequirementAssignment>?) {
170         this.requirements = requirements
171     }
172
173     fun build(): NodeTemplate {
174         nodeTemplate.id = id
175         nodeTemplate.type = type
176         nodeTemplate.description = description
177         nodeTemplate.properties = properties
178         nodeTemplate.interfaces = interfaces
179         nodeTemplate.artifacts = artifacts
180         nodeTemplate.capabilities = capabilities
181         nodeTemplate.requirements = requirements
182         return nodeTemplate
183     }
184 }
185
186 class ArtifactDefinitionBuilder(private val id: String, private val type: String, private val file: String) {
187
188     private var artifactDefinition: ArtifactDefinition = ArtifactDefinition()
189     private var properties: MutableMap<String, JsonNode>? = null
190
191     fun repository(repository: String) {
192         artifactDefinition.repository = repository
193     }
194
195     fun deployPath(deployPath: String) {
196         artifactDefinition.deployPath = deployPath
197     }
198
199     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
200         if (properties == null)
201             properties = hashMapOf()
202         properties = PropertiesAssignmentBuilder().apply(block).build()
203     }
204
205     fun build(): ArtifactDefinition {
206         artifactDefinition.id = id
207         artifactDefinition.type = type
208         artifactDefinition.file = file
209         artifactDefinition.properties = properties
210         return artifactDefinition
211     }
212 }
213
214 open class CapabilityAssignmentBuilder(private val id: String) {
215     var capabilityAssignment: CapabilityAssignment = CapabilityAssignment()
216     var attributes: MutableMap<String, JsonNode>? = null
217     var properties: MutableMap<String, JsonNode>? = null
218
219     fun attributes(block: AttributesAssignmentBuilder.() -> Unit) {
220         if (attributes == null)
221             attributes = hashMapOf()
222         attributes = AttributesAssignmentBuilder().apply(block).build()
223     }
224
225     fun properties(block: PropertiesAssignmentBuilder.() -> Unit) {
226         if (properties == null)
227             properties = hashMapOf()
228         properties = PropertiesAssignmentBuilder().apply(block).build()
229     }
230
231     fun build(): CapabilityAssignment {
232         capabilityAssignment.properties = properties
233         capabilityAssignment.attributes = attributes
234         return capabilityAssignment
235     }
236 }
237
238 open class RequirementAssignmentBuilder(private val id: String, private val capability: String,
239                                         private val node: String,
240                                         private val relationship: String) {
241     private var requirementAssignment: RequirementAssignment = RequirementAssignment()
242
243     fun build(): RequirementAssignment {
244         requirementAssignment.id = id
245         requirementAssignment.capability = capability
246         requirementAssignment.node = node
247         requirementAssignment.relationship = relationship
248         return requirementAssignment
249     }
250 }
251
252 class InterfaceAssignmentBuilder(private val id: String) {
253
254     private var interfaceAssignment: InterfaceAssignment = InterfaceAssignment()
255     private var operations: MutableMap<String, OperationAssignment>? = null
256
257     fun operation(id: String, description: String? = "",
258                   block: OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>.() -> Unit) {
259         if (operations == null)
260             operations = hashMapOf()
261         operations!![id] = OperationAssignmentBuilder<PropertiesAssignmentBuilder, PropertiesAssignmentBuilder>(
262                 id, description).apply(block).build()
263     }
264
265     fun build(): InterfaceAssignment {
266         interfaceAssignment.id = id
267         interfaceAssignment.operations = operations
268         return interfaceAssignment
269     }
270 }
271
272 class OperationAssignmentBuilder<In : PropertiesAssignmentBuilder, Out : PropertiesAssignmentBuilder>(
273         private val id: String,
274         private val description: String? = "") {
275
276     private var operationAssignment: OperationAssignment = OperationAssignment()
277
278     fun implementation(implementation: Implementation?) {
279         operationAssignment.implementation = implementation
280     }
281
282     fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF) {
283         operationAssignment.implementation = Implementation().apply {
284             this.operationHost = operationHost!!
285             this.timeout = timeout
286         }
287     }
288
289     fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF,
290                        block: ImplementationBuilder.() -> Unit) {
291         operationAssignment.implementation = ImplementationBuilder(timeout, operationHost!!).apply(block).build()
292     }
293
294     fun inputs(inputs: MutableMap<String, JsonNode>?) {
295         operationAssignment.inputs = inputs
296     }
297
298     fun inputs(block: In.() -> Unit) {
299         val instance: In = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<In>).createInstance()
300         operationAssignment.inputs = instance.apply(block).build()
301     }
302
303     fun outputs(outputs: MutableMap<String, JsonNode>?) {
304         operationAssignment.outputs = outputs
305     }
306
307     fun outputs(block: Out.() -> Unit) {
308         val instance: Out = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass<Out>).createInstance()
309         operationAssignment.outputs = instance.apply(block).build()
310     }
311
312     fun build(): OperationAssignment {
313         operationAssignment.id = id
314         operationAssignment.description = description
315         return operationAssignment
316     }
317 }
318
319 class ImplementationBuilder(private val timeout: Int, private val operationHost: String) {
320     private val implementation = Implementation()
321
322     fun primary(primary: String) {
323         implementation.primary = primary
324     }
325
326     fun dependencies(vararg dependencies: String) {
327         if (implementation.dependencies == null)
328             implementation.dependencies = arrayListOf()
329         dependencies.forEach {
330             implementation.dependencies!!.add(it)
331         }
332     }
333
334     fun build(): Implementation {
335         implementation.timeout = timeout
336         implementation.operationHost = operationHost
337         return implementation
338     }
339 }
340
341 open class PropertiesAssignmentBuilder {
342     var properties: MutableMap<String, JsonNode> = hashMapOf()
343
344     fun property(id: String, value: Any) {
345         property(id, value.asJsonType())
346     }
347
348     fun property(id: String, value: JsonNode) {
349         properties[id] = value
350     }
351
352     open fun build(): MutableMap<String, JsonNode> {
353         return properties
354     }
355 }
356
357 open class AttributesAssignmentBuilder {
358     var attributes: MutableMap<String, JsonNode> = hashMapOf()
359
360     fun attribute(id: String, value: String) {
361         attribute(id, value.asJsonType())
362     }
363
364     fun attribute(id: String, value: JsonNode) {
365         attributes[id] = value
366     }
367
368     fun build(): MutableMap<String, JsonNode> {
369         return attributes
370     }
371 }