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