7ea81da0479a443e4ef7f0ca9ef1e7db3db91935
[ccsdk/cds.git] /
1 /*\r
2  * Copyright © 2017-2018 AT&T Intellectual Property.\r
3  * Modifications Copyright © 2018 IBM.\r
4  *\r
5  * Licensed under the Apache License, Version 2.0 (the "License");\r
6  * you may not use this file except in compliance with the License.\r
7  * You may obtain a copy of the License at\r
8  *\r
9  *     http://www.apache.org/licenses/LICENSE-2.0\r
10  *\r
11  * Unless required by applicable law or agreed to in writing, software\r
12  * distributed under the License is distributed on an "AS IS" BASIS,\r
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14  * See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  */\r
17 \r
18 package org.onap.ccsdk.apps.controllerblueprints.service;\r
19 \r
20 import com.att.eelf.configuration.EELFLogger;\r
21 import com.att.eelf.configuration.EELFManager;\r
22 import com.fasterxml.jackson.databind.JsonNode;\r
23 import com.google.common.base.Preconditions;\r
24 import org.apache.commons.collections.MapUtils;\r
25 import org.apache.commons.lang3.StringUtils;\r
26 import org.jetbrains.annotations.NotNull;\r
27 import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
28 import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
29 import org.onap.ccsdk.apps.controllerblueprints.core.data.*;\r
30 import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
31 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
32 import org.onap.ccsdk.apps.controllerblueprints.resource.dict.service.ResourceDefinitionRepoService;\r
33 import org.onap.ccsdk.apps.controllerblueprints.service.enhancer.BluePrintEnhancerDefaultService;\r
34 import org.onap.ccsdk.apps.controllerblueprints.service.enhancer.ResourceAssignmentEnhancerService;\r
35 import org.springframework.beans.factory.config.ConfigurableBeanFactory;\r
36 import org.springframework.context.annotation.Scope;\r
37 import org.springframework.context.annotation.ScopedProxyMode;\r
38 import org.springframework.stereotype.Service;\r
39 \r
40 import java.util.HashMap;\r
41 import java.util.List;\r
42 import java.util.Map;\r
43 \r
44 /**\r
45  * BluePrintEnhancerService\r
46  *\r
47  * @author Brinda Santh DATE : 8/8/2018\r
48  */\r
49 \r
50 @Service\r
51 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)\r
52 public class BluePrintEnhancerService extends BluePrintEnhancerDefaultService {\r
53 \r
54     private static EELFLogger log = EELFManager.getInstance().getLogger(BluePrintEnhancerService.class);\r
55 \r
56     private ResourceAssignmentEnhancerService resourceAssignmentEnhancerService;\r
57 \r
58     private Map<String, DataType> recipeDataTypes = new HashMap<>();\r
59 \r
60     public BluePrintEnhancerService(ResourceDefinitionRepoService resourceDefinitionRepoService,\r
61                                     ResourceAssignmentEnhancerService resourceAssignmentEnhancerService) {\r
62         super(resourceDefinitionRepoService);\r
63         this.resourceAssignmentEnhancerService = resourceAssignmentEnhancerService;\r
64     }\r
65 \r
66     @Override\r
67     public void enrichTopologyTemplate(@NotNull ServiceTemplate serviceTemplate) throws BluePrintException {\r
68         super.enrichTopologyTemplate(serviceTemplate);\r
69 \r
70         // Update the Recipe Inputs and DataTypes\r
71         populateRecipeInputs(serviceTemplate);\r
72     }\r
73 \r
74 \r
75     @Override\r
76     public void enrichNodeTemplate(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate) throws BluePrintException {\r
77         super.enrichNodeTemplate(nodeTemplateName, nodeTemplate);\r
78 \r
79         String nodeTypeName = nodeTemplate.getType();\r
80         log.info("*** Enriching NodeType: {}", nodeTypeName);\r
81         // Get NodeType from Repo and Update Service Template\r
82         NodeType nodeType = super.populateNodeType(nodeTypeName);\r
83 \r
84         // Enrich NodeType\r
85         super.enrichNodeType(nodeTypeName, nodeType);\r
86 \r
87         // Custom for Artifact Population\r
88         if (StringUtils.isNotBlank(nodeType.getDerivedFrom())\r
89                 && ConfigModelConstant.MODEL_TYPE_NODE_ARTIFACT.equalsIgnoreCase(nodeType.getDerivedFrom())) {\r
90             populateArtifactTemplateMappingDataType(nodeTemplateName, nodeTemplate);\r
91         }\r
92 \r
93         //Enrich Node Template Artifacts\r
94         super.enrichNodeTemplateArtifactDefinition(nodeTemplateName, nodeTemplate);\r
95 \r
96     }\r
97 \r
98 \r
99     private void populateArtifactTemplateMappingDataType(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate)\r
100             throws BluePrintException {\r
101         log.info("****** Processing Artifact Node Template : {}", nodeTemplateName);\r
102 \r
103         if (nodeTemplate.getProperties() != null) {\r
104 \r
105             if (!nodeTemplate.getProperties().containsKey(ConfigModelConstant.PROPERTY_RECIPE_NAMES)) {\r
106                 throw new BluePrintException("Node Template (" + nodeTemplateName + ") doesn't have "\r
107                         + ConfigModelConstant.PROPERTY_RECIPE_NAMES + " property.");\r
108             }\r
109 \r
110             // Modified for ONAP converted Object to JsonNode\r
111             JsonNode recipeNames = nodeTemplate.getProperties().get(ConfigModelConstant.PROPERTY_RECIPE_NAMES);\r
112 \r
113             log.info("Processing Recipe Names : {} ", recipeNames);\r
114 \r
115             if (recipeNames != null && recipeNames.isArray() && recipeNames.size() > 0) {\r
116 \r
117                 Map<String, PropertyDefinition> mappingProperties =\r
118                         getCapabilityMappingProperties(nodeTemplateName, nodeTemplate);\r
119 \r
120                 for (JsonNode recipeNameNode : recipeNames) {\r
121                     String recipeName = recipeNameNode.textValue();\r
122                     processRecipe(nodeTemplateName, mappingProperties, recipeName);\r
123                 }\r
124             }\r
125         }\r
126     }\r
127 \r
128     private void processRecipe(@NotNull String nodeTemplateName, Map<String, PropertyDefinition> mappingProperties, String recipeName) {\r
129         if (StringUtils.isNotBlank(recipeName)) {\r
130             DataType recipeDataType = this.recipeDataTypes.get(recipeName);\r
131             if (recipeDataType == null) {\r
132                 log.info("DataType not present for the recipe({})", recipeName);\r
133                 recipeDataType = new DataType();\r
134                 recipeDataType.setVersion("1.0.0");\r
135                 recipeDataType.setDescription(\r
136                         "This is Dynamic Data type definition generated from resource mapping for the config template name "\r
137                                 + nodeTemplateName + ".");\r
138                 recipeDataType.setDerivedFrom(ConfigModelConstant.MODEL_TYPE_DATA_TYPE_DYNAMIC);\r
139                 Map<String, PropertyDefinition> dataTypeProperties = new HashMap<>();\r
140                 recipeDataType.setProperties(dataTypeProperties);\r
141             } else {\r
142                 log.info("DataType Already present for the recipe({})", recipeName);\r
143             }\r
144 \r
145             // Merge all the Recipe Properties\r
146             mergeDataTypeProperties(recipeDataType, mappingProperties);\r
147 \r
148             // Overwrite Recipe DataType\r
149             this.recipeDataTypes.put(recipeName, recipeDataType);\r
150 \r
151         }\r
152     }\r
153 \r
154     private Map<String, PropertyDefinition> getCapabilityMappingProperties(String nodeTemplateName,\r
155                                                                            NodeTemplate nodeTemplate) throws BluePrintException {\r
156 \r
157         Map<String, PropertyDefinition> dataTypeProperties = null;\r
158         if (nodeTemplate != null && MapUtils.isNotEmpty(nodeTemplate.getCapabilities())) {\r
159             CapabilityAssignment capability =\r
160                     nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
161 \r
162             if (capability != null && capability.getProperties() != null) {\r
163 \r
164                 String resourceAssignmentContent = JacksonUtils\r
165                         .getJson(capability.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING));\r
166 \r
167                 List<ResourceAssignment> resourceAssignments =\r
168                         JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment.class);\r
169 \r
170                 Preconditions.checkNotNull(resourceAssignments, "Failed to Processing Resource Mapping " + resourceAssignmentContent);\r
171                 // Enhance Resource Assignment\r
172                 resourceAssignmentEnhancerService.enhanceBluePrint(this, resourceAssignments);\r
173 \r
174                 dataTypeProperties = new HashMap<>();\r
175 \r
176                 for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
177                     if (resourceAssignment != null\r
178                             // && Boolean.valueOf(resourceAssignment.getInputParameter())\r
179                             && resourceAssignment.getProperty() != null\r
180                             && StringUtils.isNotBlank(resourceAssignment.getName())) {\r
181 \r
182                         dataTypeProperties.put(resourceAssignment.getName(), resourceAssignment.getProperty());\r
183 \r
184                     }\r
185                 }\r
186 \r
187             }\r
188         }\r
189         return dataTypeProperties;\r
190     }\r
191 \r
192     private void mergeDataTypeProperties(DataType dataType, Map<String, PropertyDefinition> mergeProperties) {\r
193         if (dataType != null && dataType.getProperties() != null && mergeProperties != null) {\r
194             // Add the Other Template Properties\r
195             mergeProperties.forEach((mappingKey, propertyDefinition) -> dataType.getProperties().put(mappingKey, propertyDefinition));\r
196         }\r
197     }\r
198 \r
199     private void populateRecipeInputs(ServiceTemplate serviceTemplate) {\r
200         if (serviceTemplate.getTopologyTemplate() != null\r
201                 && MapUtils.isNotEmpty(serviceTemplate.getTopologyTemplate().getInputs())\r
202                 && MapUtils.isNotEmpty(this.recipeDataTypes)\r
203                 && MapUtils.isNotEmpty(serviceTemplate.getDataTypes())) {\r
204             this.recipeDataTypes.forEach((recipeName, recipeDataType) -> {\r
205                 String dataTypePrefix = recipeName.replace("-action", "") + "-request";\r
206                 String dataTypeName = "dt-" + dataTypePrefix;\r
207 \r
208                 serviceTemplate.getDataTypes().put(dataTypeName, recipeDataType);\r
209 \r
210                 PropertyDefinition customInputProperty = new PropertyDefinition();\r
211                 customInputProperty.setDescription("This is Dynamic Data type for the receipe " + recipeName + ".");\r
212                 customInputProperty.setRequired(Boolean.FALSE);\r
213                 customInputProperty.setType(dataTypeName);\r
214                 serviceTemplate.getTopologyTemplate().getInputs().put(dataTypePrefix, customInputProperty);\r
215 \r
216             });\r
217         }\r
218     }\r
219 }\r