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