[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / openecomp-be / lib / openecomp-sdc-validation-lib / openecomp-sdc-validation-impl / src / main / java / org / openecomp / sdc / validation / impl / validators / HeatResourceValidator.java
1 package org.openecomp.sdc.validation.impl.validators;
2
3 import org.apache.commons.collections4.CollectionUtils;
4 import org.apache.commons.collections4.MapUtils;
5 import org.openecomp.core.validation.types.GlobalValidationContext;
6 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
7 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
8 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
9 import org.openecomp.sdc.heat.datatypes.model.Output;
10 import org.openecomp.sdc.heat.datatypes.model.Resource;
11 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
12 import org.openecomp.sdc.heat.services.HeatStructureUtil;
13 import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
14 import org.openecomp.sdc.logging.api.Logger;
15 import org.openecomp.sdc.logging.api.LoggerFactory;
16 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
17 import org.openecomp.sdc.validation.ValidationContext;
18 import org.openecomp.sdc.validation.base.ResourceBaseValidator;
19 import org.openecomp.sdc.validation.type.ConfigConstants;
20 import org.openecomp.sdc.validation.type.HeatResourceValidationContext;
21 import org.openecomp.sdc.validation.util.ValidationUtil;
22
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.Optional;
31 import java.util.Set;
32
33 public class HeatResourceValidator extends ResourceBaseValidator {
34   public static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
35   private static Logger logger = (Logger) LoggerFactory.getLogger(ResourceBaseValidator.class);
36
37   @Override
38   public void init(Map<String, Object> properties) {
39     super.init((Map<String, Object>) properties.get(ConfigConstants.Resource_Base_Validator));
40   }
41
42   @Override
43   public ValidationContext createValidationContext(String fileName,
44                                                       String envFileName,
45                                                       HeatOrchestrationTemplate heatOrchestrationTemplate,
46                                                       GlobalValidationContext globalContext) {
47     ManifestContent manifestContent = new ManifestContent();
48     try {
49       manifestContent = ValidationUtil.checkValidationPreCondition(globalContext);
50     } catch (Exception exception) {
51
52     }
53     Set<String> baseFiles = ManifestUtil.getBaseFiles(manifestContent);
54     String baseFileName = CollectionUtils.isEmpty(baseFiles) ? null : baseFiles.iterator().next();
55     HeatOrchestrationTemplate baseHot =
56         ValidationUtil.checkHeatOrchestrationPreCondition(baseFileName, globalContext);
57     Set<String> securityGroupsNamesFromBaseFileOutputs = baseFileName == null ? new HashSet<>()
58         : checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot
59             (baseFileName, baseHot, globalContext);
60
61     Map<String, Resource> resourcesMap =
62         heatOrchestrationTemplate.getResources() == null ? new HashMap<>()
63             : heatOrchestrationTemplate.getResources();
64
65     Map<String, Output> outputMap = heatOrchestrationTemplate.getOutputs() == null ? new HashMap<>()
66         : heatOrchestrationTemplate.getOutputs();
67
68     Map<String, Map<String, Map<String, List<String>>>>
69         typeToPointingResourcesMap = new HashMap<>();
70
71     initTypeRelationsMap
72         (fileName, resourcesMap, outputMap,
73             securityGroupsNamesFromBaseFileOutputs, typeToPointingResourcesMap, globalContext);
74
75     return new HeatResourceValidationContext
76         (heatOrchestrationTemplate, typeToPointingResourcesMap, envFileName);
77   }
78
79   private void initTypeRelationsMap(String fileName,
80                                     Map<String, Resource> resourceMap,
81                                     Map<String, Output> outputMap,
82                                     Set<String> securityGroupsNamesFromBaseFileOutputs,
83                                     Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
84                                     GlobalValidationContext globalContext) {
85
86     initTypeRelationsMapFromResourcesMap
87         (fileName, resourceMap, securityGroupsNamesFromBaseFileOutputs,
88             typeToPointingResourcesMap, globalContext);
89
90     initTypeRelationsMapFromOutputsMap
91         (fileName, resourceMap, outputMap,
92             typeToPointingResourcesMap, globalContext);
93   }
94
95   private void initTypeRelationsMapFromOutputsMap(String fileName,
96                                                   Map<String, Resource> resourceMap,
97                                                   Map<String, Output> outputMap,
98                                                   Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
99                                                   GlobalValidationContext globalContext) {
100     for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
101       Object outputValue = outputEntry.getValue().getValue();
102       Set<String> referencedResources = HeatStructureUtil
103           .getReferencedValuesByFunctionName(fileName,
104               ResourceReferenceFunctions.GET_RESOURCE.getFunction(), outputValue, globalContext);
105
106       updateRelationsMapWithOutputsReferences
107           (outputEntry, resourceMap, referencedResources, typeToPointingResourcesMap);
108
109
110     }
111   }
112
113   private void updateRelationsMapWithOutputsReferences(Map.Entry<String, Output> outputEntry,
114                                                        Map<String, Resource> resourceMap,
115                                                        Set<String> referencedResources,
116                                                        Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
117
118     for (String pointedResourceName : referencedResources) {
119       Resource pointedResource = resourceMap.get(pointedResourceName);
120
121       if (Objects.nonNull(pointedResource)) {
122         initCurrentResourceTypeInMap(pointedResourceName, pointedResource.getType(),
123             "output", typeToPointingResourcesMap);
124
125         typeToPointingResourcesMap
126             .get(pointedResource.getType()).get(pointedResourceName)
127             .get("output").add(outputEntry.getKey());
128       }
129     }
130   }
131
132   private void initTypeRelationsMapFromResourcesMap(String fileName,
133                                                     Map<String, Resource> resourceMap,
134                                                     Set<String> securityGroupsNamesFromBaseFileOutputs,
135                                                     Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
136                                                     GlobalValidationContext globalContext) {
137     for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
138       Resource pointingResource = resourceEntry.getValue();
139       Map<String, Object> properties =
140           pointingResource.getProperties() == null ? new HashMap<>() : pointingResource.getProperties();
141
142       Set<String> referencedResourcesByGetResource =
143           getResourcesIdsPointedByCurrentResource(fileName, ResourceReferenceFunctions.GET_RESOURCE,
144               properties, globalContext);
145
146       Set<String> referencedResourcesByGetAttr =
147           handleGetAttrBetweenResources(properties);
148
149       referencedResourcesByGetResource.addAll(referencedResourcesByGetAttr);
150
151       updateRelationsMapWithCurrentResourceReferences
152           (resourceMap, resourceEntry, referencedResourcesByGetResource,
153               typeToPointingResourcesMap);
154     }
155   }
156
157   private void updateRelationsMapWithSecurityGroupsFromBaseFileOutput(String fileName,
158                                                                       Map<String, Resource> resourcesMap,
159                                                                       Map.Entry<String, Resource> resourceEntry,
160                                                                       Map<String, Object> properties,
161                                                                       Set<String> securityGroupsNamesFromBaseFileOutputs,
162                                                                       Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap,
163                                                                       GlobalValidationContext globalContext) {
164
165     Set<String> candidateSecurityGroupUsedFromBaseFile = getResourcesIdsPointedByCurrentResource
166         (fileName, ResourceReferenceFunctions.GET_PARAM, properties, globalContext);
167     removeNonSecurityGroupNamesFromList
168         (candidateSecurityGroupUsedFromBaseFile, securityGroupsNamesFromBaseFileOutputs);
169
170     for (String usedSecurityGroupId : candidateSecurityGroupUsedFromBaseFile) {
171       updateMapWithRelationsBetweenResources
172           (usedSecurityGroupId,
173               HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE.getHeatResource(),
174               resourceEntry, typeToPointingResourcesMap);
175
176     }
177   }
178
179   private void removeNonSecurityGroupNamesFromList(
180       Set<String> candidateSecurityGroupUsedFromBaseFile,
181       Set<String> securityGroupsNamesFromBaseFileOutputs) {
182
183     Set<String> nonSecurityGroupNames = new HashSet<>();
184     for (String candidateSecurityGroup : candidateSecurityGroupUsedFromBaseFile) {
185       if (!securityGroupsNamesFromBaseFileOutputs.contains(candidateSecurityGroup)) {
186         nonSecurityGroupNames.add(candidateSecurityGroup);
187       }
188     }
189
190     candidateSecurityGroupUsedFromBaseFile.removeAll(nonSecurityGroupNames);
191   }
192
193   private void updateRelationsMapWithCurrentResourceReferences(Map<String, Resource> resourceMap,
194                                                                Map.Entry<String, Resource> currentResourceEntry,
195                                                                Set<String> referencedResourcesFromCurrentResource,
196                                                                Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
197
198     for (String pointedResourceName : referencedResourcesFromCurrentResource) {
199       Resource pointedResource = resourceMap.get(pointedResourceName);
200       if (Objects.nonNull(pointedResource)) {
201         String pointedResourceType = pointedResource.getType();
202
203         updateMapWithRelationsBetweenResources
204             (pointedResourceName, pointedResourceType,
205                 currentResourceEntry, typeToPointingResourcesMap);
206       }
207     }
208   }
209
210   private void updateMapWithRelationsBetweenResources(String pointedResourceName,
211                                                       String pointedResourceType,
212                                                       Map.Entry<String, Resource> currentResourceEntry,
213                                                       Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
214
215     initCurrentResourceTypeInMap(pointedResourceName, pointedResourceType,
216         currentResourceEntry.getValue().getType(), typeToPointingResourcesMap);
217
218     typeToPointingResourcesMap.get(pointedResourceType).get(pointedResourceName).get
219         (currentResourceEntry.getValue().getType()).add(currentResourceEntry.getKey());
220   }
221
222   private void initCurrentResourceTypeInMap(String resourceName, String resourceType,
223                                             String pointingResourceType,
224                                             Map<String, Map<String, Map<String, List<String>>>> typeToPointingResourcesMap) {
225
226     typeToPointingResourcesMap.putIfAbsent(resourceType, new HashMap<>());
227     typeToPointingResourcesMap.get(resourceType).putIfAbsent(resourceName, new HashMap<>());
228     typeToPointingResourcesMap.get(resourceType).get(resourceName).putIfAbsent
229         (pointingResourceType, new ArrayList<>());
230   }
231
232   private Set<String> handleGetAttrBetweenResources(Map<String, Object> properties){
233     Set<String> referencedResourcesByGetAttr = new HashSet<>();
234     for(Map.Entry<String, Object> proprtyEntry : properties.entrySet()){
235       referencedResourcesByGetAttr.addAll(getGetAttrReferencesInCaseOfContrail(proprtyEntry
236           .getValue()));
237     }
238
239     return referencedResourcesByGetAttr;
240   }
241
242
243   private Set<String> getGetAttrReferencesInCaseOfContrail(Object propertyValue){
244     Object value;
245     Set<String> getAttrReferences = new HashSet<>();
246
247     if (propertyValue instanceof Map) {
248       if (((Map) propertyValue).containsKey("get_attr")) {
249         value = ((Map) propertyValue).get("get_attr");
250         if (value instanceof List) {
251           if (((List) value).size() == 2 && ((List) value).get(1).equals("fq_name")) {
252             if (((List) value).get(0) instanceof String) {
253               getAttrReferences.add((String) ((List) value).get(0));
254               return getAttrReferences;
255             } else {
256               logger.warn("invalid format of 'get_attr' function - " + propertyValue.toString());
257             }
258           }
259         }
260       }else {
261         Collection<Object> valCollection = ((Map) propertyValue).values();
262         for (Object entryValue : valCollection) {
263           getAttrReferences.addAll(getGetAttrReferencesInCaseOfContrail(entryValue));
264         }
265       }
266     } else if (propertyValue instanceof List) {
267       for (Object prop : (List) propertyValue) {
268         getAttrReferences.addAll(getGetAttrReferencesInCaseOfContrail(prop));
269       }
270     }
271
272     return getAttrReferences;
273   }
274
275
276   private Set<String> getResourcesIdsPointedByCurrentResource(String fileName,
277                                                               ResourceReferenceFunctions function,
278                                                               Map<String, Object> properties,
279                                                               GlobalValidationContext globalContext) {
280
281     Set<String> referencedResources = new HashSet<>();
282     for (Map.Entry<String, Object> propertyEntry : properties.entrySet()) {
283       referencedResources
284           .addAll(HeatStructureUtil
285               .getReferencedValuesByFunctionName(fileName,
286                   function.getFunction(),
287                   propertyEntry.getValue(),
288                   globalContext));
289     }
290
291     return referencedResources;
292   }
293
294   private Set<String> checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot(
295       String baseFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
296       GlobalValidationContext globalContext) {
297     Set<String> securityGroupsNamesFromOutputsMap = new HashSet<>();
298
299     if (heatOrchestrationTemplate != null) {
300       Map<String, Resource> resourceMap = heatOrchestrationTemplate.getResources();
301       if (!isPortResourceExistInBaseFile(resourceMap)) {
302         getSecurityGroupsReferencedResourcesFromOutputs(securityGroupsNamesFromOutputsMap,
303             heatOrchestrationTemplate.getOutputs(), resourceMap);
304       }
305     }
306     return securityGroupsNamesFromOutputsMap;
307   }
308
309   private boolean isPortResourceExistInBaseFile(Map<String, Resource> resourceMap) {
310     for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
311       if (resourceEntry.getValue().getType()
312           .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
313         return true;
314       }
315     }
316
317     return false;
318   }
319
320   private void getSecurityGroupsReferencedResourcesFromOutputs(
321       Set<String> securityGroupsNamesFromOutputsMap, Map<String, Output> outputMap,
322       Map<String, Resource> resourceMap) {
323
324     if (MapUtils.isNotEmpty(outputMap)) {
325       for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
326         Object outputValue = outputEntry.getValue().getValue();
327         if (Objects.nonNull(outputValue) && outputValue instanceof Map) {
328           String resourceName = (String) ((Map) outputValue)
329               .get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
330           if (Objects.nonNull(resourceName)) {
331             Resource resource = resourceMap.get(resourceName);
332             if (Objects.nonNull(resource) && resource.getType().equals(
333                 HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE.getHeatResource())) {
334               securityGroupsNamesFromOutputsMap.add(outputEntry.getKey());
335             }
336           }
337         }
338       }
339     }
340   }
341 }