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