2 * Copyright © 2017-2018 AT&T Intellectual Property.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onap.ccsdk.apps.controllerblueprints.service.enhancer
19 import com.att.eelf.configuration.EELFLogger
20 import com.att.eelf.configuration.EELFManager
21 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException
22 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintProcessorException
23 import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant
24 import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType
25 import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition
26 import org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow
27 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintRepoService
28 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintTypeEnhancerService
29 import org.onap.ccsdk.apps.controllerblueprints.core.interfaces.BluePrintWorkflowEnhancer
30 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext
31 import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintRuntimeService
32 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils
33 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment
34 import org.springframework.beans.factory.config.ConfigurableBeanFactory
35 import org.springframework.context.annotation.Scope
36 import org.springframework.stereotype.Service
39 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
40 open class BluePrintWorkflowEnhancerImpl(private val bluePrintRepoService: BluePrintRepoService,
41 private val bluePrintTypeEnhancerService: BluePrintTypeEnhancerService,
42 private val resourceAssignmentEnhancerService: ResourceAssignmentEnhancerService)
43 : BluePrintWorkflowEnhancer {
44 private val log: EELFLogger = EELFManager.getInstance().getLogger(BluePrintNodeTemplateEnhancerImpl::class.toString())
46 lateinit var bluePrintRuntimeService: BluePrintRuntimeService<*>
47 lateinit var bluePrintContext: BluePrintContext
49 val PROPERTY_DEPENDENCY_NODE_TEMPLATES = "dependency-node-templates"
52 private val workflowDataTypes: MutableMap<String, DataType> = hashMapOf()
54 override fun enhance(bluePrintRuntimeService: BluePrintRuntimeService<*>, name: String, workflow: Workflow) {
55 log.info("Enhancing Workflow($name)")
56 this.bluePrintRuntimeService = bluePrintRuntimeService
57 this.bluePrintContext = bluePrintRuntimeService.bluePrintContext()
59 val dynamicPropertyName = "$name-properties"
60 if (workflow.inputs == null) {
61 workflow.inputs = hashMapOf()
63 // Clean Dynamic Property Field, If present
64 workflow.inputs?.remove(dynamicPropertyName)
66 // Enrich Only for Resource Assignment and Dynamic Input Properties if any
67 enhanceStepTargets(name, workflow)
69 // Enrich Workflow Inputs
70 enhanceWorkflowInputs(name, workflow)
73 open fun enhanceWorkflowInputs(name: String, workflow: Workflow) {
75 workflow.inputs?.let { inputs ->
76 bluePrintTypeEnhancerService.enhancePropertyDefinitions(bluePrintRuntimeService, inputs)
80 private fun enhanceStepTargets(name: String, workflow: Workflow) {
82 // Get the first Step Target NodeTemplate name( Since that is the DG Node Template)
83 val dgNodeTemplateName = bluePrintContext.workflowFirstStepNodeTemplate(name)
85 val dgNodeTemplate = bluePrintContext.nodeTemplateByName(dgNodeTemplateName)
87 // Get the Dependent Component Node Template Names
88 val dependencyNodeTemplateNodes = dgNodeTemplate.properties?.get(PROPERTY_DEPENDENCY_NODE_TEMPLATES)
89 ?: throw BluePrintException("couldn't get property($PROPERTY_DEPENDENCY_NODE_TEMPLATES) ")
91 val dependencyNodeTemplates = JacksonUtils.getListFromJsonNode(dependencyNodeTemplateNodes, String::class.java)
93 log.info("workflow($name) dependent component NodeTemplates($dependencyNodeTemplates)")
95 // Check and Get Resource Assignment File
96 val resourceAssignmentArtifacts = dependencyNodeTemplates?.mapNotNull { componentNodeTemplateName ->
97 log.info("Identified workflow($name) targets($componentNodeTemplateName")
98 val resourceAssignmentArtifacts = bluePrintContext.nodeTemplateByName(componentNodeTemplateName)
100 it.value.type == "artifact-mapping-resource"
102 log.info("resource assignment artifacts(${it.key}) for NodeType(${componentNodeTemplateName})")
105 resourceAssignmentArtifacts
108 log.info("Workflow($name) resource assignment files($resourceAssignmentArtifacts")
110 if (resourceAssignmentArtifacts != null && resourceAssignmentArtifacts.isNotEmpty()) {
112 // Add Workflow Dynamic Property
113 addWorkFlowDynamicPropertyDefinitions(name, workflow)
115 resourceAssignmentArtifacts.forEach { fileName ->
117 val absoluteFilePath = "${bluePrintContext.rootPath}/$fileName"
119 log.info("enriching workflow($name) artifacts file(${absoluteFilePath}")
120 // Enhance Resource Assignment File
121 val resourceAssignmentProperties = enhanceResourceAssignmentFile(absoluteFilePath)
122 // Add Workflow Dynamic DataType
123 addWorkFlowDynamicDataType(name, resourceAssignmentProperties)
128 private fun enhanceResourceAssignmentFile(filePath: String): MutableMap<String, PropertyDefinition> {
130 val resourceAssignmentProperties: MutableMap<String, PropertyDefinition> = hashMapOf()
132 val resourceAssignments: MutableList<ResourceAssignment> = JacksonUtils.getListFromFile(filePath, ResourceAssignment::class.java)
133 as? MutableList<ResourceAssignment>
134 ?: throw BluePrintProcessorException("couldn't get ResourceAssignment definitions for the file($filePath)")
136 // Call Resource Assignment Enhancer
137 resourceAssignmentEnhancerService.enhanceBluePrint(bluePrintTypeEnhancerService, bluePrintRuntimeService, resourceAssignments)
139 resourceAssignments.forEach { resourceAssignment ->
140 resourceAssignmentProperties[resourceAssignment.name] = resourceAssignment.property!!
142 return resourceAssignmentProperties
145 private fun addWorkFlowDynamicPropertyDefinitions(name: String, workflow: Workflow) {
146 val dynamicPropertyName = "$name-properties"
147 val propertyDefinition = PropertyDefinition()
148 propertyDefinition.description = "Dynamic PropertyDefinition for workflow($name)."
149 propertyDefinition.type = "dt-$dynamicPropertyName"
150 propertyDefinition.required = true
151 // Add to Workflow Inputs
152 workflow.inputs?.put(dynamicPropertyName, propertyDefinition)
155 private fun addWorkFlowDynamicDataType(workflowName: String, mappingProperties: MutableMap<String, PropertyDefinition>) {
157 val dataTypeName = "dt-$workflowName-properties"
159 var recipeDataType: DataType? = bluePrintContext.serviceTemplate.dataTypes?.get(dataTypeName)
161 if (recipeDataType == null) {
162 log.info("DataType not present for the recipe({})", dataTypeName)
163 recipeDataType = DataType()
164 recipeDataType.version = "1.0.0"
165 recipeDataType.description = "Dynamic DataType definition for workflow($workflowName)."
166 recipeDataType.derivedFrom = ConfigModelConstant.MODEL_TYPE_DATA_TYPE_DYNAMIC
168 val dataTypeProperties: MutableMap<String, PropertyDefinition> = hashMapOf()
169 recipeDataType.properties = dataTypeProperties
171 // Overwrite WorkFlow DataType
172 bluePrintContext.serviceTemplate.dataTypes?.put(dataTypeName, recipeDataType)
175 log.info("Dynamic dataType($dataTypeName) already present for workflow($workflowName).")
177 // Merge all the Recipe Properties
178 mappingProperties.forEach { propertyName, propertyDefinition ->
179 recipeDataType.properties?.put(propertyName, propertyDefinition)