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