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