ae289f9178e4ff336792a1fb87a543fd75fe86e5
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.validation.impl.validators;
18
19 import java.io.InputStream;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Objects;
25 import java.util.Optional;
26 import java.util.Set;
27
28 import org.apache.commons.collections4.CollectionUtils;
29 import org.apache.commons.collections4.MapUtils;
30 import org.onap.sdc.tosca.services.YamlUtil;
31 import org.openecomp.core.validation.ErrorMessageCode;
32 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
33 import org.openecomp.core.validation.types.GlobalValidationContext;
34 import org.openecomp.sdc.common.errors.Messages;
35 import org.openecomp.sdc.datatypes.error.ErrorLevel;
36 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
37 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
38 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
39 import org.openecomp.sdc.heat.datatypes.model.Environment;
40 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
41 import org.openecomp.sdc.heat.datatypes.model.HeatPseudoParameters;
42 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
43 import org.openecomp.sdc.heat.datatypes.model.Output;
44 import org.openecomp.sdc.heat.datatypes.model.Parameter;
45 import org.openecomp.sdc.heat.datatypes.model.Resource;
46 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
47 import org.openecomp.sdc.heat.services.HeatStructureUtil;
48 import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
49 import org.openecomp.sdc.logging.api.Logger;
50 import org.openecomp.sdc.logging.api.LoggerFactory;
51 import org.openecomp.sdc.validation.Validator;
52 import org.openecomp.sdc.validation.impl.util.HeatValidationService;
53 import org.openecomp.sdc.validation.util.ValidationUtil;
54
55 public class HeatValidator implements Validator {
56     private static final Logger LOGGER = LoggerFactory.getLogger(HeatValidator.class);
57     private static final ErrorMessageCode ERROR_CODE_HOT_1 = new ErrorMessageCode("HOT1");
58     private static final ErrorMessageCode ERROR_CODE_HOT_2 = new ErrorMessageCode("HOT2");
59     private static final ErrorMessageCode ERROR_CODE_HOT_3 = new ErrorMessageCode("HOT3");
60     private static final ErrorMessageCode ERROR_CODE_HOT_4 = new ErrorMessageCode("HOT4");
61     private static final ErrorMessageCode ERROR_CODE_HOT_5 = new ErrorMessageCode("HOT5");
62     private static final ErrorMessageCode ERROR_CODE_HOT_6 = new ErrorMessageCode("HOT6");
63     private static final ErrorMessageCode ERROR_CODE_HOT_7 = new ErrorMessageCode("HOT7");
64     private static final ErrorMessageCode ERROR_CODE_HOT_8 = new ErrorMessageCode("HOT8");
65     private static final ErrorMessageCode ERROR_CODE_HOT_9 = new ErrorMessageCode("HOT9");
66     private static final ErrorMessageCode ERROR_CODE_HOT_10 = new ErrorMessageCode("HOT10");
67     private static final ErrorMessageCode ERROR_CODE_HOT_11 = new ErrorMessageCode("HOT11");
68     private static final ErrorMessageCode ERROR_CODE_HOT_12 = new ErrorMessageCode("HOT12");
69     private static final ErrorMessageCode ERROR_CODE_HOT_13 = new ErrorMessageCode("HOT13");
70     private static final ErrorMessageCode ERROR_CODE_HOT_14 = new ErrorMessageCode("HOT14");
71     private static final ErrorMessageCode ERROR_CODE_HOT_15 = new ErrorMessageCode("HOT15");
72     private static final ErrorMessageCode ERROR_CODE_HOT_16 = new ErrorMessageCode("HOT16");
73     private static final ErrorMessageCode ERROR_CODE_HOT_17 = new ErrorMessageCode("HOT17");
74
75     private static final ErrorMessageCode ERROR_CODE_HOT_18 = new ErrorMessageCode("HOT18");
76
77     // The Artifacts generated by SDC - not allowed to be in HEAT
78     static final String VF_LICENSE_MODEL_XML = "vf-license-model.xml";
79     static final String VENDOR_LICENSE_MODEL_XML = "vendor-license-model.xml";
80     static final String HEAT_META = "HEAT.meta";
81
82     private static final Set<String> GENERATED_ARTIFACTS;
83
84     static {
85         GENERATED_ARTIFACTS = getGeneratedArtifactNames();
86     }
87
88   private static void validateAllRequiredArtifactsExist(String fileName,
89                                                         HeatOrchestrationTemplate
90                                                             heatOrchestrationTemplate,
91                                                         Set<String> artifacts,
92                                                         GlobalValidationContext globalContext) {
93     Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
94         : heatOrchestrationTemplate.getResources().values();
95
96     if (CollectionUtils.isNotEmpty(resourcesValues)) {
97       for (Resource resource : resourcesValues) {
98         Collection<Object> properties =
99             resource.getProperties() == null ? null : resource.getProperties().values();
100         validatePropertiesForAllRequiredArtifactsExist(properties, fileName,
101                 artifacts, globalContext);
102       }
103     }
104   }
105
106   private static void validatePropertiesForAllRequiredArtifactsExist(Collection<Object> properties,
107                                                  String fileName,
108                                                  Set<String> artifacts,
109                                                  GlobalValidationContext globalContext) {
110       if (CollectionUtils.isNotEmpty(properties)) {
111           for (Object property : properties) {
112               if (property instanceof Map) {
113                   globalContext.setMessageCode(ERROR_CODE_HOT_14);
114                   Set<String> artifactNames = HeatStructureUtil
115                           .getReferencedValuesByFunctionName(fileName,
116                                   ResourceReferenceFunctions.GET_FILE.getFunction(), property, globalContext);
117                   artifacts.addAll(artifactNames);
118                   globalContext.setMessageCode(ERROR_CODE_HOT_15);
119                   HeatValidationService.checkArtifactsExistence(fileName, artifactNames,
120                           globalContext);
121               }
122           }
123       }
124   }
125   /* validation 14 */
126
127   private static void validateAllResourceReferencesExist(String fileName,
128                                                          HeatOrchestrationTemplate
129                                                              heatOrchestrationTemplate,
130                                                          GlobalValidationContext globalContext) {
131     Set<String> resourcesNames = heatOrchestrationTemplate.getResources() == null ? null
132         : heatOrchestrationTemplate.getResources().keySet();
133     Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
134         : heatOrchestrationTemplate.getResources().values();
135     Collection<Output> outputsValues = heatOrchestrationTemplate.getOutputs() == null ? null
136         : heatOrchestrationTemplate.getOutputs().values();
137     checkResourceExistenceFromResourcesMap(fileName, resourcesNames, resourcesValues,
138         globalContext);
139     checkResourceExistenceFromResourcesMap(fileName, resourcesNames, outputsValues,
140         globalContext);
141   }
142
143   private static void checkResourceExistenceFromResourcesMap(String fileName,
144                                       Set<String> resourcesNames,
145                                       Collection<?> valuesToSearchIn,
146                                       GlobalValidationContext globalContext) {
147     if (CollectionUtils.isNotEmpty(valuesToSearchIn)) {
148       for (Object value : valuesToSearchIn) {
149         if (value instanceof Resource) {
150                   extractResourceProperty(fileName, resourcesNames, globalContext,
151                           (Resource) value);
152         } else if (value instanceof Output) {
153           Output output = (Output) value;
154           Object outputsValue = output.getValue();
155           handleReferencedResources(fileName, outputsValue, resourcesNames,
156               globalContext);
157         }
158       }
159     }
160   }
161
162   private static void extractResourceProperty(String fileName, Set<String> resourcesNames,
163                                               GlobalValidationContext globalContext,
164                                               Resource value) {
165       Collection<Object> resourcePropertiesValues =
166         value.getProperties() == null ? null : value.getProperties()
167             .values();
168     if (CollectionUtils.isNotEmpty(resourcePropertiesValues)) {
169       for (Object propertyValue : resourcePropertiesValues) {
170         handleReferencedResources(fileName, propertyValue, resourcesNames,
171             globalContext);
172       }
173     }
174   }
175
176   private static void handleReferencedResources(String fileName, Object valueToSearchReferencesIn,
177                                                 Set<String> resourcesNames,
178                                                 GlobalValidationContext globalContext) {
179     globalContext.setMessageCode(ERROR_CODE_HOT_13);
180     Set<String> referencedResourcesNames = HeatStructureUtil
181         .getReferencedValuesByFunctionName(fileName,
182             ResourceReferenceFunctions.GET_RESOURCE.getFunction(),
183             valueToSearchReferencesIn, globalContext);
184     if (CollectionUtils.isNotEmpty(referencedResourcesNames)) {
185       checkIfResourceReferenceExist(fileName, resourcesNames, referencedResourcesNames,
186           globalContext);
187     }
188   }
189
190   private static void checkIfResourceReferenceExist(String fileName,
191                                                     Set<String> referencedResourcesNames,
192                                                     Set<String> referencedResources,
193                                                     GlobalValidationContext globalContext) {
194     referencedResources.stream()
195                 .filter(referencedResource -> !referencedResourcesNames
196                 .contains(referencedResource))
197                 .forEach(referencedResource ->
198           globalContext.addMessage(fileName,
199               ErrorLevel.ERROR, ErrorMessagesFormatBuilder
200                   .getErrorWithParameters(ERROR_CODE_HOT_16,Messages
201                       .REFERENCED_RESOURCE_NOT_FOUND.getErrorMessage(), referencedResource)));
202   }
203
204   /* validation 16 */
205
206   private static void validateGetParamPointToParameter(String fileName,
207                                                        HeatOrchestrationTemplate
208                                                            heatOrchestrationTemplate,
209                                                        GlobalValidationContext globalContext) {
210     Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
211         : heatOrchestrationTemplate.getParameters().keySet();
212     Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
213
214     if (CollectionUtils.isNotEmpty(parametersNames) && MapUtils.isNotEmpty(resourcesMap)) {
215       for (Map.Entry<String, Resource> resourceEntry : resourcesMap.entrySet()) {
216         Resource resource = resourceEntry.getValue();
217         Map<String, Object> properties = resource.getProperties();
218           validatePropertiesForGetParamPointToParameter(properties, fileName, parametersNames,
219                   resourceEntry, globalContext);
220       }
221     }
222   }
223
224   private static void validatePropertiesForGetParamPointToParameter(Map<String,
225                                             Object> properties,
226                                             String fileName, Set<String> parametersNames,
227                                             Map.Entry<String, Resource> resourceEntry,
228                                             GlobalValidationContext globalContext) {
229       if (MapUtils.isNotEmpty(properties)) {
230           Collection<Object> propertiesValues = properties.values();
231           if (CollectionUtils.isNotEmpty(propertiesValues)) {
232               for (Object propertyObject : propertiesValues) {
233                   Set<String> referencedParameterNames = HeatStructureUtil
234                           .getReferencedValuesByFunctionName(fileName, "get_param", propertyObject,
235                                   globalContext);
236
237                   validateReferenceParams(fileName, resourceEntry.getKey(), parametersNames,
238                           referencedParameterNames, globalContext);
239               }
240           }
241       }
242   }
243
244   private static void validateReferenceParams(String fileName, String resourceName,
245                                               Set<String> parametersNamesFromFile,
246                                               Set<String> referencedParametersNames,
247                                               GlobalValidationContext globalContext) {
248     for (String parameterName : referencedParametersNames) {
249       if (!isHeatPseudoParameter(parameterName)
250           && !parametersNamesFromFile.contains(parameterName)) {
251         globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
252                         .getErrorWithParameters(ERROR_CODE_HOT_1,Messages
253                         .REFERENCED_PARAMETER_NOT_FOUND.getErrorMessage(),
254                     parameterName, resourceName));
255       }
256     }
257   }
258
259   private static boolean isHeatPseudoParameter(String parameterName) {
260     return HeatPseudoParameters.getPseudoParameterNames().contains(parameterName);
261   }
262
263   /* validation 18*/
264
265   private static void validateGetAttr(String fileName,
266                                       HeatOrchestrationTemplate heatOrchestrationTemplate,
267                                       GlobalValidationContext globalContext) {
268     Map<String, Output> outputMap;
269     outputMap = heatOrchestrationTemplate.getOutputs();
270
271     if (MapUtils.isNotEmpty(outputMap)) {
272       loopOverOutputMapAndValidateGetAttrFromNested(fileName, outputMap,
273           heatOrchestrationTemplate, globalContext);
274     }
275   }
276
277   private static void loopOverOutputMapAndValidateGetAttrFromNested(String fileName,
278                                              Map<String, Output> outputMap,
279                                              HeatOrchestrationTemplate
280                                              heatOrchestrationTemplate,
281                                              GlobalValidationContext
282                                              globalContext) {
283     for (Output output : outputMap.values()) {
284       Object outputValue = output.getValue();
285       if (outputValue != null && outputValue instanceof Map) {
286         Map<String, Object> outputValueMap = (Map<String, Object>) outputValue;
287         List<String> getAttrValue =
288             (List<String>) outputValueMap.get(
289                 ResourceReferenceFunctions.GET_ATTR.getFunction());
290                 handleGetAttrValueList(getAttrValue, fileName, heatOrchestrationTemplate,
291                         globalContext);
292
293             }
294         }
295     }
296
297     private static void handleGetAttrValueList(List<String> getAttrValue, String fileName,
298                                                HeatOrchestrationTemplate heatOrchestrationTemplate,
299                                                GlobalValidationContext globalContext) {
300         if (!CollectionUtils.isEmpty(getAttrValue)) {
301             String resourceName = getAttrValue.get(0);
302             String attNameObject = getAttrValue.get(1);
303             if (attNameObject == null) {
304                 return;
305             }
306             String attName = getAttrValue.get(1);
307             String resourceType =
308                     getResourceTypeFromResourcesMap(resourceName, heatOrchestrationTemplate);
309
310             if (Objects.nonNull(resourceType)
311                     && HeatValidationService.isNestedResource(resourceType)) {
312                 handleGetAttrNestedResource(fileName, globalContext, resourceName, attName,
313                         resourceType);
314             }
315         }
316     }
317   private static void handleGetAttrNestedResource(String fileName,
318                                                   GlobalValidationContext globalContext,
319                                                   String resourceName, String attName,
320                                                   String resourceType) {
321     Map<String, Output> nestedOutputMap;
322     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
323     try {
324       Optional<InputStream> fileContent = globalContext.getFileContent(resourceType);
325       if (fileContent.isPresent()) {
326         nestedHeatOrchestrationTemplate =
327             new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
328       } else {
329         throw new Exception("The file '" + resourceType + "' has no content");
330       }
331     } catch (Exception exception) {
332             LOGGER.error("Invalid yaml file", exception);
333       return;
334     }
335     nestedOutputMap = nestedHeatOrchestrationTemplate.getOutputs();
336
337     if (MapUtils.isEmpty(nestedOutputMap) || !nestedOutputMap.containsKey(attName)) {
338       globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
339                             .getErrorWithParameters(ERROR_CODE_HOT_17,Messages
340                             .GET_ATTR_NOT_FOUND.getErrorMessage(),
341                             attName, resourceName));
342     }
343   }
344
345   private static String getResourceTypeFromResourcesMap(String resourceName,
346                                                         HeatOrchestrationTemplate
347                                                             heatOrchestrationTemplate) {
348       Resource resource = heatOrchestrationTemplate.getResources().get(resourceName);
349       if (Objects.nonNull(resource)) {
350           return resource.getType();
351       } else {
352           return null;
353       }
354   }
355
356   /* validation 17 + */
357   private static void validateEnvFile(String fileName, String envFileName,
358                                       HeatOrchestrationTemplate heatOrchestrationTemplate,
359                                       GlobalValidationContext globalContext) {
360     Environment envContent;
361
362     if (!envFileName.contains(".env")) {
363       globalContext.addMessage(envFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
364               .getErrorWithParameters(ERROR_CODE_HOT_2,Messages
365                   .WRONG_ENV_FILE_EXTENSION.getErrorMessage(), envFileName));
366     }
367
368     envContent = HeatValidationService.validateEnvContent(fileName, envFileName, globalContext);
369     if (envContent != null) {
370       validateEnvContentIsSubSetOfHeatParameters(envFileName, envContent, globalContext,
371           heatOrchestrationTemplate);
372       validateEnvParametersMatchDefinedHeatParameterTypes(envFileName, envContent, globalContext,
373           heatOrchestrationTemplate);
374     }
375   }
376
377   private static void validateEnvContentIsSubSetOfHeatParameters(String envFile,
378                                                                  Environment envContent,
379                                                                  GlobalValidationContext
380                                                                      globalContext,
381                                                                  HeatOrchestrationTemplate
382                                                                      heatOrchestrationTemplate) {
383     Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
384         : heatOrchestrationTemplate.getParameters().keySet();
385
386     if (MapUtils.isNotEmpty(envContent.getParameters())) {
387       if (CollectionUtils.isNotEmpty(parametersNames)) {
388         for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
389
390
391             validateEnvEntryForvalidateEnvContentIsSubSetOfHeatParameters(envEntry,
392                     parametersNames, envFile, globalContext);
393         }
394       } else {
395         for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
396           globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
397                   .getErrorWithParameters(ERROR_CODE_HOT_3,Messages
398                           .ENV_INCLUDES_PARAMETER_NOT_IN_HEAT.getErrorMessage(),
399                       envFile, envEntry.getKey()));
400         }
401       }
402     }
403   }
404
405    private static void validateEnvEntryForvalidateEnvContentIsSubSetOfHeatParameters(
406                         Map.Entry<String, Object> envEntry,
407                         Set<String> parametersNames,
408                         String envFile,
409                         GlobalValidationContext globalContext) {
410     String envParameter = envEntry.getKey();
411     if (parametersNames != null && !parametersNames.contains(envParameter)) {
412         globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
413                         .getErrorWithParameters(
414                                 ERROR_CODE_HOT_3,Messages
415                                 .ENV_INCLUDES_PARAMETER_NOT_IN_HEAT.getErrorMessage(), envFile,
416                                 envParameter));
417     }
418 }
419   private static void validateParameterDefaultTypeAlignWithType(String fileName,
420                                                                 HeatOrchestrationTemplate
421                                                                     heatOrchestrationTemplate,
422                                                                 GlobalValidationContext
423                                                                     globalContext) {
424     Map<String, Parameter> parametersMap = heatOrchestrationTemplate.getParameters();
425
426     if (parametersMap != null && MapUtils.isNotEmpty(parametersMap)) {
427       for (Map.Entry<String, Parameter> parameterEntry : parametersMap.entrySet()) {
428           validateParameterEntryForParameterDefaultTypeAlignWithType(parameterEntry,
429                         fileName, globalContext);
430       }
431     }
432   }
433     private static void validateParameterEntryForParameterDefaultTypeAlignWithType(
434                             Map.Entry<String, Parameter> parameterEntry,
435                             String fileName, GlobalValidationContext globalContext){
436         Parameter parameter = parameterEntry.getValue();
437         String parameterType = parameter.getType();
438         Object parameterDefault = parameter.get_default();
439         if (parameterDefault != null && parameterType != null) {
440             boolean isValueMatchDefault =
441                     DefinedHeatParameterTypes.isValueIsFromGivenType(parameterDefault,
442                             parameterType);
443             if (!isValueMatchDefault) {
444                 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
445                                 .getErrorWithParameters(
446                                 ERROR_CODE_HOT_4,Messages
447                                 .PARAMETER_DEFAULT_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
448                                 parameterEntry.getKey(), parameterType));
449             }
450         }
451     }
452
453   private static void validateEnvParametersMatchDefinedHeatParameterTypes(String envFile,
454                                                  Environment envContent,
455                                                  GlobalValidationContext globalContext,
456                                                  HeatOrchestrationTemplate heatOrchestrationTemplate) {
457     Map<String, Parameter> heatParameters = heatOrchestrationTemplate.getParameters();
458
459     if (MapUtils.isNotEmpty(heatParameters) && MapUtils.isNotEmpty(envContent.getParameters())) {
460         validateEnvEntryForEnvParametersMatchDefinedHeatParameterTypes(envContent,
461                         heatParameters, envFile, globalContext);
462
463
464     }
465   }
466
467   private static void validateEnvEntryForEnvParametersMatchDefinedHeatParameterTypes(
468                                                           Environment envContent,
469                                                           Map<String, Parameter> heatParameters,
470                                                           String envFile,
471                                                           GlobalValidationContext globalContext) {
472       for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
473           String parameterName = envEntry.getKey();
474           Object parameterEnvValue = envEntry.getValue();
475           Parameter parameterFromHeatFile = heatParameters.get(parameterName);
476           if (parameterFromHeatFile != null) {
477               String parameterType = parameterFromHeatFile.getType();
478               if (!DefinedHeatParameterTypes.isEmptyValueInEnv(parameterEnvValue)
479                       && !DefinedHeatParameterTypes
480                       .isValueIsFromGivenType(parameterEnvValue, parameterType)) {
481                   globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
482                                   .getErrorWithParameters(
483                                   ERROR_CODE_HOT_5,Messages
484                                   .PARAMETER_ENV_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
485                                   parameterName));
486               }
487           }
488       }
489   }
490
491   @Override
492   public void validate(GlobalValidationContext globalContext) {
493     ManifestContent manifestContent;
494     try {
495       manifestContent = ValidationUtil.validateManifest(globalContext);
496     } catch (Exception exception) {
497       LOGGER.error("Failed to validate manifest file", exception);
498       return;
499     }
500     Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent);
501     Map<String, FileData> fileEnvMap = ManifestUtil.getFileAndItsEnv(manifestContent);
502     Set<String> artifacts = new HashSet<>();
503
504     globalContext.getFiles().stream()
505         .filter(fileName -> FileData.isHeatFile(fileTypeMap.get(fileName))).forEach(
506         fileName -> validate(fileName, fileEnvMap.get(fileName) == null ? null : fileEnvMap.get(
507             fileName).getFile(), artifacts,
508              globalContext));
509
510     Set<String> manifestArtifacts = ManifestUtil.getArtifacts(manifestContent);
511
512     globalContext.getFiles().stream().filter(fileName -> isManifestArtifact(manifestArtifacts, fileName)
513         && isNotArtifact(artifacts, fileName)).forEach(fileName -> {
514
515             globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
516                 .getErrorWithParameters(ERROR_CODE_HOT_11,
517                     Messages.ARTIFACT_FILE_NOT_REFERENCED.getErrorMessage()));
518
519             validateGeneratedArtifact(fileName, globalContext);
520
521         });
522     }
523
524   private void validateGeneratedArtifact(String fileName, GlobalValidationContext globalContext) {
525         if (GENERATED_ARTIFACTS.contains(fileName)) {
526             globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
527                 .getErrorWithParameters(ERROR_CODE_HOT_18,
528                     Messages.GENERATED_ARTIFACT_IN_USE.getErrorMessage(), fileName));
529         }
530   }
531
532   private static Set<String> getGeneratedArtifactNames() {
533     Set<String> predefinedArtifactNames = new HashSet<>();
534     predefinedArtifactNames.add(VF_LICENSE_MODEL_XML);
535     predefinedArtifactNames.add(VENDOR_LICENSE_MODEL_XML);
536     predefinedArtifactNames.add(HEAT_META);
537     return predefinedArtifactNames;
538   }
539
540   private boolean isManifestArtifact(Set<String> manifestArtifacts, String fileName) {
541     return manifestArtifacts.contains(fileName);
542   }
543
544   private boolean isNotArtifact(Set<String> artifacts, String fileName) {
545     return !artifacts.contains(fileName);
546   }
547
548   private void validate(String fileName, String envFileName,
549                         Set<String> artifacts,
550                         GlobalValidationContext globalContext) {
551     globalContext.setMessageCode(ERROR_CODE_HOT_12);
552     HeatOrchestrationTemplate
553         heatOrchestrationTemplate = ValidationUtil.checkHeatOrchestrationPreCondition(
554         fileName, globalContext);
555
556
557     if (heatOrchestrationTemplate != null) {
558       if (!(fileName.contains(".yaml") || fileName.contains(".yml"))) {
559         globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
560                 .getErrorWithParameters(ERROR_CODE_HOT_6,Messages
561                     .WRONG_HEAT_FILE_EXTENSION.getErrorMessage(), fileName));
562       }
563
564       validateHeatBaseStructure(fileName, heatOrchestrationTemplate, globalContext);
565       validateParameterDefaultTypeAlignWithType(fileName, heatOrchestrationTemplate, globalContext);
566       validateAllResourceReferencesExist(fileName, heatOrchestrationTemplate, globalContext);
567       validateResourceDependsOn(fileName, heatOrchestrationTemplate, globalContext);
568       validateGetParamPointToParameter(fileName, heatOrchestrationTemplate, globalContext);
569       validateGetAttr(fileName, heatOrchestrationTemplate, globalContext);
570       validateAllRequiredArtifactsExist(fileName, heatOrchestrationTemplate, artifacts,
571           globalContext);
572
573       if (envFileName != null) {
574         validateEnvFile(fileName, envFileName, heatOrchestrationTemplate, globalContext);
575       }
576     }
577   }
578
579   private void validateResourceDependsOn(String fileName,
580                                          HeatOrchestrationTemplate heatOrchestrationTemplate,
581                                          GlobalValidationContext globalContext) {
582     Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
583     if(MapUtils.isEmpty(resourcesMap)) {
584       return;
585     }
586
587     Set<String> resourcesNames = resourcesMap.keySet();
588
589     resourcesMap.entrySet().stream()
590         .forEach(entry -> checkResourceDependsOn(fileName, entry.getValue(),
591             resourcesNames, globalContext));
592   }
593
594   @SuppressWarnings("unchecked")
595   private static void checkResourceDependsOn(String fileName, Resource resource,
596                                              Set<String> resourcesNames,
597                                              GlobalValidationContext globalContext) {
598     Object dependencies = resource.getDepends_on();
599     if (dependencies instanceof Collection) {
600       ((Collection<String>) dependencies)
601           .stream()
602           .filter(resourceId -> !resourcesNames.contains(resourceId))
603           .forEach(resourceId -> globalContext.addMessage(fileName, ErrorLevel.ERROR,
604               ErrorMessagesFormatBuilder
605                   .getErrorWithParameters(ERROR_CODE_HOT_7,
606                           Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(), resourceId)));
607     } else if (dependencies instanceof String && !resourcesNames.contains(dependencies)) {
608         globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
609                 .getErrorWithParameters(ERROR_CODE_HOT_8,
610                         Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(), String.valueOf(dependencies)));
611       }
612   }
613
614
615   private void validateHeatBaseStructure(String fileName,
616                                          HeatOrchestrationTemplate heatOrchestrationTemplate,
617                                          GlobalValidationContext globalContext) {
618     if (heatOrchestrationTemplate.getHeat_template_version() == null) {
619       globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
620               .getErrorWithParameters(ERROR_CODE_HOT_9,
621                       Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
622                   "missing template version"));
623     }
624     if (heatOrchestrationTemplate.getResources() == null
625         || heatOrchestrationTemplate.getResources().size() == 0) {
626       globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
627               .getErrorWithParameters(ERROR_CODE_HOT_10,
628                       Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
629                "The heat file does not contain any resources"));
630     }
631   }
632
633
634   @SuppressWarnings("unchecked")
635   private void getSecurityGroupsReferencedResourcesFromOutputs(
636       Set<String> securityGroupsNamesFromOutputsMap, Map<String, Output> outputMap,
637       Map<String, Resource> resourceMap) {
638     if (MapUtils.isNotEmpty(outputMap)) {
639       for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
640
641           validateOutputEntryForGetSecurityGroupsReferencedResourcesFromOutputs(outputEntry,
642                   resourceMap, securityGroupsNamesFromOutputsMap);
643
644       }
645     }
646   }
647     private void validateOutputEntryForGetSecurityGroupsReferencedResourcesFromOutputs(
648             Map.Entry<String, Output> outputEntry,
649             Map<String, Resource> resourceMap, Set<String> securityGroupsNamesFromOutputsMap){
650         Object outputValue = outputEntry.getValue().getValue();
651         if (Objects.nonNull(outputValue) && outputValue instanceof Map) {
652             String resourceName = (String) ((Map) outputValue)
653                     .get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
654             if (Objects.nonNull(resourceName)) {
655                 Resource resource = resourceMap.get(resourceName);
656                 if (Objects.nonNull(resource) && resource.getType().equals(
657                         HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE.getHeatResource())) {
658                     securityGroupsNamesFromOutputsMap.add(outputEntry.getKey());
659                 }
660             }
661         }
662     }
663
664 }