2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.validation.impl.validators;
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;
56 import java.io.InputStream;
57 import java.util.Collection;
58 import java.util.HashSet;
59 import java.util.List;
61 import java.util.Objects;
62 import java.util.Optional;
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");
86 private static void validateAllRequiredArtifactsExist(String fileName,
87 HeatOrchestrationTemplate
88 heatOrchestrationTemplate,
89 Set<String> artifacts,
90 GlobalValidationContext globalContext) {
92 mdcDataDebugMessage.debugEntryMessage("file", fileName);
94 Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
95 : heatOrchestrationTemplate.getResources().values();
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);
117 mdcDataDebugMessage.debugExitMessage("file", fileName);
122 private static void validateAllResourceReferencesExist(String fileName,
123 HeatOrchestrationTemplate
124 heatOrchestrationTemplate,
125 GlobalValidationContext globalContext) {
127 mdcDataDebugMessage.debugEntryMessage("file", fileName);
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,
137 checkResourceExistenceFromResourcesMap(fileName, resourcesNames, outputsValues,
140 mdcDataDebugMessage.debugExitMessage("file", fileName);
144 private static void checkResourceExistenceFromResourcesMap(String fileName,
145 Set<String> resourcesNames,
146 Collection<?> valuesToSearchIn,
147 GlobalValidationContext globalContext) {
149 mdcDataDebugMessage.debugEntryMessage("file", fileName);
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,
165 private static void extractResourceProperty(String fileName, Set<String> resourcesNames,
166 GlobalValidationContext globalContext,
168 Resource resource = value;
169 Collection<Object> resourcePropertiesValues =
170 resource.getProperties() == null ? null : resource.getProperties()
172 if (CollectionUtils.isNotEmpty(resourcePropertiesValues)) {
173 for (Object propertyValue : resourcePropertiesValues) {
174 handleReferencedResources(fileName, propertyValue, resourcesNames,
180 private static void handleReferencedResources(String fileName, Object valueToSearchReferencesIn,
181 Set<String> resourcesNames,
182 GlobalValidationContext globalContext) {
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,
196 mdcDataDebugMessage.debugExitMessage("file", fileName);
199 private static void checkIfResourceReferenceExist(String fileName,
200 Set<String> referencedResourcesNames,
201 Set<String> referencedResources,
202 GlobalValidationContext globalContext) {
205 mdcDataDebugMessage.debugEntryMessage("file", fileName);
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);
218 mdcDataDebugMessage.debugExitMessage("file", fileName);
223 private static void validateGetParamPointToParameter(String fileName,
224 HeatOrchestrationTemplate
225 heatOrchestrationTemplate,
226 GlobalValidationContext globalContext) {
228 mdcDataDebugMessage.debugEntryMessage("file", fileName);
230 Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
231 : heatOrchestrationTemplate.getParameters().keySet();
232 Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
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,
246 validateReferenceParams(fileName, resourceEntry.getKey(), parametersNames,
247 referencedParameterNames, globalContext);
254 mdcDataDebugMessage.debugExitMessage("file", fileName);
257 private static void validateReferenceParams(String fileName, String resourceName,
258 Set<String> parametersNamesFromFile,
259 Set<String> referencedParametersNames,
260 GlobalValidationContext globalContext) {
263 mdcDataDebugMessage.debugEntryMessage("file", fileName);
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);
277 mdcDataDebugMessage.debugExitMessage("file", fileName);
280 private static boolean isHeatPseudoParameter(String parameterName) {
281 return HeatPseudoParameters.getPseudoParameterNames().contains(parameterName);
286 private static void validateGetAttr(String fileName,
287 HeatOrchestrationTemplate heatOrchestrationTemplate,
288 GlobalValidationContext globalContext) {
290 mdcDataDebugMessage.debugEntryMessage("file", fileName);
292 Map<String, Output> outputMap;
293 outputMap = heatOrchestrationTemplate.getOutputs();
295 if (MapUtils.isNotEmpty(outputMap)) {
296 loopOverOutputMapAndValidateGetAttrFromNested(fileName, outputMap,
297 heatOrchestrationTemplate, globalContext);
300 mdcDataDebugMessage.debugExitMessage("file", fileName);
303 private static void loopOverOutputMapAndValidateGetAttrFromNested(String fileName,
304 Map<String, Output> outputMap,
305 HeatOrchestrationTemplate
306 heatOrchestrationTemplate,
307 GlobalValidationContext
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)) {
322 String attName = getAttrValue.get(1);
323 String resourceType =
324 getResourceTypeFromResourcesMap(resourceName, heatOrchestrationTemplate);
326 if (Objects.nonNull(resourceType)
327 && HeatValidationService.isNestedResource(resourceType)) {
328 handleGetAttrNestedResource(fileName, globalContext, resourceName, attName,
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;
343 Optional<InputStream> fileContent = globalContext.getFileContent(resourceType);
344 if (fileContent.isPresent()) {
345 nestedHeatOrchestrationTemplate =
346 new YamlUtil().yamlToObject(fileContent.get(), HeatOrchestrationTemplate.class);
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");
355 } catch (Exception exception) {
356 logger.debug("",exception);
359 nestedOutputMap = nestedHeatOrchestrationTemplate.getOutputs();
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);
371 private static String getResourceTypeFromResourcesMap(String resourceName,
372 HeatOrchestrationTemplate
373 heatOrchestrationTemplate) {
374 return heatOrchestrationTemplate.getResources().get(resourceName).getType();
377 /* validation 17 + */
378 private static void validateEnvFile(String fileName, String envFileName,
379 HeatOrchestrationTemplate heatOrchestrationTemplate,
380 GlobalValidationContext globalContext) {
383 mdcDataDebugMessage.debugEntryMessage("file", fileName);
385 Environment envContent;
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);
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);
402 mdcDataDebugMessage.debugExitMessage("file", fileName);
406 private static void validateEnvContentIsSubSetOfHeatParameters(String envFile,
407 Environment envContent,
408 GlobalValidationContext
410 HeatOrchestrationTemplate
411 heatOrchestrationTemplate) {
413 mdcDataDebugMessage.debugEntryMessage("file", envFile);
415 Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
416 : heatOrchestrationTemplate.getParameters().keySet();
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);
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);
442 mdcDataDebugMessage.debugExitMessage("file", envFile);
446 private static void validateParameterDefaultTypeAlignWithType(String fileName,
447 HeatOrchestrationTemplate
448 heatOrchestrationTemplate,
449 GlobalValidationContext
452 mdcDataDebugMessage.debugEntryMessage("file", fileName);
454 Map<String, Parameter> parametersMap = heatOrchestrationTemplate.getParameters() == null ? null
455 : heatOrchestrationTemplate.getParameters();
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);
478 mdcDataDebugMessage.debugExitMessage("file", fileName);
482 private static void validateEnvParametersMatchDefinedHeatParameterTypes(String envFile,
483 Environment envContent,
484 GlobalValidationContext globalContext,
485 HeatOrchestrationTemplate heatOrchestrationTemplate) {
488 mdcDataDebugMessage.debugEntryMessage("file", envFile);
490 Map<String, Parameter> heatParameters = heatOrchestrationTemplate.getParameters();
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);
513 mdcDataDebugMessage.debugExitMessage("file", envFile);
518 public void validate(GlobalValidationContext globalContext) {
519 mdcDataDebugMessage.debugEntryMessage(null, null);
520 ManifestContent manifestContent;
522 manifestContent = ValidationUtil.validateManifest(globalContext);
523 } catch (Exception exception) {
524 logger.debug("",exception);
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<>();
535 baseFileName = CollectionUtils.isEmpty(baseFiles) ? null : baseFiles.iterator().next();
536 securityGroupsNamesFromBaseFileOutputs = baseFileName == null ? null
537 : checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot(baseFileName,
541 globalContext.getFiles().stream()
542 .filter(fileName -> FileData.isHeatFile(fileTypeMap.get(fileName))).forEach(
543 fileName -> validate(fileName, fileEnvMap.get(fileName) == null ? null : fileEnvMap.get(
545 baseFileName == null ? null : baseFileName, artifacts,
546 securityGroupsNamesFromBaseFileOutputs, globalContext));
549 Set<String> manifestArtifacts = ManifestUtil.getArtifacts(manifestContent);
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));
561 mdcDataDebugMessage.debugExitMessage(null, null);
565 private boolean isManifestArtifact(Set<String> manifestArtifacts, String fileName) {
566 return manifestArtifacts.contains(fileName);
569 private boolean isNotArtifact(Set<String> artifacts, String fileName) {
570 return !artifacts.contains(fileName);
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);
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);
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,
600 if (envFileName != null) {
601 validateEnvFile(fileName, envFileName, heatOrchestrationTemplate, globalContext);
606 private void validateResourceDependsOn(String fileName,
607 HeatOrchestrationTemplate heatOrchestrationTemplate,
608 GlobalValidationContext globalContext) {
609 Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
610 if(MapUtils.isEmpty(resourcesMap)){
614 Set<String> resourcesNames = resourcesMap.keySet();
616 resourcesMap.entrySet().stream()
617 .forEach(entry -> checkResourceDependsOn(fileName, entry.getValue(),
618 resourcesNames, globalContext));
621 @SuppressWarnings("unchecked")
622 private static void checkResourceDependsOn(String fileName, Resource resource,
623 Set<String> resourcesNames,
624 GlobalValidationContext globalContext) {
627 mdcDataDebugMessage.debugEntryMessage("file", fileName);
629 Object dependencies = resource.getDepends_on();
630 if (dependencies instanceof Collection) {
631 ((Collection<String>) dependencies)
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);
650 mdcDataDebugMessage.debugExitMessage("file", fileName);
654 private void validateHeatBaseStructure(String fileName,
655 HeatOrchestrationTemplate heatOrchestrationTemplate,
656 GlobalValidationContext globalContext) {
659 mdcDataDebugMessage.debugEntryMessage("file", fileName);
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);
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);
677 mdcDataDebugMessage.debugExitMessage("file", fileName);
680 private Set<String> checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot(
681 String baseFileName, GlobalValidationContext globalContext) {
682 Set<String> securityGroupsNamesFromOutputsMap = new HashSet<>();
683 HeatOrchestrationTemplate heatOrchestrationTemplate =
684 ValidationUtil.checkHeatOrchestrationPreCondition(baseFileName, globalContext);
686 if (heatOrchestrationTemplate != null) {
687 Map<String, Resource> resourceMap = heatOrchestrationTemplate.getResources();
688 if (!isPortResourceExistInBaseFile(resourceMap)) {
689 getSecurityGroupsReferencedResourcesFromOutputs(securityGroupsNamesFromOutputsMap,
690 heatOrchestrationTemplate.getOutputs(), resourceMap);
693 return securityGroupsNamesFromOutputsMap;
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());
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())) {