aaa45e143e025a0c1704f225137cdb898c6e5eae
[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.stereotype.Service;\r
38 \r
39 import java.util.HashMap;\r
40 import java.util.List;\r
41 import java.util.Map;\r
42 \r
43 /**\r
44  * BluePrintEnhancerService\r
45  *\r
46  * @author Brinda Santh DATE : 8/8/2018\r
47  */\r
48 \r
49 @Service\r
50 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)\r
51 public class BluePrintEnhancerService extends BluePrintEnhancerDefaultService {\r
52 \r
53     private static EELFLogger log = EELFManager.getInstance().getLogger(BluePrintEnhancerService.class);\r
54 \r
55     private ResourceAssignmentEnhancerService resourceAssignmentEnhancerService;\r
56 \r
57     private Map<String, DataType> recipeDataTypes = new HashMap<>();\r
58 \r
59     public BluePrintEnhancerService(ResourceDefinitionRepoService resourceDefinitionRepoService,\r
60                                     ResourceAssignmentEnhancerService resourceAssignmentEnhancerService) {\r
61         super(resourceDefinitionRepoService);\r
62         this.resourceAssignmentEnhancerService = resourceAssignmentEnhancerService;\r
63     }\r
64 \r
65     @Override\r
66     public void enrichTopologyTemplate(@NotNull ServiceTemplate serviceTemplate) throws BluePrintException {\r
67         super.enrichTopologyTemplate(serviceTemplate);\r
68 \r
69         // Update the Recipe Inputs and DataTypes\r
70         populateRecipeInputs(serviceTemplate);\r
71     }\r
72 \r
73 \r
74     @Override\r
75     public void enrichNodeTemplate(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate) throws BluePrintException {\r
76         super.enrichNodeTemplate(nodeTemplateName, nodeTemplate);\r
77 \r
78         String nodeTypeName = nodeTemplate.getType();\r
79         log.info("*** Enriching NodeType: {}", nodeTypeName);\r
80         // Get NodeType from Repo and Update Service Template\r
81         NodeType nodeType = super.populateNodeType(nodeTypeName);\r
82 \r
83         // Enrich NodeType\r
84         super.enrichNodeType(nodeTypeName, nodeType);\r
85 \r
86         // Custom for Artifact Population\r
87         if (StringUtils.isNotBlank(nodeType.getDerivedFrom())\r
88                 && ConfigModelConstant.MODEL_TYPE_NODE_ARTIFACT.equalsIgnoreCase(nodeType.getDerivedFrom())) {\r
89             populateArtifactTemplateMappingDataType(nodeTemplateName, nodeTemplate);\r
90         }\r
91 \r
92         //Enrich Node Template Artifacts\r
93         super.enrichNodeTemplateArtifactDefinition(nodeTemplateName, nodeTemplate);\r
94 \r
95     }\r
96 \r
97 \r
98     private void populateArtifactTemplateMappingDataType(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate)\r
99             throws BluePrintException {\r
100         log.info("****** Processing Artifact Node Template : {}", nodeTemplateName);\r
101 \r
102         if (nodeTemplate.getProperties() != null) {\r
103 \r
104             if (!nodeTemplate.getProperties().containsKey(ConfigModelConstant.PROPERTY_RECIPE_NAMES)) {\r
105                 throw new BluePrintException("Node Template (" + nodeTemplateName + ") doesn't have "\r
106                         + ConfigModelConstant.PROPERTY_RECIPE_NAMES + " property.");\r
107             }\r
108 \r
109             // Modified for ONAP converted Object to JsonNode\r
110             JsonNode recipeNames = nodeTemplate.getProperties().get(ConfigModelConstant.PROPERTY_RECIPE_NAMES);\r
111 \r
112             log.info("Processing Recipe Names : {} ", recipeNames);\r
113 \r
114             if (recipeNames != null && recipeNames.isArray() && recipeNames.size() > 0) {\r
115 \r
116                 Map<String, PropertyDefinition> mappingProperties =\r
117                         getCapabilityMappingProperties(nodeTemplateName, nodeTemplate);\r
118 \r
119                 for (JsonNode recipeNameNode : recipeNames) {\r
120                     String recipeName = recipeNameNode.textValue();\r
121                     processRecipe(nodeTemplateName, mappingProperties, recipeName);\r
122                 }\r
123             }\r
124         }\r
125     }\r
126 \r
127     private void processRecipe(@NotNull String nodeTemplateName, Map<String, PropertyDefinition> mappingProperties, String recipeName) {\r
128         if (StringUtils.isNotBlank(recipeName)) {\r
129             DataType recipeDataType = this.recipeDataTypes.get(recipeName);\r
130             if (recipeDataType == null) {\r
131                 log.info("DataType not present for the recipe({})", recipeName);\r
132                 recipeDataType = new DataType();\r
133                 recipeDataType.setVersion("1.0.0");\r
134                 recipeDataType.setDescription(\r
135                         "This is Dynamic Data type definition generated from resource mapping for the config template name "\r
136                                 + nodeTemplateName + ".");\r
137                 recipeDataType.setDerivedFrom(ConfigModelConstant.MODEL_TYPE_DATA_TYPE_DYNAMIC);\r
138                 Map<String, PropertyDefinition> dataTypeProperties = new HashMap<>();\r
139                 recipeDataType.setProperties(dataTypeProperties);\r
140             } else {\r
141                 log.info("DataType Already present for the recipe({})", recipeName);\r
142             }\r
143 \r
144             // Merge all the Recipe Properties\r
145             mergeDataTypeProperties(recipeDataType, mappingProperties);\r
146 \r
147             // Overwrite Recipe DataType\r
148             this.recipeDataTypes.put(recipeName, recipeDataType);\r
149 \r
150         }\r
151     }\r
152 \r
153     private Map<String, PropertyDefinition> getCapabilityMappingProperties(String nodeTemplateName,\r
154                                                                            NodeTemplate nodeTemplate) throws BluePrintException {\r
155 \r
156         Map<String, PropertyDefinition> dataTypeProperties = null;\r
157         if (nodeTemplate != null && MapUtils.isNotEmpty(nodeTemplate.getCapabilities())) {\r
158             CapabilityAssignment capability =\r
159                     nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
160 \r
161             if (capability != null && capability.getProperties() != null) {\r
162 \r
163                 String resourceAssignmentContent = JacksonUtils\r
164                         .getJson(capability.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING));\r
165 \r
166                 List<ResourceAssignment> resourceAssignments =\r
167                         JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment.class);\r
168 \r
169                 Preconditions.checkNotNull(resourceAssignments, "Failed to Processing Resource Mapping " + resourceAssignmentContent);\r
170                 // Enhance Resource Assignment\r
171                 resourceAssignmentEnhancerService.enhanceBluePrint(this, resourceAssignments);\r
172 \r
173                 dataTypeProperties = new HashMap<>();\r
174 \r
175                 for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
176                     if (resourceAssignment != null\r
177                             // && Boolean.valueOf(resourceAssignment.getInputParameter())\r
178                             && resourceAssignment.getProperty() != null\r
179                             && StringUtils.isNotBlank(resourceAssignment.getName())) {\r
180 \r
181                         dataTypeProperties.put(resourceAssignment.getName(), resourceAssignment.getProperty());\r
182 \r
183                     }\r
184                 }\r
185 \r
186             }\r
187         }\r
188         return dataTypeProperties;\r
189     }\r
190 \r
191     private void mergeDataTypeProperties(DataType dataType, Map<String, PropertyDefinition> mergeProperties) {\r
192         if (dataType != null && dataType.getProperties() != null && mergeProperties != null) {\r
193             // Add the Other Template Properties\r
194             mergeProperties.forEach((mappingKey, propertyDefinition) -> dataType.getProperties().put(mappingKey, propertyDefinition));\r
195         }\r
196     }\r
197 \r
198     private void populateRecipeInputs(ServiceTemplate serviceTemplate) {\r
199         if (serviceTemplate.getTopologyTemplate() != null\r
200                 && MapUtils.isNotEmpty(serviceTemplate.getTopologyTemplate().getInputs())\r
201                 && MapUtils.isNotEmpty(this.recipeDataTypes)\r
202                 && MapUtils.isNotEmpty(serviceTemplate.getDataTypes())) {\r
203             this.recipeDataTypes.forEach((recipeName, recipeDataType) -> {\r
204                 String dataTypePrefix = recipeName.replace("-action", "") + "-request";\r
205                 String dataTypeName = "dt-" + dataTypePrefix;\r
206 \r
207                 serviceTemplate.getDataTypes().put(dataTypeName, recipeDataType);\r
208 \r
209                 PropertyDefinition customInputProperty = new PropertyDefinition();\r
210                 customInputProperty.setDescription("This is Dynamic Data type for the receipe " + recipeName + ".");\r
211                 customInputProperty.setRequired(Boolean.FALSE);\r
212                 customInputProperty.setType(dataTypeName);\r
213                 serviceTemplate.getTopologyTemplate().getInputs().put(dataTypePrefix, customInputProperty);\r
214 \r
215             });\r
216         }\r
217     }\r
218 }\r