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