/* * Copyright © 2019 IBM. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onap.ccsdk.cds.controllerblueprints.core.dsl import com.fasterxml.jackson.databind.JsonNode import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType import org.onap.ccsdk.cds.controllerblueprints.core.data.* import kotlin.reflect.KClass import kotlin.reflect.full.createInstance import kotlin.reflect.jvm.reflect class TopologyTemplateBuilder { private var topologyTemplate = TopologyTemplate() private var nodeTemplates: MutableMap? = null private var workflows: MutableMap? = null fun nodeTemplate(id: String, type: String, description: String, block: NodeTemplateBuilder.() -> Unit) { if (nodeTemplates == null) nodeTemplates = hashMapOf() nodeTemplates!![id] = NodeTemplateBuilder(id, type, description).apply(block).build() } fun nodeTemplate(nodeTemplate: NodeTemplate) { if (nodeTemplates == null) nodeTemplates = hashMapOf() nodeTemplates!![nodeTemplate.id!!] = nodeTemplate } fun nodeTemplateOperation(nodeTemplateName: String, type: String, interfaceName: String, description: String, operationBlock: OperationAssignmentBuilder.() -> Unit) { if (nodeTemplates == null) nodeTemplates = hashMapOf() val nodeTemplateBuilder = NodeTemplateBuilder(nodeTemplateName, type, description) nodeTemplateBuilder.operation(interfaceName, "$description operation", operationBlock) nodeTemplates!![nodeTemplateName] = nodeTemplateBuilder.build() } fun workflow(id: String, description: String, block: WorkflowBuilder.() -> Unit) { if (workflows == null) workflows = hashMapOf() workflows!![id] = WorkflowBuilder(id, description).apply(block).build() } fun workflow(workflow: Workflow) { if (workflows == null) workflows = hashMapOf() workflows!![workflow.id!!] = workflow } //TODO("populate inputs, outputs") fun workflowNodeTemplate(actionName: String, nodeTemplateType: String, description: String, block: NodeTemplateBuilder.() -> Unit) { if (nodeTemplates == null) nodeTemplates = hashMapOf() if (workflows == null) workflows = hashMapOf() val workflowBuilder = WorkflowBuilder(actionName, description) workflowBuilder.nodeTemplateStep(actionName, description) // Workflow name is NodeTemplate name workflows!![actionName] = workflowBuilder.build() nodeTemplates!![actionName] = NodeTemplateBuilder(actionName, nodeTemplateType, description).apply(block).build() } fun build(): TopologyTemplate { topologyTemplate.nodeTemplates = nodeTemplates topologyTemplate.workflows = workflows return topologyTemplate } } open class NodeTemplateBuilder(private val id: String, private val type: String, private val description: String? = "") { private var nodeTemplate: NodeTemplate = NodeTemplate() private var properties: MutableMap? = null private var interfaces: MutableMap? = null private var artifacts: MutableMap? = null private var capabilities: MutableMap? = null private var requirements: MutableMap? = null fun properties(properties: MutableMap?) { this.properties = properties } fun properties(block: PropertiesAssignmentBuilder.() -> Unit) { if (properties == null) properties = hashMapOf() properties = PropertiesAssignmentBuilder().apply(block).build() } open fun typedProperties(block: Prop.() -> Unit) { if (properties == null) properties = hashMapOf() val instance: Prop = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass).createInstance() properties = instance.apply(block).build() } open fun typedOperation( interfaceName: String, description: String = "", block: OperationAssignmentBuilder.() -> Unit) { if (interfaces == null) interfaces = hashMapOf() val interfaceAssignment = InterfaceAssignment() val defaultOperationName = BluePrintConstants.DEFAULT_STEP_OPERATION interfaceAssignment.operations = hashMapOf() interfaceAssignment.operations!![defaultOperationName] = OperationAssignmentBuilder(defaultOperationName, description).apply(block).build() interfaces!![interfaceName] = interfaceAssignment } fun operation(interfaceName: String, description: String, block: OperationAssignmentBuilder.() -> Unit) { typedOperation(interfaceName, description, block) } fun artifact(id: String, type: String, file: String) { if (artifacts == null) artifacts = hashMapOf() artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).build() } fun artifact(id: String, type: String, file: String, block: ArtifactDefinitionBuilder.() -> Unit) { if (artifacts == null) artifacts = hashMapOf() artifacts!![id] = ArtifactDefinitionBuilder(id, type, file).apply(block).build() } fun artifacts(artifacts: MutableMap?) { this.artifacts = artifacts } fun capability(id: String, block: CapabilityAssignmentBuilder.() -> Unit) { if (capabilities == null) capabilities = hashMapOf() capabilities!![id] = CapabilityAssignmentBuilder(id).apply(block).build() } fun capabilities(capabilities: MutableMap?) { this.capabilities = capabilities } fun requirement(id: String, capability: String, node: String, relationship: String) { if (requirements == null) requirements = hashMapOf() requirements!![id] = RequirementAssignmentBuilder(id, capability, node, relationship).build() } fun requirements(requirements: MutableMap?) { this.requirements = requirements } fun build(): NodeTemplate { nodeTemplate.id = id nodeTemplate.type = type nodeTemplate.description = description nodeTemplate.properties = properties nodeTemplate.interfaces = interfaces nodeTemplate.artifacts = artifacts nodeTemplate.capabilities = capabilities nodeTemplate.requirements = requirements return nodeTemplate } } class ArtifactDefinitionBuilder(private val id: String, private val type: String, private val file: String) { private var artifactDefinition: ArtifactDefinition = ArtifactDefinition() private var properties: MutableMap? = null fun repository(repository: String) { artifactDefinition.repository = repository } fun deployPath(deployPath: String) { artifactDefinition.deployPath = deployPath } fun properties(block: PropertiesAssignmentBuilder.() -> Unit) { if (properties == null) properties = hashMapOf() properties = PropertiesAssignmentBuilder().apply(block).build() } fun build(): ArtifactDefinition { artifactDefinition.id = id artifactDefinition.type = type artifactDefinition.file = file artifactDefinition.properties = properties return artifactDefinition } } open class CapabilityAssignmentBuilder(private val id: String) { var capabilityAssignment: CapabilityAssignment = CapabilityAssignment() var attributes: MutableMap? = null var properties: MutableMap? = null fun attributes(block: AttributesAssignmentBuilder.() -> Unit) { if (attributes == null) attributes = hashMapOf() attributes = AttributesAssignmentBuilder().apply(block).build() } fun properties(block: PropertiesAssignmentBuilder.() -> Unit) { if (properties == null) properties = hashMapOf() properties = PropertiesAssignmentBuilder().apply(block).build() } fun build(): CapabilityAssignment { capabilityAssignment.properties = properties capabilityAssignment.attributes = attributes return capabilityAssignment } } open class RequirementAssignmentBuilder(private val id: String, private val capability: String, private val node: String, private val relationship: String) { private var requirementAssignment: RequirementAssignment = RequirementAssignment() fun build(): RequirementAssignment { requirementAssignment.id = id requirementAssignment.capability = capability requirementAssignment.node = node requirementAssignment.relationship = relationship return requirementAssignment } } class InterfaceAssignmentBuilder(private val id: String) { private var interfaceAssignment: InterfaceAssignment = InterfaceAssignment() private var operations: MutableMap? = null fun operation(id: String, description: String? = "", block: OperationAssignmentBuilder.() -> Unit) { if (operations == null) operations = hashMapOf() operations!![id] = OperationAssignmentBuilder( id, description).apply(block).build() } fun build(): InterfaceAssignment { interfaceAssignment.id = id interfaceAssignment.operations = operations return interfaceAssignment } } class OperationAssignmentBuilder( private val id: String, private val description: String? = "") { private var operationAssignment: OperationAssignment = OperationAssignment() fun implementation(implementation: Implementation?) { operationAssignment.implementation = implementation } fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF) { operationAssignment.implementation = Implementation().apply { this.operationHost = operationHost!! this.timeout = timeout } } fun implementation(timeout: Int, operationHost: String? = BluePrintConstants.PROPERTY_SELF, block: ImplementationBuilder.() -> Unit) { operationAssignment.implementation = ImplementationBuilder(timeout, operationHost!!).apply(block).build() } fun inputs(inputs: MutableMap?) { operationAssignment.inputs = inputs } fun inputs(block: In.() -> Unit) { val instance: In = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass).createInstance() operationAssignment.inputs = instance.apply(block).build() } fun outputs(outputs: MutableMap?) { operationAssignment.outputs = outputs } fun outputs(block: Out.() -> Unit) { val instance: Out = (block.reflect()?.parameters?.get(0)?.type?.classifier as KClass).createInstance() operationAssignment.outputs = instance.apply(block).build() } fun build(): OperationAssignment { operationAssignment.id = id operationAssignment.description = description return operationAssignment } } class ImplementationBuilder(private val timeout: Int, private val operationHost: String) { private val implementation = Implementation() fun primary(primary: String) { implementation.primary = primary } fun dependencies(vararg dependencies: String) { if (implementation.dependencies == null) implementation.dependencies = arrayListOf() dependencies.forEach { implementation.dependencies!!.add(it) } } fun build(): Implementation { implementation.timeout = timeout implementation.operationHost = operationHost return implementation } } open class PropertiesAssignmentBuilder { var properties: MutableMap = hashMapOf() fun property(id: String, value: Any) { property(id, value.asJsonType()) } fun property(id: String, value: JsonNode) { properties[id] = value } open fun build(): MutableMap { return properties } } open class AttributesAssignmentBuilder { var attributes: MutableMap = hashMapOf() fun attribute(id: String, value: String) { attribute(id, value.asJsonType()) } fun attribute(id: String, value: JsonNode) { attributes[id] = value } fun build(): MutableMap { return attributes } }