2 * Copyright © 2016-2017 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.openecomp.sdc.validation.impl.validators;
19 import java.io.InputStream;
20 import java.util.Collection;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
28 import org.apache.commons.collections4.CollectionUtils;
29 import org.apache.commons.collections4.MapUtils;
30 import org.onap.sdc.tosca.services.YamlUtil;
31 import org.openecomp.core.validation.ErrorMessageCode;
32 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
33 import org.openecomp.core.validation.types.GlobalValidationContext;
34 import org.openecomp.sdc.common.errors.Messages;
35 import org.openecomp.sdc.datatypes.error.ErrorLevel;
36 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
37 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
38 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
39 import org.openecomp.sdc.heat.datatypes.model.Environment;
40 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
41 import org.openecomp.sdc.heat.datatypes.model.HeatPseudoParameters;
42 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
43 import org.openecomp.sdc.heat.datatypes.model.Output;
44 import org.openecomp.sdc.heat.datatypes.model.Parameter;
45 import org.openecomp.sdc.heat.datatypes.model.Resource;
46 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
47 import org.openecomp.sdc.heat.services.HeatStructureUtil;
48 import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
49 import org.openecomp.sdc.logging.api.Logger;
50 import org.openecomp.sdc.logging.api.LoggerFactory;
51 import org.openecomp.sdc.validation.Validator;
52 import org.openecomp.sdc.validation.impl.util.HeatValidationService;
53 import org.openecomp.sdc.validation.util.ValidationUtil;
55 public class HeatValidator implements Validator {
56 private static final Logger LOGGER = LoggerFactory.getLogger(HeatValidator.class);
57 private static final ErrorMessageCode ERROR_CODE_HOT_1 = new ErrorMessageCode("HOT1");
58 private static final ErrorMessageCode ERROR_CODE_HOT_2 = new ErrorMessageCode("HOT2");
59 private static final ErrorMessageCode ERROR_CODE_HOT_3 = new ErrorMessageCode("HOT3");
60 private static final ErrorMessageCode ERROR_CODE_HOT_4 = new ErrorMessageCode("HOT4");
61 private static final ErrorMessageCode ERROR_CODE_HOT_5 = new ErrorMessageCode("HOT5");
62 private static final ErrorMessageCode ERROR_CODE_HOT_6 = new ErrorMessageCode("HOT6");
63 private static final ErrorMessageCode ERROR_CODE_HOT_7 = new ErrorMessageCode("HOT7");
64 private static final ErrorMessageCode ERROR_CODE_HOT_8 = new ErrorMessageCode("HOT8");
65 private static final ErrorMessageCode ERROR_CODE_HOT_9 = new ErrorMessageCode("HOT9");
66 private static final ErrorMessageCode ERROR_CODE_HOT_10 = new ErrorMessageCode("HOT10");
67 private static final ErrorMessageCode ERROR_CODE_HOT_11 = new ErrorMessageCode("HOT11");
68 private static final ErrorMessageCode ERROR_CODE_HOT_12 = new ErrorMessageCode("HOT12");
69 private static final ErrorMessageCode ERROR_CODE_HOT_13 = new ErrorMessageCode("HOT13");
70 private static final ErrorMessageCode ERROR_CODE_HOT_14 = new ErrorMessageCode("HOT14");
71 private static final ErrorMessageCode ERROR_CODE_HOT_15 = new ErrorMessageCode("HOT15");
72 private static final ErrorMessageCode ERROR_CODE_HOT_16 = new ErrorMessageCode("HOT16");
73 private static final ErrorMessageCode ERROR_CODE_HOT_17 = new ErrorMessageCode("HOT17");
75 private static final ErrorMessageCode ERROR_CODE_HOT_18 = new ErrorMessageCode("HOT18");
77 // The Artifacts generated by SDC - not allowed to be in HEAT
78 static final String VF_LICENSE_MODEL_XML = "vf-license-model.xml";
79 static final String VENDOR_LICENSE_MODEL_XML = "vendor-license-model.xml";
80 static final String HEAT_META = "HEAT.meta";
82 private static final Set<String> GENERATED_ARTIFACTS;
85 GENERATED_ARTIFACTS = getGeneratedArtifactNames();
88 private static void validateAllRequiredArtifactsExist(String fileName,
89 HeatOrchestrationTemplate
90 heatOrchestrationTemplate,
91 Set<String> artifacts,
92 GlobalValidationContext globalContext) {
93 Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
94 : heatOrchestrationTemplate.getResources().values();
96 if (CollectionUtils.isNotEmpty(resourcesValues)) {
97 for (Resource resource : resourcesValues) {
98 Collection<Object> properties =
99 resource.getProperties() == null ? null : resource.getProperties().values();
100 validatePropertiesForAllRequiredArtifactsExist(properties, fileName,
101 artifacts, globalContext);
106 private static void validatePropertiesForAllRequiredArtifactsExist(Collection<Object> properties,
108 Set<String> artifacts,
109 GlobalValidationContext globalContext) {
110 if (CollectionUtils.isNotEmpty(properties)) {
111 for (Object property : properties) {
112 if (property instanceof Map) {
113 globalContext.setMessageCode(ERROR_CODE_HOT_14);
114 Set<String> artifactNames = HeatStructureUtil
115 .getReferencedValuesByFunctionName(fileName,
116 ResourceReferenceFunctions.GET_FILE.getFunction(), property, globalContext);
117 artifacts.addAll(artifactNames);
118 globalContext.setMessageCode(ERROR_CODE_HOT_15);
119 HeatValidationService.checkArtifactsExistence(fileName, artifactNames,
127 private static void validateAllResourceReferencesExist(String fileName,
128 HeatOrchestrationTemplate
129 heatOrchestrationTemplate,
130 GlobalValidationContext globalContext) {
131 Set<String> resourcesNames = heatOrchestrationTemplate.getResources() == null ? null
132 : heatOrchestrationTemplate.getResources().keySet();
133 Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
134 : heatOrchestrationTemplate.getResources().values();
135 Collection<Output> outputsValues = heatOrchestrationTemplate.getOutputs() == null ? null
136 : heatOrchestrationTemplate.getOutputs().values();
137 checkResourceExistenceFromResourcesMap(fileName, resourcesNames, resourcesValues,
139 checkResourceExistenceFromResourcesMap(fileName, resourcesNames, outputsValues,
143 private static void checkResourceExistenceFromResourcesMap(String fileName,
144 Set<String> resourcesNames,
145 Collection<?> valuesToSearchIn,
146 GlobalValidationContext globalContext) {
147 if (CollectionUtils.isNotEmpty(valuesToSearchIn)) {
148 for (Object value : valuesToSearchIn) {
149 if (value instanceof Resource) {
150 extractResourceProperty(fileName, resourcesNames, globalContext,
152 } else if (value instanceof Output) {
153 Output output = (Output) value;
154 Object outputsValue = output.getValue();
155 handleReferencedResources(fileName, outputsValue, resourcesNames,
162 private static void extractResourceProperty(String fileName, Set<String> resourcesNames,
163 GlobalValidationContext globalContext,
165 Collection<Object> resourcePropertiesValues =
166 value.getProperties() == null ? null : value.getProperties()
168 if (CollectionUtils.isNotEmpty(resourcePropertiesValues)) {
169 for (Object propertyValue : resourcePropertiesValues) {
170 handleReferencedResources(fileName, propertyValue, resourcesNames,
176 private static void handleReferencedResources(String fileName, Object valueToSearchReferencesIn,
177 Set<String> resourcesNames,
178 GlobalValidationContext globalContext) {
179 globalContext.setMessageCode(ERROR_CODE_HOT_13);
180 Set<String> referencedResourcesNames = HeatStructureUtil
181 .getReferencedValuesByFunctionName(fileName,
182 ResourceReferenceFunctions.GET_RESOURCE.getFunction(),
183 valueToSearchReferencesIn, globalContext);
184 if (CollectionUtils.isNotEmpty(referencedResourcesNames)) {
185 checkIfResourceReferenceExist(fileName, resourcesNames, referencedResourcesNames,
190 private static void checkIfResourceReferenceExist(String fileName,
191 Set<String> referencedResourcesNames,
192 Set<String> referencedResources,
193 GlobalValidationContext globalContext) {
194 referencedResources.stream()
195 .filter(referencedResource -> !referencedResourcesNames
196 .contains(referencedResource))
197 .forEach(referencedResource ->
198 globalContext.addMessage(fileName,
199 ErrorLevel.ERROR, ErrorMessagesFormatBuilder
200 .getErrorWithParameters(ERROR_CODE_HOT_16,Messages
201 .REFERENCED_RESOURCE_NOT_FOUND.getErrorMessage(), referencedResource)));
206 private static void validateGetParamPointToParameter(String fileName,
207 HeatOrchestrationTemplate
208 heatOrchestrationTemplate,
209 GlobalValidationContext globalContext) {
210 Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
211 : heatOrchestrationTemplate.getParameters().keySet();
212 Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
214 if (CollectionUtils.isNotEmpty(parametersNames) && MapUtils.isNotEmpty(resourcesMap)) {
215 for (Map.Entry<String, Resource> resourceEntry : resourcesMap.entrySet()) {
216 Resource resource = resourceEntry.getValue();
217 Map<String, Object> properties = resource.getProperties();
218 validatePropertiesForGetParamPointToParameter(properties, fileName, parametersNames,
219 resourceEntry, globalContext);
224 private static void validatePropertiesForGetParamPointToParameter(Map<String,
226 String fileName, Set<String> parametersNames,
227 Map.Entry<String, Resource> resourceEntry,
228 GlobalValidationContext globalContext) {
229 if (MapUtils.isNotEmpty(properties)) {
230 Collection<Object> propertiesValues = properties.values();
231 if (CollectionUtils.isNotEmpty(propertiesValues)) {
232 for (Object propertyObject : propertiesValues) {
233 Set<String> referencedParameterNames = HeatStructureUtil
234 .getReferencedValuesByFunctionName(fileName, "get_param", propertyObject,
237 validateReferenceParams(fileName, resourceEntry.getKey(), parametersNames,
238 referencedParameterNames, globalContext);
244 private static void validateReferenceParams(String fileName, String resourceName,
245 Set<String> parametersNamesFromFile,
246 Set<String> referencedParametersNames,
247 GlobalValidationContext globalContext) {
248 for (String parameterName : referencedParametersNames) {
249 if (!isHeatPseudoParameter(parameterName)
250 && !parametersNamesFromFile.contains(parameterName)) {
251 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
252 .getErrorWithParameters(ERROR_CODE_HOT_1,Messages
253 .REFERENCED_PARAMETER_NOT_FOUND.getErrorMessage(),
254 parameterName, resourceName));
259 private static boolean isHeatPseudoParameter(String parameterName) {
260 return HeatPseudoParameters.getPseudoParameterNames().contains(parameterName);
265 private static void validateGetAttr(String fileName,
266 HeatOrchestrationTemplate heatOrchestrationTemplate,
267 GlobalValidationContext globalContext) {
268 Map<String, Output> outputMap;
269 outputMap = heatOrchestrationTemplate.getOutputs();
271 if (MapUtils.isNotEmpty(outputMap)) {
272 loopOverOutputMapAndValidateGetAttrFromNested(fileName, outputMap,
273 heatOrchestrationTemplate, globalContext);
277 private static void loopOverOutputMapAndValidateGetAttrFromNested(String fileName,
278 Map<String, Output> outputMap,
279 HeatOrchestrationTemplate
280 heatOrchestrationTemplate,
281 GlobalValidationContext
283 for (Output output : outputMap.values()) {
284 Object outputValue = output.getValue();
285 if (outputValue != null && outputValue instanceof Map) {
286 Map<String, Object> outputValueMap = (Map<String, Object>) outputValue;
287 List<String> getAttrValue =
288 (List<String>) outputValueMap.get(
289 ResourceReferenceFunctions.GET_ATTR.getFunction());
290 handleGetAttrValueList(getAttrValue, fileName, heatOrchestrationTemplate,
297 private static void handleGetAttrValueList(List<String> getAttrValue, String fileName,
298 HeatOrchestrationTemplate heatOrchestrationTemplate,
299 GlobalValidationContext globalContext) {
300 if (!CollectionUtils.isEmpty(getAttrValue)) {
301 String resourceName = getAttrValue.get(0);
302 String attNameObject = getAttrValue.get(1);
303 if (attNameObject == null) {
306 String attName = getAttrValue.get(1);
307 String resourceType =
308 getResourceTypeFromResourcesMap(resourceName, heatOrchestrationTemplate);
310 if (Objects.nonNull(resourceType)
311 && HeatValidationService.isNestedResource(resourceType)) {
312 handleGetAttrNestedResource(fileName, globalContext, resourceName, attName,
317 private static void handleGetAttrNestedResource(String fileName,
318 GlobalValidationContext globalContext,
319 String resourceName, String attName,
320 String resourceType) {
321 Map<String, Output> nestedOutputMap;
322 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
324 Optional<InputStream> fileContent = globalContext.getFileContent(resourceType);
325 if (fileContent.isPresent()) {
326 nestedHeatOrchestrationTemplate =
327 new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
329 throw new Exception("The file '" + resourceType + "' has no content");
331 } catch (Exception exception) {
332 LOGGER.error("Invalid yaml file", exception);
335 nestedOutputMap = nestedHeatOrchestrationTemplate.getOutputs();
337 if (MapUtils.isEmpty(nestedOutputMap) || !nestedOutputMap.containsKey(attName)) {
338 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
339 .getErrorWithParameters(ERROR_CODE_HOT_17,Messages
340 .GET_ATTR_NOT_FOUND.getErrorMessage(),
341 attName, resourceName));
345 private static String getResourceTypeFromResourcesMap(String resourceName,
346 HeatOrchestrationTemplate
347 heatOrchestrationTemplate) {
348 Resource resource = heatOrchestrationTemplate.getResources().get(resourceName);
349 if (Objects.nonNull(resource)) {
350 return resource.getType();
356 /* validation 17 + */
357 private static void validateEnvFile(String fileName, String envFileName,
358 HeatOrchestrationTemplate heatOrchestrationTemplate,
359 GlobalValidationContext globalContext) {
360 Environment envContent;
362 if (!envFileName.contains(".env")) {
363 globalContext.addMessage(envFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
364 .getErrorWithParameters(ERROR_CODE_HOT_2,Messages
365 .WRONG_ENV_FILE_EXTENSION.getErrorMessage(), envFileName));
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);
377 private static void validateEnvContentIsSubSetOfHeatParameters(String envFile,
378 Environment envContent,
379 GlobalValidationContext
381 HeatOrchestrationTemplate
382 heatOrchestrationTemplate) {
383 Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
384 : heatOrchestrationTemplate.getParameters().keySet();
386 if (MapUtils.isNotEmpty(envContent.getParameters())) {
387 if (CollectionUtils.isNotEmpty(parametersNames)) {
388 for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
391 validateEnvEntryForvalidateEnvContentIsSubSetOfHeatParameters(envEntry,
392 parametersNames, envFile, globalContext);
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()));
405 private static void validateEnvEntryForvalidateEnvContentIsSubSetOfHeatParameters(
406 Map.Entry<String, Object> envEntry,
407 Set<String> parametersNames,
409 GlobalValidationContext globalContext) {
410 String envParameter = envEntry.getKey();
411 if (parametersNames != null && !parametersNames.contains(envParameter)) {
412 globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
413 .getErrorWithParameters(
414 ERROR_CODE_HOT_3,Messages
415 .ENV_INCLUDES_PARAMETER_NOT_IN_HEAT.getErrorMessage(), envFile,
419 private static void validateParameterDefaultTypeAlignWithType(String fileName,
420 HeatOrchestrationTemplate
421 heatOrchestrationTemplate,
422 GlobalValidationContext
424 Map<String, Parameter> parametersMap = heatOrchestrationTemplate.getParameters();
426 if (parametersMap != null && MapUtils.isNotEmpty(parametersMap)) {
427 for (Map.Entry<String, Parameter> parameterEntry : parametersMap.entrySet()) {
428 validateParameterEntryForParameterDefaultTypeAlignWithType(parameterEntry,
429 fileName, globalContext);
433 private static void validateParameterEntryForParameterDefaultTypeAlignWithType(
434 Map.Entry<String, Parameter> parameterEntry,
435 String fileName, GlobalValidationContext globalContext){
436 Parameter parameter = parameterEntry.getValue();
437 String parameterType = parameter.getType();
438 Object parameterDefault = parameter.get_default();
439 if (parameterDefault != null && parameterType != null) {
440 boolean isValueMatchDefault =
441 DefinedHeatParameterTypes.isValueIsFromGivenType(parameterDefault,
443 if (!isValueMatchDefault) {
444 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
445 .getErrorWithParameters(
446 ERROR_CODE_HOT_4,Messages
447 .PARAMETER_DEFAULT_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
448 parameterEntry.getKey(), parameterType));
453 private static void validateEnvParametersMatchDefinedHeatParameterTypes(String envFile,
454 Environment envContent,
455 GlobalValidationContext globalContext,
456 HeatOrchestrationTemplate heatOrchestrationTemplate) {
457 Map<String, Parameter> heatParameters = heatOrchestrationTemplate.getParameters();
459 if (MapUtils.isNotEmpty(heatParameters) && MapUtils.isNotEmpty(envContent.getParameters())) {
460 validateEnvEntryForEnvParametersMatchDefinedHeatParameterTypes(envContent,
461 heatParameters, envFile, globalContext);
467 private static void validateEnvEntryForEnvParametersMatchDefinedHeatParameterTypes(
468 Environment envContent,
469 Map<String, Parameter> heatParameters,
471 GlobalValidationContext globalContext) {
472 for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
473 String parameterName = envEntry.getKey();
474 Object parameterEnvValue = envEntry.getValue();
475 Parameter parameterFromHeatFile = heatParameters.get(parameterName);
476 if (parameterFromHeatFile != null) {
477 String parameterType = parameterFromHeatFile.getType();
478 if (!DefinedHeatParameterTypes.isEmptyValueInEnv(parameterEnvValue)
479 && !DefinedHeatParameterTypes
480 .isValueIsFromGivenType(parameterEnvValue, parameterType)) {
481 globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
482 .getErrorWithParameters(
483 ERROR_CODE_HOT_5,Messages
484 .PARAMETER_ENV_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
492 public void validate(GlobalValidationContext globalContext) {
493 ManifestContent manifestContent;
495 manifestContent = ValidationUtil.validateManifest(globalContext);
496 } catch (Exception exception) {
497 LOGGER.error("Failed to validate manifest file", exception);
500 Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent);
501 Map<String, FileData> fileEnvMap = ManifestUtil.getFileAndItsEnv(manifestContent);
502 Set<String> artifacts = new HashSet<>();
504 globalContext.getFiles().stream()
505 .filter(fileName -> FileData.isHeatFile(fileTypeMap.get(fileName))).forEach(
506 fileName -> validate(fileName, fileEnvMap.get(fileName) == null ? null : fileEnvMap.get(
507 fileName).getFile(), artifacts,
510 Set<String> manifestArtifacts = ManifestUtil.getArtifacts(manifestContent);
512 globalContext.getFiles().stream().filter(fileName -> isManifestArtifact(manifestArtifacts, fileName)
513 && isNotArtifact(artifacts, fileName)).forEach(fileName -> {
515 globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
516 .getErrorWithParameters(ERROR_CODE_HOT_11,
517 Messages.ARTIFACT_FILE_NOT_REFERENCED.getErrorMessage()));
519 validateGeneratedArtifact(fileName, globalContext);
524 private void validateGeneratedArtifact(String fileName, GlobalValidationContext globalContext) {
525 if (GENERATED_ARTIFACTS.contains(fileName)) {
526 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
527 .getErrorWithParameters(ERROR_CODE_HOT_18,
528 Messages.GENERATED_ARTIFACT_IN_USE.getErrorMessage(), fileName));
532 private static Set<String> getGeneratedArtifactNames() {
533 Set<String> predefinedArtifactNames = new HashSet<>();
534 predefinedArtifactNames.add(VF_LICENSE_MODEL_XML);
535 predefinedArtifactNames.add(VENDOR_LICENSE_MODEL_XML);
536 predefinedArtifactNames.add(HEAT_META);
537 return predefinedArtifactNames;
540 private boolean isManifestArtifact(Set<String> manifestArtifacts, String fileName) {
541 return manifestArtifacts.contains(fileName);
544 private boolean isNotArtifact(Set<String> artifacts, String fileName) {
545 return !artifacts.contains(fileName);
548 private void validate(String fileName, String envFileName,
549 Set<String> artifacts,
550 GlobalValidationContext globalContext) {
551 globalContext.setMessageCode(ERROR_CODE_HOT_12);
552 HeatOrchestrationTemplate
553 heatOrchestrationTemplate = ValidationUtil.checkHeatOrchestrationPreCondition(
554 fileName, globalContext);
557 if (heatOrchestrationTemplate != null) {
558 if (!(fileName.contains(".yaml") || fileName.contains(".yml"))) {
559 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
560 .getErrorWithParameters(ERROR_CODE_HOT_6,Messages
561 .WRONG_HEAT_FILE_EXTENSION.getErrorMessage(), fileName));
564 validateHeatBaseStructure(fileName, heatOrchestrationTemplate, globalContext);
565 validateParameterDefaultTypeAlignWithType(fileName, heatOrchestrationTemplate, globalContext);
566 validateAllResourceReferencesExist(fileName, heatOrchestrationTemplate, globalContext);
567 validateResourceDependsOn(fileName, heatOrchestrationTemplate, globalContext);
568 validateGetParamPointToParameter(fileName, heatOrchestrationTemplate, globalContext);
569 validateGetAttr(fileName, heatOrchestrationTemplate, globalContext);
570 validateAllRequiredArtifactsExist(fileName, heatOrchestrationTemplate, artifacts,
573 if (envFileName != null) {
574 validateEnvFile(fileName, envFileName, heatOrchestrationTemplate, globalContext);
579 private void validateResourceDependsOn(String fileName,
580 HeatOrchestrationTemplate heatOrchestrationTemplate,
581 GlobalValidationContext globalContext) {
582 Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
583 if(MapUtils.isEmpty(resourcesMap)) {
587 Set<String> resourcesNames = resourcesMap.keySet();
589 resourcesMap.entrySet().stream()
590 .forEach(entry -> checkResourceDependsOn(fileName, entry.getValue(),
591 resourcesNames, globalContext));
594 @SuppressWarnings("unchecked")
595 private static void checkResourceDependsOn(String fileName, Resource resource,
596 Set<String> resourcesNames,
597 GlobalValidationContext globalContext) {
598 Object dependencies = resource.getDepends_on();
599 if (dependencies instanceof Collection) {
600 ((Collection<String>) dependencies)
602 .filter(resourceId -> !resourcesNames.contains(resourceId))
603 .forEach(resourceId -> globalContext.addMessage(fileName, ErrorLevel.ERROR,
604 ErrorMessagesFormatBuilder
605 .getErrorWithParameters(ERROR_CODE_HOT_7,
606 Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(), resourceId)));
607 } else if (dependencies instanceof String && !resourcesNames.contains(dependencies)) {
608 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
609 .getErrorWithParameters(ERROR_CODE_HOT_8,
610 Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(), String.valueOf(dependencies)));
615 private void validateHeatBaseStructure(String fileName,
616 HeatOrchestrationTemplate heatOrchestrationTemplate,
617 GlobalValidationContext globalContext) {
618 if (heatOrchestrationTemplate.getHeat_template_version() == null) {
619 globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
620 .getErrorWithParameters(ERROR_CODE_HOT_9,
621 Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
622 "missing template version"));
624 if (heatOrchestrationTemplate.getResources() == null
625 || heatOrchestrationTemplate.getResources().size() == 0) {
626 globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
627 .getErrorWithParameters(ERROR_CODE_HOT_10,
628 Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
629 "The heat file does not contain any resources"));
634 @SuppressWarnings("unchecked")
635 private void getSecurityGroupsReferencedResourcesFromOutputs(
636 Set<String> securityGroupsNamesFromOutputsMap, Map<String, Output> outputMap,
637 Map<String, Resource> resourceMap) {
638 if (MapUtils.isNotEmpty(outputMap)) {
639 for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
641 validateOutputEntryForGetSecurityGroupsReferencedResourcesFromOutputs(outputEntry,
642 resourceMap, securityGroupsNamesFromOutputsMap);
647 private void validateOutputEntryForGetSecurityGroupsReferencedResourcesFromOutputs(
648 Map.Entry<String, Output> outputEntry,
649 Map<String, Resource> resourceMap, Set<String> securityGroupsNamesFromOutputsMap){
650 Object outputValue = outputEntry.getValue().getValue();
651 if (Objects.nonNull(outputValue) && outputValue instanceof Map) {
652 String resourceName = (String) ((Map) outputValue)
653 .get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
654 if (Objects.nonNull(resourceName)) {
655 Resource resource = resourceMap.get(resourceName);
656 if (Objects.nonNull(resource) && resource.getType().equals(
657 HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE.getHeatResource())) {
658 securityGroupsNamesFromOutputsMap.add(outputEntry.getKey());