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