push addional code
[sdc.git] / openecomp-be / lib / openecomp-sdc-validation-lib / openecomp-sdc-validation-impl / src / main / java / org / openecomp / sdc / validation / impl / util / HeatValidationService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.validation.impl.util;
22
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.collections4.MapUtils;
25 import org.openecomp.core.utilities.yaml.YamlUtil;
26 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
27 import org.openecomp.core.validation.errors.Messages;
28 import org.openecomp.core.validation.types.GlobalValidationContext;
29 import org.openecomp.sdc.datatypes.error.ErrorLevel;
30 import org.openecomp.sdc.heat.datatypes.model.Environment;
31 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
32 import org.openecomp.sdc.heat.datatypes.model.Output;
33 import org.openecomp.sdc.heat.datatypes.model.Resource;
34 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
35 import org.openecomp.sdc.heat.services.HeatStructureUtil;
36 import org.openecomp.sdc.validation.impl.validators.HeatValidator;
37
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import java.util.Collection;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.Set;
46
47 public class HeatValidationService {
48
49   private static final Logger logger = LoggerFactory.getLogger(HeatValidator.class);
50
51   /**
52    * Check artifacts existence.
53    *
54    * @param fileName       the file name
55    * @param artifactsNames the artifacts names
56    * @param globalContext  the global context
57    */
58   public static void checkArtifactsExistence(String fileName, Set<String> artifactsNames,
59                                              GlobalValidationContext globalContext) {
60     artifactsNames
61         .stream()
62         .filter(artifactName -> !globalContext.getFileContextMap().containsKey(artifactName))
63         .forEach(artifactName -> {
64           globalContext
65               .addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
66                   .getErrorWithParameters(Messages.MISSING_ARTIFACT.getErrorMessage(),
67                       artifactName));
68         });
69   }
70
71
72   /**
73    * Check resource existence from resources map.
74    *
75    * @param fileName         the file name
76    * @param resourcesNames   the resources names
77    * @param valuesToSearchIn the values to search in
78    * @param globalContext    the global context
79    */
80   public static void checkResourceExistenceFromResourcesMap(String fileName,
81                                                             Set<String> resourcesNames,
82                                                             Collection<?> valuesToSearchIn,
83                                                             GlobalValidationContext globalContext) {
84     if (CollectionUtils.isNotEmpty(valuesToSearchIn)) {
85       for (Object value : valuesToSearchIn) {
86         if (value instanceof Resource) {
87           Resource resource = (Resource) value;
88           //checkResourceDependsOn(fileName,resource,resourcesNames,globalContext);
89
90           Collection<Object> resourcePropertiesValues =
91               resource.getProperties() == null ? null : resource.getProperties().values();
92           if (CollectionUtils.isNotEmpty(resourcePropertiesValues)) {
93             for (Object propertyValue : resourcePropertiesValues) {
94               handleReferencedResources(fileName, propertyValue, resourcesNames, globalContext);
95             }
96           }
97         } else if (value instanceof Output) {
98           Output output = (Output) value;
99           Object outputsValue = output.getValue();
100           handleReferencedResources(fileName, outputsValue, resourcesNames, globalContext);
101         }
102       }
103     }
104   }
105
106
107   private static void handleReferencedResources(String fileName, Object valueToSearchReferencesIn,
108                                                 Set<String> resourcesNames,
109                                                 GlobalValidationContext globalContext) {
110     Set<String> referencedResourcesNames = HeatStructureUtil
111         .getReferencedValuesByFunctionName(fileName,
112             ResourceReferenceFunctions.GET_RESOURCE.getFunction(), valueToSearchReferencesIn,
113             globalContext);
114     if (CollectionUtils.isNotEmpty(referencedResourcesNames)) {
115       HeatValidationService
116           .checkIfResourceReferenceExist(fileName, resourcesNames, referencedResourcesNames,
117               globalContext);
118     }
119   }
120
121
122   private static void checkIfResourceReferenceExist(String fileName,
123                                                     Set<String> referencedResourcesNames,
124                                                     Set<String> referencedResources,
125                                                     GlobalValidationContext globalContext) {
126     referencedResources.stream()
127         .filter(referencedResource -> !referencedResourcesNames.contains(referencedResource))
128         .forEach(referencedResource -> {
129           globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
130               .getErrorWithParameters(Messages.REFERENCED_RESOURCE_NOT_FOUND.getErrorMessage(),
131                   referencedResource));
132         });
133   }
134
135   /**
136    * Draw files loop string.
137    *
138    * @param filesInPath the files in path
139    * @return the string
140    */
141   public static String drawFilesLoop(List<String> filesInPath) {
142     StringBuilder stringBuilder = new StringBuilder();
143     stringBuilder.append("[");
144     int pathSize = filesInPath.size();
145
146     for (int i = 0; i < pathSize; i++) {
147       stringBuilder.append(filesInPath.get(i));
148       if (i != pathSize - 1) {
149         stringBuilder.append(" -- ");
150       }
151     }
152     if (!filesInPath.get(0).equals(filesInPath.get(pathSize - 1))) {
153       stringBuilder.append(" -- ");
154       stringBuilder.append(filesInPath.get(0));
155     }
156     stringBuilder.append("]");
157
158     return stringBuilder.toString();
159   }
160
161
162   /**
163    * Check nested parameters.
164    *
165    * @param callingNestedFileName  the calling nested file name
166    * @param nestedFileName         the nested file name
167    * @param resourceName           the resource name
168    * @param globalContext          the global context
169    * @param resourceFileProperties the resource file properties
170    */
171   public static void checkNestedParameters(String callingNestedFileName, String nestedFileName,
172                                            String resourceName,
173                                            GlobalValidationContext globalContext,
174                                            Set<String> resourceFileProperties) {
175     HeatOrchestrationTemplate heatOrchestrationTemplate;
176     try {
177       heatOrchestrationTemplate = new YamlUtil()
178           .yamlToObject(globalContext.getFileContent(nestedFileName),
179               HeatOrchestrationTemplate.class);
180     } catch (Exception e0) {
181       return;
182     }
183     Set<String> nestedParametersNames = heatOrchestrationTemplate.getParameters() == null ? null
184         : heatOrchestrationTemplate.getParameters().keySet();
185
186     if (CollectionUtils.isNotEmpty(nestedParametersNames)) {
187       resourceFileProperties
188           .stream()
189           .filter(propertyName -> !nestedParametersNames.contains(propertyName))
190           .forEach(propertyName -> globalContext
191               .addMessage(callingNestedFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
192                   .getErrorWithParameters(Messages.MISSING_PARAMETER_IN_NESTED.getErrorMessage(),
193                       nestedFileName, resourceName, propertyName)));
194     }
195   }
196
197
198   /**
199    * Is nested loop exist in file boolean.
200    *
201    * @param callingFileName the calling file name
202    * @param nestedFileName  the nested file name
203    * @param filesInLoop     the files in loop
204    * @param globalContext   the global context
205    * @return the boolean
206    */
207   public static boolean isNestedLoopExistInFile(String callingFileName, String nestedFileName,
208                                                 List<String> filesInLoop,
209                                                 GlobalValidationContext globalContext) {
210     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
211     try {
212       nestedHeatOrchestrationTemplate = new YamlUtil()
213           .yamlToObject(globalContext.getFileContent(nestedFileName),
214               HeatOrchestrationTemplate.class);
215     } catch (Exception e0) {
216       logger.warn("HEAT Validator will not be executed on file " + nestedFileName
217           + " due to illegal HEAT format");
218       return false;
219     }
220     filesInLoop.add(nestedFileName);
221     Collection<Resource> nestedResources =
222         nestedHeatOrchestrationTemplate.getResources() == null ? null
223             : nestedHeatOrchestrationTemplate.getResources().values();
224     if (CollectionUtils.isNotEmpty(nestedResources)) {
225       for (Resource resource : nestedResources) {
226         String resourceType = resource.getType();
227
228         if (Objects.nonNull(resourceType) && isNestedResource(resourceType)) {
229           return resourceType.equals(callingFileName) || !filesInLoop.contains(resourceType)
230               && isNestedLoopExistInFile(callingFileName, resourceType, filesInLoop, globalContext);
231         }
232       }
233     }
234     return false;
235   }
236
237
238   /**
239    * Loop over output map and validate get attr from nested.
240    *
241    * @param fileName                  the file name
242    * @param outputMap                 the output map
243    * @param heatOrchestrationTemplate the heat orchestration template
244    * @param globalContext             the global context
245    */
246   @SuppressWarnings("unchecked")
247   public static void loopOverOutputMapAndValidateGetAttrFromNested(String fileName,
248                                        Map<String, Output> outputMap,
249                                        HeatOrchestrationTemplate heatOrchestrationTemplate,
250                                        GlobalValidationContext globalContext) {
251     for (Output output : outputMap.values()) {
252       Object outputValue = output.getValue();
253       if (outputValue != null && outputValue instanceof Map) {
254         Map<String, Object> outputValueMap = (Map<String, Object>) outputValue;
255         List<String> getAttrValue =
256             (List<String>) outputValueMap.get(ResourceReferenceFunctions.GET_ATTR.getFunction());
257         if (!CollectionUtils.isEmpty(getAttrValue)) {
258           String resourceName = getAttrValue.get(0);
259           String propertyName = getAttrValue.get(1);
260           String resourceType =
261               getResourceTypeFromResourcesMap(resourceName, heatOrchestrationTemplate);
262
263           if (Objects.nonNull(resourceType)
264               && HeatValidationService.isNestedResource(resourceType)) {
265             Map<String, Output> nestedOutputMap;
266             HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
267             try {
268               nestedHeatOrchestrationTemplate = new YamlUtil()
269                   .yamlToObject(globalContext.getFileContent(resourceType),
270                       HeatOrchestrationTemplate.class);
271             } catch (Exception e0) {
272               return;
273             }
274             nestedOutputMap = nestedHeatOrchestrationTemplate.getOutputs();
275
276             if (MapUtils.isEmpty(nestedOutputMap) || !nestedOutputMap.containsKey(propertyName)) {
277               globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
278                   .getErrorWithParameters(Messages.GET_ATTR_NOT_FOUND.getErrorMessage(),
279                       propertyName, resourceName));
280             }
281           }
282         }
283       }
284     }
285   }
286
287
288   public static boolean isNestedResource(String resourceType) {
289     return resourceType.contains(".yaml") || resourceType.contains(".yml");
290   }
291
292
293   private static String getResourceTypeFromResourcesMap(String resourceName,
294                                     HeatOrchestrationTemplate heatOrchestrationTemplate) {
295     return heatOrchestrationTemplate.getResources().get(resourceName).getType();
296   }
297
298   /**
299    * Validate env content environment.
300    *
301    * @param fileName      the file name
302    * @param envFileName   the env file name
303    * @param globalContext the global context
304    * @return the environment
305    */
306   public static Environment validateEnvContent(String fileName, String envFileName,
307                                                GlobalValidationContext globalContext) {
308     Environment envContent = null;
309     try {
310       envContent =
311           new YamlUtil().yamlToObject(globalContext.getFileContent(envFileName), Environment.class);
312     } catch (Exception e0) {
313       return null;
314     }
315     return envContent;
316   }
317
318
319   public static String getResourceGroupResourceName(String resourceCallingToResourceGroup) {
320     return "OS::Heat::ResourceGroup in " + resourceCallingToResourceGroup;
321   }
322
323 }