summaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-02-19 12:35:04 +0200
committerMichael Lando <ml636r@att.com>2017-02-19 12:35:04 +0200
commitf5f13c4f6b6fe3b4d98e349dfd7db59339803436 (patch)
tree72caffc93fab394ffa3b761505775331f1c559b9 /openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main
parent451a3400b76511393c62a444f588a4ed15f4a549 (diff)
push addional code
Change-Id: Ia427bb3460cda3a896f8faced2de69eaf3807b74 Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main')
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/HeatValidationService.java323
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/ResourceValidationHeatValidator.java617
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/EcompGuideLineValidator.java784
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/HeatValidator.java469
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/ManifestValidator.java153
-rw-r--r--openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/YamlValidator.java97
6 files changed, 2443 insertions, 0 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/HeatValidationService.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/HeatValidationService.java
new file mode 100644
index 0000000000..920724ed3b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/HeatValidationService.java
@@ -0,0 +1,323 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.util;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.core.utilities.yaml.YamlUtil;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.heat.datatypes.model.Environment;
+import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
+import org.openecomp.sdc.heat.datatypes.model.Output;
+import org.openecomp.sdc.heat.datatypes.model.Resource;
+import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
+import org.openecomp.sdc.heat.services.HeatStructureUtil;
+import org.openecomp.sdc.validation.impl.validators.HeatValidator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+public class HeatValidationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(HeatValidator.class);
+
+ /**
+ * Check artifacts existence.
+ *
+ * @param fileName the file name
+ * @param artifactsNames the artifacts names
+ * @param globalContext the global context
+ */
+ public static void checkArtifactsExistence(String fileName, Set<String> artifactsNames,
+ GlobalValidationContext globalContext) {
+ artifactsNames
+ .stream()
+ .filter(artifactName -> !globalContext.getFileContextMap().containsKey(artifactName))
+ .forEach(artifactName -> {
+ globalContext
+ .addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_ARTIFACT.getErrorMessage(),
+ artifactName));
+ });
+ }
+
+
+ /**
+ * Check resource existence from resources map.
+ *
+ * @param fileName the file name
+ * @param resourcesNames the resources names
+ * @param valuesToSearchIn the values to search in
+ * @param globalContext the global context
+ */
+ public static void checkResourceExistenceFromResourcesMap(String fileName,
+ Set<String> resourcesNames,
+ Collection<?> valuesToSearchIn,
+ GlobalValidationContext globalContext) {
+ if (CollectionUtils.isNotEmpty(valuesToSearchIn)) {
+ for (Object value : valuesToSearchIn) {
+ if (value instanceof Resource) {
+ Resource resource = (Resource) value;
+ //checkResourceDependsOn(fileName,resource,resourcesNames,globalContext);
+
+ Collection<Object> resourcePropertiesValues =
+ resource.getProperties() == null ? null : resource.getProperties().values();
+ if (CollectionUtils.isNotEmpty(resourcePropertiesValues)) {
+ for (Object propertyValue : resourcePropertiesValues) {
+ handleReferencedResources(fileName, propertyValue, resourcesNames, globalContext);
+ }
+ }
+ } else if (value instanceof Output) {
+ Output output = (Output) value;
+ Object outputsValue = output.getValue();
+ handleReferencedResources(fileName, outputsValue, resourcesNames, globalContext);
+ }
+ }
+ }
+ }
+
+
+ private static void handleReferencedResources(String fileName, Object valueToSearchReferencesIn,
+ Set<String> resourcesNames,
+ GlobalValidationContext globalContext) {
+ Set<String> referencedResourcesNames = HeatStructureUtil
+ .getReferencedValuesByFunctionName(fileName,
+ ResourceReferenceFunctions.GET_RESOURCE.getFunction(), valueToSearchReferencesIn,
+ globalContext);
+ if (CollectionUtils.isNotEmpty(referencedResourcesNames)) {
+ HeatValidationService
+ .checkIfResourceReferenceExist(fileName, resourcesNames, referencedResourcesNames,
+ globalContext);
+ }
+ }
+
+
+ private static void checkIfResourceReferenceExist(String fileName,
+ Set<String> referencedResourcesNames,
+ Set<String> referencedResources,
+ GlobalValidationContext globalContext) {
+ referencedResources.stream()
+ .filter(referencedResource -> !referencedResourcesNames.contains(referencedResource))
+ .forEach(referencedResource -> {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.REFERENCED_RESOURCE_NOT_FOUND.getErrorMessage(),
+ referencedResource));
+ });
+ }
+
+ /**
+ * Draw files loop string.
+ *
+ * @param filesInPath the files in path
+ * @return the string
+ */
+ public static String drawFilesLoop(List<String> filesInPath) {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("[");
+ int pathSize = filesInPath.size();
+
+ for (int i = 0; i < pathSize; i++) {
+ stringBuilder.append(filesInPath.get(i));
+ if (i != pathSize - 1) {
+ stringBuilder.append(" -- ");
+ }
+ }
+ if (!filesInPath.get(0).equals(filesInPath.get(pathSize - 1))) {
+ stringBuilder.append(" -- ");
+ stringBuilder.append(filesInPath.get(0));
+ }
+ stringBuilder.append("]");
+
+ return stringBuilder.toString();
+ }
+
+
+ /**
+ * Check nested parameters.
+ *
+ * @param callingNestedFileName the calling nested file name
+ * @param nestedFileName the nested file name
+ * @param resourceName the resource name
+ * @param globalContext the global context
+ * @param resourceFileProperties the resource file properties
+ */
+ public static void checkNestedParameters(String callingNestedFileName, String nestedFileName,
+ String resourceName,
+ GlobalValidationContext globalContext,
+ Set<String> resourceFileProperties) {
+ HeatOrchestrationTemplate heatOrchestrationTemplate;
+ try {
+ heatOrchestrationTemplate = new YamlUtil()
+ .yamlToObject(globalContext.getFileContent(nestedFileName),
+ HeatOrchestrationTemplate.class);
+ } catch (Exception e0) {
+ return;
+ }
+ Set<String> nestedParametersNames = heatOrchestrationTemplate.getParameters() == null ? null
+ : heatOrchestrationTemplate.getParameters().keySet();
+
+ if (CollectionUtils.isNotEmpty(nestedParametersNames)) {
+ resourceFileProperties
+ .stream()
+ .filter(propertyName -> !nestedParametersNames.contains(propertyName))
+ .forEach(propertyName -> globalContext
+ .addMessage(callingNestedFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_PARAMETER_IN_NESTED.getErrorMessage(),
+ nestedFileName, resourceName, propertyName)));
+ }
+ }
+
+
+ /**
+ * Is nested loop exist in file boolean.
+ *
+ * @param callingFileName the calling file name
+ * @param nestedFileName the nested file name
+ * @param filesInLoop the files in loop
+ * @param globalContext the global context
+ * @return the boolean
+ */
+ public static boolean isNestedLoopExistInFile(String callingFileName, String nestedFileName,
+ List<String> filesInLoop,
+ GlobalValidationContext globalContext) {
+ HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
+ try {
+ nestedHeatOrchestrationTemplate = new YamlUtil()
+ .yamlToObject(globalContext.getFileContent(nestedFileName),
+ HeatOrchestrationTemplate.class);
+ } catch (Exception e0) {
+ logger.warn("HEAT Validator will not be executed on file " + nestedFileName
+ + " due to illegal HEAT format");
+ return false;
+ }
+ filesInLoop.add(nestedFileName);
+ Collection<Resource> nestedResources =
+ nestedHeatOrchestrationTemplate.getResources() == null ? null
+ : nestedHeatOrchestrationTemplate.getResources().values();
+ if (CollectionUtils.isNotEmpty(nestedResources)) {
+ for (Resource resource : nestedResources) {
+ String resourceType = resource.getType();
+
+ if (Objects.nonNull(resourceType) && isNestedResource(resourceType)) {
+ return resourceType.equals(callingFileName) || !filesInLoop.contains(resourceType)
+ && isNestedLoopExistInFile(callingFileName, resourceType, filesInLoop, globalContext);
+ }
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Loop over output map and validate get attr from nested.
+ *
+ * @param fileName the file name
+ * @param outputMap the output map
+ * @param heatOrchestrationTemplate the heat orchestration template
+ * @param globalContext the global context
+ */
+ @SuppressWarnings("unchecked")
+ public static void loopOverOutputMapAndValidateGetAttrFromNested(String fileName,
+ Map<String, Output> outputMap,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ for (Output output : outputMap.values()) {
+ Object outputValue = output.getValue();
+ if (outputValue != null && outputValue instanceof Map) {
+ Map<String, Object> outputValueMap = (Map<String, Object>) outputValue;
+ List<String> getAttrValue =
+ (List<String>) outputValueMap.get(ResourceReferenceFunctions.GET_ATTR.getFunction());
+ if (!CollectionUtils.isEmpty(getAttrValue)) {
+ String resourceName = getAttrValue.get(0);
+ String propertyName = getAttrValue.get(1);
+ String resourceType =
+ getResourceTypeFromResourcesMap(resourceName, heatOrchestrationTemplate);
+
+ if (Objects.nonNull(resourceType)
+ && HeatValidationService.isNestedResource(resourceType)) {
+ Map<String, Output> nestedOutputMap;
+ HeatOrchestrationTemplate nestedHeatOrchestrationTemplate;
+ try {
+ nestedHeatOrchestrationTemplate = new YamlUtil()
+ .yamlToObject(globalContext.getFileContent(resourceType),
+ HeatOrchestrationTemplate.class);
+ } catch (Exception e0) {
+ return;
+ }
+ nestedOutputMap = nestedHeatOrchestrationTemplate.getOutputs();
+
+ if (MapUtils.isEmpty(nestedOutputMap) || !nestedOutputMap.containsKey(propertyName)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.GET_ATTR_NOT_FOUND.getErrorMessage(),
+ propertyName, resourceName));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ public static boolean isNestedResource(String resourceType) {
+ return resourceType.contains(".yaml") || resourceType.contains(".yml");
+ }
+
+
+ private static String getResourceTypeFromResourcesMap(String resourceName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate) {
+ return heatOrchestrationTemplate.getResources().get(resourceName).getType();
+ }
+
+ /**
+ * Validate env content environment.
+ *
+ * @param fileName the file name
+ * @param envFileName the env file name
+ * @param globalContext the global context
+ * @return the environment
+ */
+ public static Environment validateEnvContent(String fileName, String envFileName,
+ GlobalValidationContext globalContext) {
+ Environment envContent = null;
+ try {
+ envContent =
+ new YamlUtil().yamlToObject(globalContext.getFileContent(envFileName), Environment.class);
+ } catch (Exception e0) {
+ return null;
+ }
+ return envContent;
+ }
+
+
+ public static String getResourceGroupResourceName(String resourceCallingToResourceGroup) {
+ return "OS::Heat::ResourceGroup in " + resourceCallingToResourceGroup;
+ }
+
+}
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/ResourceValidationHeatValidator.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/ResourceValidationHeatValidator.java
new file mode 100644
index 0000000000..3457bed1e9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/util/ResourceValidationHeatValidator.java
@@ -0,0 +1,617 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.util;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
+import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
+import org.openecomp.sdc.heat.datatypes.model.Output;
+import org.openecomp.sdc.heat.datatypes.model.PolicyTypes;
+import org.openecomp.sdc.heat.datatypes.model.PropertiesMapKeyTypes;
+import org.openecomp.sdc.heat.datatypes.model.Resource;
+import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
+import org.openecomp.sdc.heat.datatypes.model.ResourceTypeToMessageString;
+import org.openecomp.sdc.heat.services.HeatStructureUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+
+public class ResourceValidationHeatValidator {
+
+ /**
+ * Validate resource type.
+ *
+ * @param fileName the file name
+ * @param baseFileName the base file name
+ * @param securityGroupsNamesFromBaseFileOutputs the security groups names from base file outputs
+ * @param heatOrchestrationTemplate the heat orchestration template
+ * @param globalContext the global context
+ */
+ public static void validateResourceType(String fileName, String baseFileName,
+ Set<String> securityGroupsNamesFromBaseFileOutputs,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Map<String, Resource> resourceMap =
+ heatOrchestrationTemplate.getResources() == null ? new HashMap<>()
+ : heatOrchestrationTemplate.getResources();
+ Map<String, Integer> numberOfVisitsInPort = new HashMap<>();
+ Set<String> resourcesNames = resourceMap.keySet();
+ Set<String> sharedResourcesFromOutputMap =
+ getSharedResourcesNamesFromOutputs(fileName, heatOrchestrationTemplate.getOutputs(),
+ globalContext);
+ boolean isBaseFile = baseFileName != null && fileName.equals(baseFileName);
+
+ Map<HeatResourcesTypes, List<String>> resourceTypeToNamesListMap = HeatResourcesTypes
+ .getListForResourceType(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE,
+ HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE,
+ HeatResourcesTypes.CONTRAIL_NETWORK_RULE_RESOURCE_TYPE);
+
+ initResourceTypeListWithItsResourcesNames(fileName, resourceTypeToNamesListMap, resourceMap,
+ sharedResourcesFromOutputMap, globalContext);
+ initVisitedPortsMap(fileName, resourceMap, numberOfVisitsInPort, globalContext);
+
+
+ for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
+ String resourceType = resourceEntry.getValue().getType();
+ validateSecurityGroupsFromBaseOutput(fileName, resourceEntry, isBaseFile,
+ securityGroupsNamesFromBaseFileOutputs, globalContext);
+ checkResourceDependsOn(fileName, resourceEntry.getValue(), resourcesNames, globalContext);
+
+ if (Objects.isNull(resourceType)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_RESOURCE_TYPE.getErrorMessage(), "null",
+ resourceEntry.getKey()));
+ } else {
+ HeatResourcesTypes heatResourceType = HeatResourcesTypes.findByHeatResource(resourceType);
+
+ if (heatResourceType != null) {
+ switch (heatResourceType) {
+ case NOVA_SERVER_RESOURCE_TYPE:
+ validateNovaServerResourceType(fileName, resourceEntry, numberOfVisitsInPort,
+ resourceTypeToNamesListMap
+ .get(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE),
+ heatOrchestrationTemplate, globalContext);
+ break;
+
+ case NOVA_SERVER_GROUP_RESOURCE_TYPE:
+ validateNovaServerGroupPolicy(fileName, resourceEntry, globalContext);
+ break;
+
+ case RESOURCE_GROUP_RESOURCE_TYPE:
+ validateResourceGroupType(fileName, resourceEntry, globalContext);
+ break;
+
+ case NEUTRON_PORT_RESOURCE_TYPE:
+ validateNeutronPortType(fileName, resourceEntry, resourceTypeToNamesListMap
+ .get(HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE), globalContext);
+ break;
+
+ case CONTRAIL_NETWORK_ATTACH_RULE_RESOURCE_TYPE:
+ validateContrailAttachPolicyType(resourceEntry, resourceTypeToNamesListMap
+ .get(HeatResourcesTypes.CONTRAIL_NETWORK_RULE_RESOURCE_TYPE));
+ break;
+ default:
+ }
+ } else {
+ if (HeatValidationService.isNestedResource(resourceType)) {
+ handleNestedResourceType(fileName, resourceEntry.getKey(), resourceEntry.getValue(),
+ globalContext);
+ }
+ }
+ }
+ }
+
+ checkForEmptyResourceNamesInMap(fileName,
+ CollectionUtils.isEmpty(securityGroupsNamesFromBaseFileOutputs), resourceTypeToNamesListMap,
+ globalContext);
+ handleOrphanPorts(fileName, numberOfVisitsInPort, globalContext);
+ }
+
+
+ private static void validateNovaServerResourceType(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ Map<String, Integer> numberOfVisitsInPort,
+ List<String> serverGroupResourcesNames,
+ HeatOrchestrationTemplate
+ heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ validateAssignedValueForImageOrFlavorFromNova(fileName, resourceEntry, globalContext);
+ validateNovaServerPortBinding(fileName, resourceEntry.getValue(), numberOfVisitsInPort,
+ globalContext);
+ validateAllServerGroupsPointedByServerExistAndDefined(fileName, resourceEntry,
+ serverGroupResourcesNames, heatOrchestrationTemplate, globalContext);
+
+ }
+
+
+ private static void handleNestedResourceType(String fileName, String resourceName,
+ Resource resource,
+ GlobalValidationContext globalContext) {
+ validateAllPropertiesMatchNestedParameters(fileName, resourceName, resource, globalContext);
+ validateLoopsOfNestingFromFile(fileName, resource.getType(), globalContext);
+ }
+
+
+ private static void validateResourceGroupType(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ Resource resourceDef = HeatStructureUtil
+ .getResourceDef(fileName, resourceEntry.getKey(), resourceEntry.getValue(), globalContext);
+ // validateResourceGroupTypeIsSupported(fileName, resourceEntry.getKey(),resourceDef.getType(),
+ // globalContext);
+ if (resourceDef != null) {
+ if (Objects.nonNull(resourceDef.getType())
+ && HeatValidationService.isNestedResource(resourceDef.getType())) {
+ handleNestedResourceType(fileName, resourceDef.getType(), resourceDef, globalContext);
+ }
+ }
+ }
+
+
+ private static void validateAllPropertiesMatchNestedParameters(String fileName,
+ String resourceName,
+ Resource resource,
+ GlobalValidationContext
+ globalContext) {
+
+ String resourceType = resource.getType();
+ if (globalContext.getFileContextMap().containsKey(resourceType)) {
+ Set<String> propertiesNames =
+ resource.getProperties() == null ? null : resource.getProperties().keySet();
+ if (CollectionUtils.isNotEmpty(propertiesNames)) {
+ HeatValidationService
+ .checkNestedParameters(fileName, resourceType, resourceName, globalContext,
+ propertiesNames);
+ }
+ } else {
+ globalContext.addMessage(resourceType, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_NESTED_FILE.getErrorMessage(), resourceType));
+ }
+ }
+
+
+ private static void validateAssignedValueForImageOrFlavorFromNova(String fileName,
+ Map.Entry<String, Resource>
+ resourceEntry,
+ GlobalValidationContext
+ globalContext) {
+
+ Resource resource = resourceEntry.getValue();
+ Map<String, Object> propertiesMap = resource.getProperties();
+ if (propertiesMap.get(PropertiesMapKeyTypes.IMAGE.getKeyMap()) == null
+ && propertiesMap.get(PropertiesMapKeyTypes.FLAVOR.getKeyMap()) == null) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_IMAGE_AND_FLAVOR.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+
+
+ private static void validateLoopsOfNestingFromFile(String fileName, String resourceType,
+ GlobalValidationContext globalContext) {
+ List<String> filesInLoop = new ArrayList<>(Collections.singletonList(fileName));
+ if (HeatValidationService
+ .isNestedLoopExistInFile(fileName, resourceType, filesInLoop, globalContext)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.NESTED_LOOP.getErrorMessage(),
+ HeatValidationService.drawFilesLoop(filesInLoop)));
+ }
+ }
+
+
+ /* validation 22*/
+ @SuppressWarnings("unchecked")
+ private static void validateNovaServerPortBinding(String fileName, Resource resource,
+ Map<String, Integer> numberOfVisitsInPort,
+ GlobalValidationContext globalContext) {
+
+ Map<String, Object> propertiesMap = resource.getProperties();
+ List<Object> networksList =
+ (List<Object>) propertiesMap.get(PropertiesMapKeyTypes.NETWORKS.getKeyMap());
+
+ if (CollectionUtils.isNotEmpty(networksList)) {
+ networksList
+ .stream()
+ .filter(networkObject -> networkObject instanceof Map)
+ .forEach(networkObject -> {
+ Map<String, Object> portValueMap =
+ (Map<String, Object>) ((Map) networkObject).get("port");
+ if (MapUtils.isNotEmpty(portValueMap)) {
+ checkPortBindingFromMap(fileName, portValueMap, numberOfVisitsInPort, globalContext);
+ }
+ });
+ }
+ }
+
+ /* validation 23*/
+ @SuppressWarnings("unchecked")
+ private static void validateAllServerGroupsPointedByServerExistAndDefined(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ List<String> serverGroupNamesList,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
+
+ Map<String, Object> resourceProperties = resourceEntry.getValue().getProperties();
+ Map<String, Object> schedulerHintsMap = resourceProperties == null ? null
+ : (Map<String, Object>) resourceProperties
+ .get(ResourceReferenceFunctions.SCHEDULER_HINTS.getFunction());
+
+ if (MapUtils.isNotEmpty(schedulerHintsMap)) {
+ for (Object serverGroupMap : schedulerHintsMap.values()) {
+ Map<String, Object> currentServerMap = (Map<String, Object>) serverGroupMap;
+ String serverResourceName = currentServerMap == null ? null
+ : (String) currentServerMap.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
+ Resource serverResource = serverResourceName == null || resourcesMap == null ? null
+ : resourcesMap.get(serverResourceName);
+ if (serverResource != null && !serverResource.getType()
+ .equals(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE.getHeatResource())) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.SERVER_NOT_DEFINED_FROM_NOVA.getErrorMessage(),
+ serverResourceName, resourceEntry.getKey()));
+ } else {
+ serverGroupNamesList.remove(serverResourceName);
+ }
+ }
+ }
+ }
+
+
+ /* validation 24*/
+ @SuppressWarnings("unchecked")
+ private static void validateNovaServerGroupPolicy(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+
+ Resource resource = resourceEntry.getValue();
+ List<String> policiesList = resource.getProperties() == null ? null
+ : (List<String>) resource.getProperties().get("policies");
+
+ if (CollectionUtils.isNotEmpty(policiesList)) {
+ if (policiesList.size() == 1) {
+ String policy = policiesList.get(0);
+ if (!PolicyTypes.isGivenPolicyValid(policy)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_POLICY_IN_SERVER_GROUP.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_POLICY_IN_SERVER_GROUP.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+ }
+
+
+ private static void validateNeutronPortType(String filename,
+ Map.Entry<String, Resource> resourceEntry,
+ List<String> securityGroupResourceNameList,
+ GlobalValidationContext globalContext) {
+ validateAllSecurityGroupsAreUsed(filename, resourceEntry, securityGroupResourceNameList,
+ globalContext);
+
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static void validateAllSecurityGroupsAreUsed(String filename,
+ Map.Entry<String, Resource> resourceEntry,
+ List<String> securityGroupResourceNameList,
+ GlobalValidationContext globalContext) {
+ Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
+
+ if (MapUtils.isEmpty(propertiesMap)) {
+ return;
+ }
+
+ Object securityGroupsValue = propertiesMap.get("security_groups");
+
+ if (Objects.isNull(securityGroupsValue)) {
+ return;
+ }
+
+ if (securityGroupsValue instanceof List) {
+ List<Object> securityGroupsListFromCurrResource =
+ (List<Object>) propertiesMap.get("security_groups");
+ for (Object securityGroup : securityGroupsListFromCurrResource) {
+ removeSecurityGroupNamesFromListByGivenFunction(filename,
+ ResourceReferenceFunctions.GET_RESOURCE.getFunction(), securityGroup,
+ securityGroupResourceNameList, globalContext);
+ }
+ }
+ }
+
+
+ private static void validateSecurityGroupsFromBaseOutput(String filename,
+ Map.Entry<String, Resource> resourceEntry,
+ boolean isBaseFile,
+ Set<String> securityGroupNamesFromBaseOutput,
+ GlobalValidationContext globalContext) {
+ if (!isBaseFile && CollectionUtils.isNotEmpty(securityGroupNamesFromBaseOutput)) {
+ Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
+
+ if (MapUtils.isEmpty(propertiesMap)) {
+ return;
+ }
+
+ for (Map.Entry<String, Object> propertyEntry : propertiesMap.entrySet()) {
+ removeSecurityGroupNamesFromListByGivenFunction(filename,
+ ResourceReferenceFunctions.GET_PARAM.getFunction(), propertyEntry.getValue(),
+ securityGroupNamesFromBaseOutput, globalContext);
+ }
+ }
+ }
+
+
+ private static void removeSecurityGroupNamesFromListByGivenFunction(String filename,
+ String functionName,
+ Object securityGroup,
+ Collection<String> securityGroupResourceNameList,
+ GlobalValidationContext globalContext) {
+ Set<String> securityGroupsNamesFromFunction = HeatStructureUtil
+ .getReferencedValuesByFunctionName(filename, functionName, securityGroup, globalContext);
+ securityGroupsNamesFromFunction.forEach(securityGroupResourceNameList::remove);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private static void validateContrailAttachPolicyType(Map.Entry<String, Resource> resourceEntry,
+ List<String> networkPolicyResourceNames) {
+ Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
+
+ if (MapUtils.isNotEmpty(propertiesMap)) {
+ Map<String, Object> policyMap = (Map<String, Object>) propertiesMap.get("policy");
+ if (MapUtils.isNotEmpty(policyMap)) {
+ List<Object> securityGroupList =
+ (List<Object>) policyMap.get(ResourceReferenceFunctions.GET_ATTR.getFunction());
+ //noinspection SuspiciousMethodCalls
+ if (CollectionUtils.isNotEmpty(securityGroupList)) {
+ //noinspection SuspiciousMethodCalls
+ networkPolicyResourceNames.remove(securityGroupList.get(0));
+ }
+ }
+ }
+ }
+
+
+ private static void getResourceNamesListFromSpecificResource(String filename,
+ List<String> resourcesNames,
+ HeatResourcesTypes heatResourcesType,
+ Map<String, Resource> resourcesMap,
+ Set<String> sharedResourcesFromOutputMap,
+ GlobalValidationContext globalContext) {
+
+ for (Map.Entry<String, Resource> resourceEntry : resourcesMap.entrySet()) {
+ String resourceType = resourceEntry.getValue().getType();
+ if (Objects.isNull(resourceType)) {
+ globalContext.addMessage(filename, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_RESOURCE_TYPE.getErrorMessage(), null,
+ resourceEntry.getKey()));
+ } else {
+ if (resourceType.equals(heatResourcesType.getHeatResource())
+ && !isSharedResource(resourceEntry.getKey(), sharedResourcesFromOutputMap)) {
+ resourcesNames.add(resourceEntry.getKey());
+ }
+ }
+ }
+ }
+
+
+ private static boolean isSharedResource(String resourceName,
+ Set<String> sharedResourcesFromOutputMap) {
+ return !CollectionUtils.isEmpty(sharedResourcesFromOutputMap)
+ && sharedResourcesFromOutputMap.contains(resourceName);
+ }
+
+ /**
+ * Handle not empty resource names list.
+ *
+ * @param fileName the file name
+ * @param resourcesNameList the resources name list
+ * @param securityOrServerGroup the security or server group
+ * @param globalContext the global context
+ */
+ public static void handleNotEmptyResourceNamesList(String fileName,
+ Collection<String> resourcesNameList,
+ String securityOrServerGroup,
+ GlobalValidationContext globalContext) {
+ if (CollectionUtils.isNotEmpty(resourcesNameList)) {
+ resourcesNameList.forEach(name ->
+ globalContext
+ .addMessage(
+ fileName,
+ ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.SERVER_OR_SECURITY_GROUP_NOT_IN_USE.getErrorMessage(),
+ securityOrServerGroup, name)));
+ }
+ }
+
+
+ private static void initVisitedPortsMap(String filename, Map<String, Resource> resourceMap,
+ Map<String, Integer> numberOfVisitsInPort,
+ GlobalValidationContext globalContext) {
+ for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
+ String resourceType = resourceEntry.getValue().getType();
+
+ if (Objects.isNull(resourceType)) {
+ globalContext.addMessage(filename, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_RESOURCE_TYPE.getErrorMessage(), "null",
+ resourceEntry.getKey()));
+ } else {
+ if (resourceType.equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
+ numberOfVisitsInPort.put(resourceEntry.getKey(), 0);
+ }
+ }
+ }
+ }
+
+ private static boolean checkIfPortWasVisited(String resourcePortName,
+ Map<String, Integer> numberOfVisitsInPort) {
+ return numberOfVisitsInPort.containsKey(resourcePortName)
+ && numberOfVisitsInPort.get(resourcePortName) == 1;
+ }
+
+
+ private static void incrementNumberOfVisitsInPort(String resourcePortName,
+ Map<String, Integer> numberOfVisitsInPort) {
+ if (numberOfVisitsInPort.containsKey(resourcePortName)) {
+ numberOfVisitsInPort.put(resourcePortName, numberOfVisitsInPort.get(resourcePortName) + 1);
+ }
+ }
+
+
+ private static void handleOrphanPorts(String fileName, Map<String, Integer> numberOfVisitsInPort,
+ GlobalValidationContext globalContext) {
+ numberOfVisitsInPort
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue() == 0)
+ .forEach(entry ->
+ globalContext
+ .addMessage(
+ fileName,
+ ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.PORT_NO_BIND_TO_ANY_NOVA_SERVER.getErrorMessage(),
+ entry.getKey())));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void checkResourceDependsOn(String fileName, Resource resource,
+ Set<String> resourcesNames,
+ GlobalValidationContext globalContext) {
+ Object dependencies = resource.getDepends_on();
+ if (dependencies instanceof Collection) {
+ ((Collection<String>) dependencies)
+ .stream()
+ .filter(resource_id -> !resourcesNames.contains(resource_id))
+ .forEach(resource_id -> globalContext.addMessage(fileName, ErrorLevel.ERROR,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(),
+ (String) resource_id)));
+ } else if (dependencies instanceof String) {
+ if (!resourcesNames.contains(dependencies)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_RESOURCE_IN_DEPENDS_ON.getErrorMessage(),
+ (String) dependencies));
+ }
+ }
+ }
+
+
+ private static void checkPortBindingFromMap(String fileName, Map<String, Object> portValueMap,
+ Map<String, Integer> numberOfVisitsInPort,
+ GlobalValidationContext globalContext) {
+ String resourcePortName =
+ (String) portValueMap.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
+ if (checkIfPortWasVisited(resourcePortName, numberOfVisitsInPort)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MORE_THAN_ONE_BIND_FROM_NOVA_TO_PORT.getErrorMessage(),
+ (String) portValueMap.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction())));
+ } else {
+ incrementNumberOfVisitsInPort(resourcePortName, numberOfVisitsInPort);
+ }
+ }
+
+
+ private static void initResourceTypeListWithItsResourcesNames(String filename,
+ Map<HeatResourcesTypes, List<String>> resourcesTypesListMap,
+ Map<String, Resource> resourcesMap,
+ Set<String> sharedResourcesFromOutputsMap,
+ GlobalValidationContext globalContext) {
+ for (Map.Entry<HeatResourcesTypes, List<String>> resourcesTypesToListEntry
+ : resourcesTypesListMap.entrySet()) {
+ HeatResourcesTypes currentType = resourcesTypesToListEntry.getKey();
+ List<String> currNamesList = new ArrayList<>();
+ getResourceNamesListFromSpecificResource(filename, currNamesList, currentType, resourcesMap,
+ sharedResourcesFromOutputsMap, globalContext);
+ resourcesTypesListMap.put(currentType, currNamesList);
+ }
+ }
+
+
+ private static void checkForEmptyResourceNamesInMap(String fileName,
+ boolean isBaseFileContainPorts,
+ Map<HeatResourcesTypes, List<String>> resourcesTypesListMap,
+ GlobalValidationContext globalContext) {
+ if (isBaseFileContainPorts) {
+ for (Map.Entry<HeatResourcesTypes, List<String>> resourcesTypesListEntry
+ : resourcesTypesListMap.entrySet()) {
+ handleNotEmptyResourceNamesList(fileName, resourcesTypesListEntry.getValue(),
+ ResourceTypeToMessageString
+ .getTypeForMessageFromResourceType(resourcesTypesListEntry.getKey()),
+ globalContext);
+ }
+ }
+ }
+
+
+ private static Set<String> getSharedResourcesNamesFromOutputs(String filename,
+ Map<String, Output> outputsMap,
+ GlobalValidationContext globalContext) {
+ Set<String> sharedResources = new HashSet<>();
+
+ if (MapUtils.isEmpty(outputsMap)) {
+ return null;
+ }
+
+ for (Map.Entry<String, Output> outputEntry : outputsMap.entrySet()) {
+ Output output = outputEntry.getValue();
+ Object valueObject = output.getValue();
+ if (valueObject instanceof Map) {
+ Map<String, Object> outputValueMap = (Map<String, Object>) valueObject;
+ Object getResourceValue =
+ outputValueMap.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
+ if (Objects.nonNull(getResourceValue)) {
+ if (getResourceValue instanceof String) {
+ String resourceName =
+ (String) outputValueMap.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
+ sharedResources.add(resourceName);
+ } else {
+ globalContext.addMessage(filename, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_GET_RESOURCE_SYNTAX.getErrorMessage(),
+ getResourceValue.toString()));
+ }
+ }
+
+ }
+ }
+
+ return sharedResources;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/EcompGuideLineValidator.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/EcompGuideLineValidator.java
new file mode 100644
index 0000000000..5be56e4b38
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/EcompGuideLineValidator.java
@@ -0,0 +1,784 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.validators;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.core.utilities.CommonMethods;
+import org.openecomp.core.utilities.yaml.YamlUtil;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.interfaces.Validator;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.common.utils.AsdcCommon;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.datatypes.model.heat.ForbiddenHeatResourceTypes;
+import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData;
+import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
+import org.openecomp.sdc.heat.datatypes.model.Environment;
+import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
+import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
+import org.openecomp.sdc.heat.datatypes.model.Resource;
+import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
+import org.openecomp.sdc.heat.services.HeatStructureUtil;
+import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+public class EcompGuideLineValidator extends HeatValidator implements Validator {
+ @Override
+ public void validate(GlobalValidationContext globalContext) {
+
+ ManifestContent manifestContent;
+ try {
+ manifestContent = checkValidationPreCondition(globalContext);
+ } catch (Exception exception) {
+ return;
+ }
+
+ //global validations
+ Set<String> baseFiles = validateManifest(manifestContent, globalContext);
+
+ Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent);
+ Map<String, FileData> fileEnvMap = ManifestUtil.getFileAndItsEnv(manifestContent);
+ globalContext
+ .getFiles()
+ .stream()
+ .filter(fileName -> FileData
+ .isHeatFile(fileTypeMap.get(fileName)))
+ .forEach(fileName -> validate(fileName,
+ fileEnvMap.get(fileName) != null ? fileEnvMap.get(fileName).getFile() : null,
+ fileTypeMap, baseFiles, globalContext));
+ }
+
+ private void validate(String fileName, String envFileName, Map<String, FileData.Type> fileTypeMap,
+ Set<String> baseFiles, GlobalValidationContext globalContext) {
+ HeatOrchestrationTemplate heatOrchestrationTemplate =
+ checkHeatOrchestrationPreCondition(fileName, globalContext);
+ if (heatOrchestrationTemplate == null) {
+ return;
+ }
+
+ validateBaseFile(fileName, baseFiles, heatOrchestrationTemplate, globalContext);
+ validateHeatVolumeFile(fileName, fileTypeMap, heatOrchestrationTemplate, globalContext);
+ validateHeatNamingConvention(fileName, heatOrchestrationTemplate, globalContext);
+ validateHeatNovaResource(fileName, envFileName, heatOrchestrationTemplate, globalContext);
+ validateResourceTypeIsForbidden(fileName, heatOrchestrationTemplate, globalContext);
+ validateFixedIpsNamingConvention(fileName, heatOrchestrationTemplate, globalContext);
+ }
+
+ private void validateHeatNovaResource(String fileName, String envFileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Map<String, String> uniqueResourcePortNetworkRole = new HashMap<>();
+ //if no resources exist return
+ if (heatOrchestrationTemplate.getResources() == null
+ || heatOrchestrationTemplate.getResources().size() == 0) {
+ return;
+ }
+
+ heatOrchestrationTemplate
+ .getResources()
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue().getType()
+ .equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource()))
+ .forEach(entry -> validateNovaServerResourceType(entry.getKey(), fileName, envFileName,
+ entry, uniqueResourcePortNetworkRole, heatOrchestrationTemplate, globalContext));
+ }
+
+ private void validateNovaServerResourceType(String resourceId, String fileName,
+ String envFileName,
+ Map.Entry<String, Resource> resourceEntry,
+ Map<String, String> uniqueResourcePortNetworkRole,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalValidationContext) {
+ validateNovaServerResourceMetaData(fileName, resourceId,
+ heatOrchestrationTemplate.getResources().get(resourceId), globalValidationContext);
+ validateNovaServerResourceNetworkUniqueRole(fileName, resourceId, heatOrchestrationTemplate,
+ globalValidationContext);
+ validateNovaServerNamingConvention(fileName, envFileName, resourceEntry,
+ globalValidationContext);
+ validateNovaServerAvailabilityZoneName(fileName, resourceEntry, globalValidationContext);
+ validateImageAndFlavorFromNovaServer(fileName, resourceEntry, globalValidationContext);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void validateNovaServerResourceMetaData(String fileName, String resourceId,
+ Resource resource,
+ GlobalValidationContext globalValidationContext) {
+ Map<String, Object> novaServerProp = resource.getProperties();
+ Object novaServerPropMetadata;
+ if (MapUtils.isNotEmpty(novaServerProp)) {
+ novaServerPropMetadata = novaServerProp.get("metadata");
+ if (novaServerPropMetadata == null) {
+ globalValidationContext.addMessage(
+ fileName,
+ ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_METADATA.getErrorMessage(),
+ resourceId));
+ } else if (novaServerPropMetadata instanceof Map) {
+ TreeMap<String, Object> propertyMap = new TreeMap(new Comparator<String>() {
+
+ @Override
+ public int compare(String o1, String o2) {
+ return o1.compareToIgnoreCase(o2);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return false;
+ }
+ });
+ propertyMap.putAll((Map) novaServerPropMetadata);
+ if (!propertyMap.containsKey("vf_module_id")) {
+ globalValidationContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder.getErrorWithParameters(
+ Messages.MISSING_NOVA_SERVER_VF_MODULE_ID.getErrorMessage(), resourceId));
+ }
+ if (!propertyMap.containsKey("vnf_id")) {
+ globalValidationContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_VNF_ID.getErrorMessage(),
+ resourceId));
+ }
+ }
+ }
+ }
+
+ private void validateNovaServerResourceNetworkUniqueRole(String fileName, String resourceId,
+ HeatOrchestrationTemplate
+ heatOrchestrationTemplate,
+ GlobalValidationContext
+ globalValidationContext) {
+
+ String network;
+ String role;
+ Map<String, String> uniqueResourcePortNetworkRole = new HashMap<>();
+
+ Object propertyNetworkValue =
+ heatOrchestrationTemplate.getResources().get(resourceId).getProperties().get("networks");
+ if (propertyNetworkValue != null && propertyNetworkValue instanceof List) {
+ List<String> portResourceIdList =
+ getNovaNetworkPortResourceList(fileName, (List) propertyNetworkValue,
+ globalValidationContext);
+ for (String portResourceId : portResourceIdList) {
+ Resource portResource = heatOrchestrationTemplate.getResources().get(portResourceId);
+ if (portResource != null && portResource.getType()
+ .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
+ Map portNetwork =
+ getPortNetwork(fileName, resourceId, portResource, globalValidationContext);
+ if (Objects.nonNull(portNetwork)) {
+ network = (String) portNetwork.get("get_param");
+ if (Objects.nonNull(network)) {
+ role = getNetworkRole(network);
+ if (role != null && uniqueResourcePortNetworkRole.containsKey(role)) {
+ globalValidationContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder.getErrorWithParameters(
+ Messages.RESOURCE_CONNECTED_TO_TWO_EXTERNAL_NETWORKS_WITH_SAME_ROLE
+ .getErrorMessage(), resourceId, role));
+ } else {
+ uniqueResourcePortNetworkRole.put(role, portResourceId);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ private Map getPortNetwork(String fileName, String resourceId, Resource portResource,
+ GlobalValidationContext globalValidationContext) {
+ Object portNetwork = portResource.getProperties().get("network_id");
+ if (portNetwork == null) {
+ portNetwork = portResource.getProperties().get("network");
+ }
+ if (!(portNetwork instanceof Map)) {
+ globalValidationContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
+ "network or network_id", resourceId));
+ return null;
+ }
+ return (Map) portNetwork;
+ }
+
+ private List<String> getNovaNetworkPortResourceList(String filename, List propertyNetworkValue,
+ GlobalValidationContext globalContext) {
+ List<String> portResourceIdList = new ArrayList<>();
+ for (Object propValue : propertyNetworkValue) {
+ Object portPropValue = ((Map) propValue).get("port");
+ Collection<String> portResourceIds = HeatStructureUtil
+ .getReferencedValuesByFunctionName(filename, "get_resource", portPropValue,
+ globalContext);
+ if (portResourceIds != null) {
+ portResourceIdList.addAll(portResourceIds);
+ }
+ }
+
+ return portResourceIdList;
+ }
+
+ private String getNetworkRole(String network) {
+ if (network == null) {
+ return null;
+ }
+ if (network.contains("_net_id")) {
+ return network.substring(0, network.indexOf("_net_id"));
+ } else if (network.contains("net_name")) {
+ return network.substring(0, network.indexOf("_net_name"));
+ } else if (network.contains("net_fqdn")) {
+ return network.substring(0, network.indexOf("_net_fqdn"));
+ }
+ return null;
+ }
+
+ private void validateHeatNamingConvention(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ validatePortNetworkNamingConvention(fileName, heatOrchestrationTemplate, globalContext);
+ }
+
+ private void validatePortNetworkNamingConvention(String fileName,
+ HeatOrchestrationTemplate
+ heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
+ return;
+ }
+ String[] regexList = new String[]{".*_net_id", ".*_net_name", ".*_net_fqdn"};
+
+ heatOrchestrationTemplate
+ .getResources()
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue().getType() != null && entry.getValue().getType()
+ .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource()))
+ .forEach(entry -> entry.getValue()
+ .getProperties()
+ .entrySet()
+ .stream()
+ .filter(propertyEntry -> propertyEntry != null
+ && (propertyEntry.getKey().toLowerCase().equals("network".toLowerCase())
+ ||
+ propertyEntry.getKey().equals("network_id")))
+ .forEach(propertyEntry -> validateParamNamingConvention(fileName, entry.getKey(),
+ propertyEntry.getValue(), regexList,
+ Messages.NETWORK_PARAM_NOT_ALIGNED_WITH_GUIDE_LINE, globalContext)));
+ }
+
+ private void validateParamNamingConvention(String fileName, String resourceId,
+ Object propertyValue, String[] regexList,
+ Messages message,
+ GlobalValidationContext globalContext) {
+ Object paramName;
+ if (propertyValue instanceof Map) {
+ paramName = ((Map) propertyValue).get("get_param");
+ if (paramName instanceof String) {
+ if (!evalPattern((String) paramName, regexList)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(message.getErrorMessage(), (String) paramName, resourceId));
+ }
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
+ "network or network_id", resourceId));
+ }
+ }
+
+ private boolean evalPattern(Object paramVal, String[] regexList) {
+ String value = "";
+ if (paramVal instanceof String) {
+ value = ((String) paramVal);
+ }
+ if (paramVal instanceof Integer) {
+ value = paramVal.toString();
+ }
+ return evalPattern(value, regexList);
+ }
+
+ private boolean evalPattern(String paramVal, String[] regexList) {
+
+ for (String regex : regexList) {
+ if (Pattern.matches(regex, paramVal)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ private void validateHeatVolumeFile(String fileName, Map<String, FileData.Type> fileTypeMap,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ //if not heat volume return
+ if (!fileTypeMap.get(fileName).equals(FileData.Type.HEAT_VOL)) {
+ return;
+ }
+
+ //if no resources exist return
+ if (heatOrchestrationTemplate.getResources() == null
+ || heatOrchestrationTemplate.getResources().size() == 0) {
+ return;
+ }
+
+ Set<String> expectedExposedResources = new HashSet<>();
+ Set<String> actualExposedResources = new HashSet<>();
+ heatOrchestrationTemplate.getResources()
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue().getType()
+ .equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource()))
+ .forEach(entry -> expectedExposedResources.add(entry.getKey()));
+
+ if (heatOrchestrationTemplate.getOutputs() != null) {
+
+ heatOrchestrationTemplate.getOutputs().entrySet()
+ .stream()
+ .filter(entry -> isPropertyValueGetResource(fileName, entry.getValue().getValue(),
+ globalContext))
+ .forEach(entry -> actualExposedResources.add(
+ getResourceIdFromPropertyValue(fileName, entry.getValue().getValue(),
+ globalContext)));
+ }
+
+ actualExposedResources.stream().forEach(expectedExposedResources::remove);
+
+ if (expectedExposedResources.size() > 0) {
+ expectedExposedResources
+ .stream()
+ .forEach(name -> globalContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.VOLUME_HEAT_NOT_EXPOSED.getErrorMessage(),
+ name)));
+ }
+ }
+
+ private void validateBaseFile(String fileName, Set<String> baseFiles,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+
+ //if not base return
+ if (baseFiles == null || !baseFiles.contains(fileName)) {
+ return;
+ }
+
+ //if no resources exist return
+ if (heatOrchestrationTemplate.getResources() == null
+ || heatOrchestrationTemplate.getResources().size() == 0) {
+ return;
+ }
+
+ Set<String> expectedExposedResources = new HashSet<>();
+ Set<String> actualExposedResources = new HashSet<>();
+ heatOrchestrationTemplate.getResources()
+ .entrySet()
+ .stream()
+ .filter(entry -> isExpectedToBeExposed(entry.getValue().getType()))
+ .forEach(entry -> expectedExposedResources.add(entry.getKey()));
+
+ if (heatOrchestrationTemplate.getOutputs() != null) {
+
+ heatOrchestrationTemplate.getOutputs().entrySet()
+ .stream()
+ .filter(entry -> isPropertyValueGetResource(fileName, entry.getValue().getValue(),
+ globalContext))
+ .forEach(entry -> actualExposedResources.add(
+ getResourceIdFromPropertyValue(fileName, entry.getValue().getValue(),
+ globalContext)));
+ }
+ actualExposedResources.stream().forEach(expectedExposedResources::remove);
+
+ if (expectedExposedResources.size() > 0) {
+ expectedExposedResources
+ .stream()
+ .forEach(name -> globalContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.RESOURCE_NOT_DEFINED_IN_OUTPUT.getErrorMessage(),
+ name)));
+ }
+ }
+
+ private void validateResourceTypeIsForbidden(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
+ return;
+ }
+
+ heatOrchestrationTemplate.getResources()
+ .entrySet()
+ .stream()
+ .filter(entry ->
+ ForbiddenHeatResourceTypes.findByForbiddenHeatResource(entry.getValue().getType())
+ != null)
+ .filter(entry -> ForbiddenHeatResourceTypes
+ .findByForbiddenHeatResource(entry.getValue().getType())
+ .equals(ForbiddenHeatResourceTypes.HEAT_FLOATING_IP_TYPE))
+ .forEach(entry -> globalContext.addMessage(fileName, ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.FLOATING_IP_NOT_IN_USE.getErrorMessage(),
+ entry.getKey())));
+ }
+
+
+ private void validateFixedIpsNamingConvention(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
+ return;
+ }
+
+ heatOrchestrationTemplate.getResources()
+ .entrySet()
+ .stream()
+ .filter(entry -> HeatResourcesTypes.findByHeatResource(entry.getValue().getType()) != null)
+ .filter(entry -> HeatResourcesTypes.findByHeatResource(entry.getValue().getType())
+ .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE))
+ .forEach(entry -> checkNeutronPortFixedIpsName(fileName, entry, globalContext));
+ }
+
+ private void validateImageAndFlavorFromNovaServer(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
+ return;
+ }
+
+ String[] imageOrFlavorAsParameters = new String[]{"image", "flavor"};
+ Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
+
+ for (String imageOrFlavor : imageOrFlavorAsParameters) {
+ checkImageAndFlavorNames(fileName, imageOrFlavor, resourceEntry.getKey(), propertiesMap,
+ globalContext);
+ }
+ }
+
+ private void checkImageAndFlavorNames(String fileName, String imageOrFlavor, String resourceId,
+ Map<String, Object> propertiesMap,
+ GlobalValidationContext globalContext) {
+ Object nameValue =
+ propertiesMap.get(imageOrFlavor) == null ? null : propertiesMap.get(imageOrFlavor);
+ String[] regexList = new String[]{".*_" + imageOrFlavor + "_name"};
+
+ if (Objects.nonNull(nameValue)) {
+ if (nameValue instanceof Map) {
+ String imageOrFlavorName = getWantedNameFromPropertyValueGetParam(nameValue);
+ if (Objects.nonNull(imageOrFlavorName)) {
+ if (!evalPattern(imageOrFlavorName, regexList)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.WRONG_IMAGE_OR_FLAVOR_NAME_NOVA_SERVER.getErrorMessage(),
+ imageOrFlavor, resourceId));
+ }
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(), imageOrFlavor,
+ resourceId));
+ }
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private void checkNeutronPortFixedIpsName(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ String[] regexList =
+ new String[]{"[^_]+_[^_]+_ips", "[^_]+_[^_]+_v6_ips", "[^_]+_[^_]+_ip_(\\d+)",
+ "[^_]+_[^_]+_v6_ip_(\\d+)"};
+
+ if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
+ return;
+ }
+
+ Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
+ Object fixedIps = propertiesMap.get("fixed_ips");
+ if (Objects.nonNull(fixedIps) && fixedIps instanceof List) {
+ List<Object> fixedIpsList = (List<Object>) fixedIps;
+ for (Object fixedIpsObject : fixedIpsList) {
+ Map.Entry<String, Object> fixedIpsEntry =
+ ((Map<String, Object>) fixedIpsObject).entrySet().iterator().next();
+ if (Objects.nonNull(fixedIpsEntry)) {
+ if (fixedIpsEntry.getValue() instanceof Map) {
+ String fixedIpsName = getWantedNameFromPropertyValueGetParam(fixedIpsEntry.getValue());
+ if (Objects.nonNull(fixedIpsName)) {
+ if (!evalPattern(fixedIpsName, regexList)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.FIXED_IPS_NOT_ALIGNED_WITH_GUIDE_LINES.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(), "fixed_ips",
+ resourceEntry.getKey()));
+ }
+ }
+ }
+ }
+ }
+
+
+ private void validateNovaServerNamingConvention(String fileName, String envFileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
+ return;
+ }
+
+ checkIfNovaNameByGuidelines(fileName, envFileName, resourceEntry, globalContext);
+ }
+
+ private void checkIfNovaNameByGuidelines(String fileName, String envFileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
+ return;
+ }
+
+ Object novaServerName = resourceEntry.getValue().getProperties().get("name");
+ Map novaNameMap;
+ String novaName;
+ if (Objects.nonNull(novaServerName)) {
+ if (novaServerName instanceof Map) {
+ novaNameMap = (Map) novaServerName;
+ Object novaNameGetParam =
+ novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction()) == null ? null
+ : novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction());
+ if (Objects.nonNull(novaNameGetParam)) {
+ checkNovaNameGetParamValueMap(fileName, novaNameGetParam, resourceEntry, globalContext);
+ novaName = novaNameGetParam instanceof List ? (String) ((List) novaNameGetParam).get(0)
+ : (String) novaNameGetParam;
+ checkIfNovaNameParameterInEnvIsStringOrList(fileName, envFileName, resourceEntry,
+ novaName, globalContext);
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
+ "nova server name", resourceEntry.getKey()));
+ }
+ }
+
+ }
+
+ private void checkIfNovaNameParameterInEnvIsStringOrList(String fileName, String envFileName,
+ Map.Entry<String, Resource>
+ resourceEntry,
+ String novaServerName,
+ GlobalValidationContext globalContext) {
+ if (Objects.nonNull(envFileName)) {
+ Environment environment = validateEnvContent(envFileName, globalContext);
+
+ if (environment != null && MapUtils.isNotEmpty(environment.getParameters())) {
+ Object novaServerNameEnvValue =
+ environment.getParameters().containsKey(novaServerName) ? environment.getParameters()
+ .get(novaServerName) : null;
+ if (Objects.nonNull(novaServerNameEnvValue)) {
+ if (!DefinedHeatParameterTypes
+ .isNovaServerEnvValueIsFromRightType(novaServerNameEnvValue)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.NOVA_SERVER_NAME_NOT_ALIGNED_WITH_GUIDE_LINES.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+ }
+ }
+ }
+
+
+ private void validateNovaServerAvailabilityZoneName(String fileName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ String[] regexList = new String[]{"availability_zone_(\\d+)"};
+
+ if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
+ return;
+ }
+
+ Object availabilityZoneMap =
+ resourceEntry.getValue().getProperties().containsKey("availability_zone") ? resourceEntry
+ .getValue().getProperties().get("availability_zone") : null;
+
+ if (Objects.nonNull(availabilityZoneMap)) {
+ if (availabilityZoneMap instanceof Map) {
+ String availabilityZoneName = getWantedNameFromPropertyValueGetParam(availabilityZoneMap);
+
+ if (availabilityZoneName != null) {
+ if (!evalPattern(availabilityZoneName, regexList)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.AVAILABILITY_ZONE_NOT_ALIGNED_WITH_GUIDE_LINES.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+ } else {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
+ "availability_zone", resourceEntry.getKey()));
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private void checkNovaNameGetParamValueMap(String fileName, Object getParamValue,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ if (getParamValue instanceof List) {
+ List<Object> getParamNameList = (List) getParamValue;
+ String[] regexName = new String[]{".*_names"};
+ isNovaNameAsListLegal(fileName, getParamNameList, regexName, resourceEntry, globalContext);
+ } else if (getParamValue instanceof String) {
+ String[] regexName = new String[]{".*_name_(\\d+)"};
+ isNovaNameAsStringLegal(fileName, (String) getParamValue, regexName, resourceEntry,
+ globalContext);
+ }
+
+ }
+
+
+ private void isNovaNameAsListLegal(String fileName, List<Object> getParamNameList,
+ String[] regexName, Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+
+ if (getParamNameList.size() != 2 || !evalPattern(getParamNameList.get(0), regexName)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.NOVA_SERVER_NAME_NOT_ALIGNED_WITH_GUIDE_LINES.getErrorMessage(),
+ resourceEntry.getKey()));
+ }
+ }
+
+ private boolean isNovaNameAsStringLegal(String fileName, String novaName, String[] regexName,
+ Map.Entry<String, Resource> resourceEntry,
+ GlobalValidationContext globalContext) {
+ if (!evalPattern(novaName, regexName)) {
+ globalContext.addMessage(fileName, ErrorLevel.WARNING, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.NOVA_SERVER_NAME_NOT_ALIGNED_WITH_GUIDE_LINES.getErrorMessage(),
+ resourceEntry.getKey()));
+ return false;
+ }
+ return true;
+ }
+
+ private String getWantedNameFromPropertyValueGetParam(Object value) {
+ Set<String> paramName = HeatStructureUtil
+ .getReferencedValuesByFunctionName(null, ResourceReferenceFunctions.GET_PARAM.getFunction(),
+ value, null);
+ if (paramName != null && CollectionUtils.isNotEmpty(paramName)) {
+ return (String) paramName.toArray()[0];
+ }
+ return null;
+ }
+
+ private String getResourceIdFromPropertyValue(String filename, Object value,
+ GlobalValidationContext globalContext) {
+ Set<String> referenceValues = HeatStructureUtil.getReferencedValuesByFunctionName(filename,
+ ResourceReferenceFunctions.GET_RESOURCE.getFunction(), value, globalContext);
+ if (referenceValues != null && CollectionUtils.isNotEmpty(referenceValues)) {
+ return (String) referenceValues.toArray()[0];
+ }
+ return null;
+ }
+
+ private boolean isPropertyValueGetResource(String filename, Object value,
+ GlobalValidationContext globalContext) {
+ Set<String> referenceValues = HeatStructureUtil.getReferencedValuesByFunctionName(filename,
+ ResourceReferenceFunctions.GET_RESOURCE.getFunction(), value, globalContext);
+ return referenceValues != null && (referenceValues.size() > 0);
+ }
+
+ private boolean isExpectedToBeExposed(String type) {
+ return HeatResourcesTypes.isResourceExpectedToBeExposed(type);
+ }
+
+ private Set<String> validateManifest(ManifestContent manifestContent,
+ GlobalValidationContext globalContext) {
+ Set<String> baseFiles = ManifestUtil.getBaseFiles(manifestContent);
+ if (baseFiles == null || baseFiles.size() == 0) {
+ globalContext.addMessage(
+ AsdcCommon.MANIFEST_NAME,
+ ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MISSIN_BASE_HEAT_FILE.getErrorMessage()));
+ } else if (baseFiles.size() > 1) {
+ String baseFileList = getElementListAsString(baseFiles);
+ globalContext.addMessage(
+ AsdcCommon.MANIFEST_NAME,
+ ErrorLevel.WARNING,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.MULTI_BASE_HEAT_FILE.getErrorMessage(),
+ baseFileList));
+ }
+ return baseFiles;
+ }
+
+ private String getElementListAsString(Set<String> elementCollection) {
+
+ return "[" + CommonMethods.collectionToCommaSeparatedString(elementCollection) + "]";
+ }
+
+
+ private Environment validateEnvContent(String envFileName,
+ GlobalValidationContext globalContext) {
+ Environment envContent;
+ try {
+ envContent =
+ new YamlUtil().yamlToObject(globalContext.getFileContent(envFileName), Environment.class);
+ } catch (Exception exception) {
+ return null;
+ }
+ return envContent;
+ }
+
+ private HeatOrchestrationTemplate checkHeatOrchestrationPreCondition(String fileName,
+ GlobalValidationContext
+ globalContext) {
+ HeatOrchestrationTemplate heatOrchestrationTemplate;
+ try {
+ heatOrchestrationTemplate = new YamlUtil()
+ .yamlToObject(globalContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
+
+ } catch (Exception exception) {
+ return null;
+ }
+ return heatOrchestrationTemplate;
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/HeatValidator.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/HeatValidator.java
new file mode 100644
index 0000000000..c287394a54
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/HeatValidator.java
@@ -0,0 +1,469 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.validators;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.core.utilities.json.JsonUtil;
+import org.openecomp.core.utilities.yaml.YamlUtil;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.interfaces.Validator;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.common.utils.AsdcCommon;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData;
+import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
+import org.openecomp.sdc.heat.datatypes.model.Environment;
+import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
+import org.openecomp.sdc.heat.datatypes.model.HeatPseudoParameters;
+import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
+import org.openecomp.sdc.heat.datatypes.model.Output;
+import org.openecomp.sdc.heat.datatypes.model.Parameter;
+import org.openecomp.sdc.heat.datatypes.model.Resource;
+import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
+import org.openecomp.sdc.heat.services.HeatStructureUtil;
+import org.openecomp.sdc.heat.services.manifest.ManifestUtil;
+import org.openecomp.sdc.validation.impl.util.HeatValidationService;
+import org.openecomp.sdc.validation.impl.util.ResourceValidationHeatValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+public class HeatValidator implements Validator {
+
+ protected static Logger logger = LoggerFactory.getLogger(HeatValidator.class);
+
+ /* validation 9*/
+ private static void validateAllRequiredArtifactsExist(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Set<String> artifacts,
+ GlobalValidationContext globalContext) {
+ Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
+ : heatOrchestrationTemplate.getResources().values();
+
+ if (CollectionUtils.isNotEmpty(resourcesValues)) {
+ for (Resource resource : resourcesValues) {
+ Collection<Object> properties =
+ resource.getProperties() == null ? null : resource.getProperties().values();
+ if (CollectionUtils.isNotEmpty(properties)) {
+ for (Object property : properties) {
+ if (property instanceof Map) {
+ Set<String> artifactNames = HeatStructureUtil
+ .getReferencedValuesByFunctionName(fileName,
+ ResourceReferenceFunctions.GET_FILE.getFunction(), property, globalContext);
+ artifacts.addAll(artifactNames);
+ HeatValidationService.checkArtifactsExistence(fileName, artifactNames, globalContext);
+ }
+ }
+ }
+ }
+ }
+
+
+ }
+
+ /* validation 14 */
+ private static void validateAllResourceReferencesExist(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+
+ Set<String> resourcesNames = heatOrchestrationTemplate.getResources() == null ? null
+ : heatOrchestrationTemplate.getResources().keySet();
+ Collection<Resource> resourcesValues = heatOrchestrationTemplate.getResources() == null ? null
+ : heatOrchestrationTemplate.getResources().values();
+ Collection<Output> outputsValues = heatOrchestrationTemplate.getOutputs() == null ? null
+ : heatOrchestrationTemplate.getOutputs().values();
+
+ HeatValidationService
+ .checkResourceExistenceFromResourcesMap(fileName, resourcesNames, resourcesValues,
+ globalContext);
+ HeatValidationService
+ .checkResourceExistenceFromResourcesMap(fileName, resourcesNames, outputsValues,
+ globalContext);
+
+ }
+
+ /* validation 16 */
+ private static void validateGetParamPointToParameter(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
+ : heatOrchestrationTemplate.getParameters().keySet();
+ Map<String, Resource> resourcesMap = heatOrchestrationTemplate.getResources();
+
+ if (CollectionUtils.isNotEmpty(parametersNames) && MapUtils.isNotEmpty(resourcesMap)) {
+ for (Map.Entry<String, Resource> resourceEntry : resourcesMap.entrySet()) {
+ Resource resource = resourceEntry.getValue();
+ Map<String, Object> properties = resource.getProperties();
+ if (MapUtils.isNotEmpty(properties)) {
+ Collection<Object> propertiesValues = properties.values();
+ if (CollectionUtils.isNotEmpty(propertiesValues)) {
+ for (Object propertyObject : propertiesValues) {
+ //Set<String> referencedParameterNames = HeatValidationService
+ // .getParameterNameFromGetParamMap(propertyObject);
+ Set<String> referencedParameterNames = HeatStructureUtil
+ .getReferencedValuesByFunctionName(fileName, "get_param", propertyObject,
+ globalContext);
+
+ validateReferenceParams(fileName, resourceEntry.getKey(), parametersNames,
+ referencedParameterNames, globalContext);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static void validateReferenceParams(String fileName, String resourceName,
+ Set<String> parametersNamesFromFile,
+ Set<String> referencedParametersNames,
+ GlobalValidationContext globalContext) {
+
+ for (String parameterName : referencedParametersNames) {
+ if (!isHeatPseudoParameter(parameterName)
+ && !parametersNamesFromFile.contains(parameterName)) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.REFERENCED_PARAMETER_NOT_FOUND.getErrorMessage(),
+ parameterName, resourceName));
+ }
+ }
+ }
+
+ private static boolean isHeatPseudoParameter(String parameterName) {
+ return HeatPseudoParameters.getPseudoParameterNames().contains(parameterName);
+ }
+
+ /* validation 18*/
+ private static void validateGetAttr(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Map<String, Output> outputMap;
+ outputMap = heatOrchestrationTemplate.getOutputs();
+
+ if (MapUtils.isNotEmpty(outputMap)) {
+ HeatValidationService.loopOverOutputMapAndValidateGetAttrFromNested(fileName, outputMap,
+ heatOrchestrationTemplate, globalContext);
+ }
+ }
+
+ /* validation 17 + */
+ private static void validateEnvFile(String fileName, String envFileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+
+ Environment envContent;
+
+ if (!envFileName.contains(".env")) {
+ globalContext.addMessage(envFileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_ENV_FILE_EXTENSION.getErrorMessage(),
+ envFileName));
+ }
+
+ envContent = HeatValidationService.validateEnvContent(fileName, envFileName, globalContext);
+ if (envContent != null) {
+ validateEnvContentIsSubSetOfHeatParameters(envFileName, envContent, globalContext,
+ heatOrchestrationTemplate);
+ validateEnvParametersMatchDefinedHeatParameterTypes(envFileName, envContent, globalContext,
+ heatOrchestrationTemplate);
+ }
+
+ }
+
+ private static void validateEnvContentIsSubSetOfHeatParameters(String envFile,
+ Environment envContent,
+ GlobalValidationContext globalContext,
+ HeatOrchestrationTemplate heatOrchestrationTemplate) {
+ Set<String> parametersNames = heatOrchestrationTemplate.getParameters() == null ? null
+ : heatOrchestrationTemplate.getParameters().keySet();
+
+ if (MapUtils.isNotEmpty(envContent.getParameters())) {
+ if (CollectionUtils.isNotEmpty(parametersNames)) {
+ for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
+ String envParameter = envEntry.getKey();
+ if (!parametersNames.contains(envParameter)) {
+ globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.ENV_INCLUDES_PARAMETER_NOT_IN_HEAT.getErrorMessage(), envFile,
+ envParameter));
+ }
+ }
+ } else {
+ for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
+ globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.ENV_INCLUDES_PARAMETER_NOT_IN_HEAT.getErrorMessage(),
+ envFile, envEntry.getKey()));
+ }
+ }
+ }
+ }
+
+ private static void validateParameterDefaultTypeAlignWithType(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ Map<String, Parameter> parametersMap = heatOrchestrationTemplate.getParameters() == null ? null
+ : heatOrchestrationTemplate.getParameters();
+
+ if (MapUtils.isNotEmpty(parametersMap)) {
+ for (Map.Entry<String, Parameter> parameterEntry : parametersMap.entrySet()) {
+ Parameter parameter = parameterEntry.getValue();
+ String parameterType = parameter.getType();
+ Object parameterDefault = parameter.get_default();
+ if (parameterDefault != null && parameterType != null) {
+ boolean isValueMatchDefault =
+ DefinedHeatParameterTypes.isValueIsFromGivenType(parameterDefault, parameterType);
+ if (!isValueMatchDefault) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.PARAMETER_DEFAULT_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
+ parameterEntry.getKey(), parameterType));
+ }
+ }
+ }
+ }
+ }
+
+ private static void validateEnvParametersMatchDefinedHeatParameterTypes(String envFile,
+ Environment envContent,
+ GlobalValidationContext globalContext,
+ HeatOrchestrationTemplate heatOrchestrationTemplate) {
+ Map<String, Parameter> heatParameters = heatOrchestrationTemplate.getParameters();
+
+ if (MapUtils.isNotEmpty(heatParameters) && MapUtils.isNotEmpty(envContent.getParameters())) {
+ for (Map.Entry<String, Object> envEntry : envContent.getParameters().entrySet()) {
+ String parameterName = envEntry.getKey();
+ Object parameterEnvValue = envEntry.getValue();
+ Parameter parameterFromHeatFile = heatParameters.get(parameterName);
+ if (parameterFromHeatFile != null) {
+ String parameterType = parameterFromHeatFile.getType();
+ if (!DefinedHeatParameterTypes.isEmptyValueInEnv(parameterEnvValue)
+ && !DefinedHeatParameterTypes.isValueIsFromGivenType(parameterEnvValue,
+ parameterType)) {
+ globalContext.addMessage(envFile, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(
+ Messages.PARAMETER_ENV_VALUE_NOT_ALIGN_WITH_TYPE.getErrorMessage(),
+ parameterName));
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void validate(GlobalValidationContext globalContext) {
+
+ ManifestContent manifestContent;
+ try {
+ manifestContent = checkValidationPreCondition(globalContext);
+ } catch (Exception e0) {
+ return;
+ }
+ String baseFileName;
+ Map<String, FileData.Type> fileTypeMap = ManifestUtil.getFileTypeMap(manifestContent);
+ Map<String, FileData> fileEnvMap = ManifestUtil.getFileAndItsEnv(manifestContent);
+ Set<String> baseFiles = ManifestUtil.getBaseFiles(manifestContent);
+ Set<String> securityGroupsNamesFromBaseFileOutputs;
+ Set<String> artifacts = new HashSet<>();
+
+
+ baseFileName = CollectionUtils.isEmpty(baseFiles) ? null : baseFiles.iterator().next();
+ securityGroupsNamesFromBaseFileOutputs = baseFileName == null ? null
+ : checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot(baseFileName,
+ globalContext);
+
+
+ globalContext.getFiles().stream()
+ .filter(fileName -> FileData.isHeatFile(fileTypeMap.get(fileName))).forEach(
+ fileName -> validate(fileName,
+ fileEnvMap.get(fileName) == null ? null : fileEnvMap.get(fileName).getFile(),
+ baseFileName == null ? null : baseFileName, artifacts,
+ securityGroupsNamesFromBaseFileOutputs, globalContext));
+
+
+ Set<String> manifestArtifacts = ManifestUtil.getArtifacts(manifestContent);
+
+ globalContext.getFiles().stream()
+ .filter(fileName -> manifestArtifacts.contains(fileName) && !artifacts.contains(fileName))
+ .forEach(fileName -> globalContext.addMessage(fileName, ErrorLevel.WARNING,
+ Messages.ARTIFACT_FILE_NOT_REFERENCED.getErrorMessage()));
+
+ ResourceValidationHeatValidator
+ .handleNotEmptyResourceNamesList(baseFileName, securityGroupsNamesFromBaseFileOutputs,
+ "SecurityGroup", globalContext);
+
+ }
+
+ private void validate(String fileName, String envFileName, String baseFileName,
+ Set<String> artifacts, Set<String> securityGroupsNamesFromBaseFileOutputs,
+ GlobalValidationContext globalContext) {
+ HeatOrchestrationTemplate heatOrchestrationTemplate =
+ checkHeatOrchestrationPreCondition(fileName, globalContext);
+
+
+ if (heatOrchestrationTemplate != null) {
+ if (!(fileName.contains(".yaml") || fileName.contains(".yml"))) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_HEAT_FILE_EXTENSION.getErrorMessage(),
+ fileName));
+ }
+
+ validateHeatBaseStructure(fileName, heatOrchestrationTemplate, globalContext);
+
+ ResourceValidationHeatValidator
+ .validateResourceType(fileName, baseFileName, securityGroupsNamesFromBaseFileOutputs,
+ heatOrchestrationTemplate, globalContext);
+ validateParameterDefaultTypeAlignWithType(fileName, heatOrchestrationTemplate, globalContext);
+ validateAllResourceReferencesExist(fileName, heatOrchestrationTemplate, globalContext);
+ validateGetParamPointToParameter(fileName, heatOrchestrationTemplate, globalContext);
+ validateGetAttr(fileName, heatOrchestrationTemplate, globalContext);
+ validateAllRequiredArtifactsExist(fileName, heatOrchestrationTemplate, artifacts,
+ globalContext);
+
+ if (envFileName != null) {
+ validateEnvFile(fileName, envFileName, heatOrchestrationTemplate, globalContext);
+ }
+ }
+ }
+
+ private void validateHeatBaseStructure(String fileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ GlobalValidationContext globalContext) {
+ if (heatOrchestrationTemplate.getHeat_template_version() == null) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
+ "missing template version"));
+ }
+ if (heatOrchestrationTemplate.getResources() == null
+ || heatOrchestrationTemplate.getResources().size() == 0) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
+ "heat file must have minimum one resource"));
+ }
+ }
+
+ protected ManifestContent checkValidationPreCondition(GlobalValidationContext globalContext) {
+ InputStream manifest = globalContext.getFileContent(AsdcCommon.MANIFEST_NAME);
+ if (manifest == null) {
+ throw new RuntimeException("Can't load manifest file for Heat Validator");
+ }
+ ManifestContent manifestContent;
+ try {
+ manifestContent = JsonUtil.json2Object(manifest, ManifestContent.class);
+ } catch (Exception e0) {
+ throw new RuntimeException("Can't load manifest file for Heat Validator");
+ }
+
+ return manifestContent;
+ }
+
+
+ private HeatOrchestrationTemplate checkHeatOrchestrationPreCondition(String fileName,
+ GlobalValidationContext globalContext) {
+ HeatOrchestrationTemplate heatOrchestrationTemplate;
+ try {
+ heatOrchestrationTemplate = new YamlUtil()
+ .yamlToObject(globalContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
+ } catch (Exception e0) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_HEAT_FORMAT_REASON.getErrorMessage(),
+ getParserExceptionReason(e0)));
+ return null;
+ }
+
+ return heatOrchestrationTemplate;
+ }
+
+
+ private Set<String> checkForBaseFilePortsExistenceAndReturnSecurityGroupNamesFromOutputsIfNot(
+ String baseFileName, GlobalValidationContext globalContext) {
+ Set<String> securityGroupsNamesFromOutputsMap = new HashSet<>();
+ HeatOrchestrationTemplate heatOrchestrationTemplate =
+ checkHeatOrchestrationPreCondition(baseFileName, globalContext);
+
+ if (heatOrchestrationTemplate != null) {
+ Map<String, Resource> resourceMap = heatOrchestrationTemplate.getResources();
+ if (!isPortResourceExistInBaseFile(resourceMap)) {
+ getSecurityGroupsReferencedResourcesFromOutputs(securityGroupsNamesFromOutputsMap,
+ heatOrchestrationTemplate.getOutputs(), resourceMap);
+ }
+ }
+
+ return securityGroupsNamesFromOutputsMap;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private void getSecurityGroupsReferencedResourcesFromOutputs(
+ Set<String> securityGroupsNamesFromOutputsMap, Map<String, Output> outputMap,
+ Map<String, Resource> resourceMap) {
+ if (MapUtils.isNotEmpty(outputMap)) {
+ for (Map.Entry<String, Output> outputEntry : outputMap.entrySet()) {
+ Object outputValue = outputEntry.getValue().getValue();
+ if (Objects.nonNull(outputValue) && outputValue instanceof Map) {
+ String resourceName = (String) ((Map) outputValue)
+ .get(ResourceReferenceFunctions.GET_RESOURCE.getFunction());
+ if (Objects.nonNull(resourceName)) {
+ Resource resource = resourceMap.get(resourceName);
+ if (Objects.nonNull(resource) && resource.getType().equals(
+ HeatResourcesTypes.NEUTRON_SECURITY_GROUP_RESOURCE_TYPE.getHeatResource())) {
+ securityGroupsNamesFromOutputsMap.add(outputEntry.getKey());
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ private boolean isPortResourceExistInBaseFile(Map<String, Resource> resourceMap) {
+ for (Map.Entry<String, Resource> resourceEntry : resourceMap.entrySet()) {
+ if (resourceEntry.getValue().getType()
+ .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ private String getParserExceptionReason(Exception e0) {
+ String reason;
+
+ if (e0.getCause() != null && e0.getCause().getCause() != null) {
+ reason = e0.getCause().getCause().getMessage();
+ } else if (e0.getCause() != null) {
+ reason = e0.getCause().getMessage();
+ } else {
+ reason = Messages.GENERAL_HEAT_PARSER_ERROR.getErrorMessage();
+ }
+ return reason;
+ }
+
+
+}
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/ManifestValidator.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/ManifestValidator.java
new file mode 100644
index 0000000000..4ce40f0007
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/ManifestValidator.java
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.validators;
+
+import org.openecomp.core.utilities.json.JsonUtil;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.interfaces.Validator;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.common.utils.AsdcCommon;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData;
+import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ManifestValidator implements Validator {
+
+ private static Logger logger = LoggerFactory.getLogger(YamlValidator.class);
+
+
+ @Override
+ public void validate(GlobalValidationContext globalContext) {
+
+
+ InputStream content = globalContext.getFileContent(AsdcCommon.MANIFEST_NAME);
+ ManifestContent manifestContent;
+
+ try {
+ manifestContent = JsonUtil.json2Object(content, ManifestContent.class);
+ } catch (RuntimeException re) {
+ globalContext.addMessage(AsdcCommon.MANIFEST_NAME, ErrorLevel.ERROR,
+ Messages.INVALID_MANIFEST_FILE.getErrorMessage());
+ return;
+ }
+
+ List<String> manifestFiles = getManifestFileList(manifestContent, globalContext);
+ manifestFiles.stream().filter(name ->
+ !globalContext.getFileContextMap().containsKey(name)
+ ).forEach(name -> globalContext
+ .addMessage(name, ErrorLevel.ERROR, Messages.MISSING_FILE_IN_ZIP.getErrorMessage()));
+
+ globalContext.getFileContextMap().keySet().stream().filter(name ->
+ !manifestFiles.contains(name) && !AsdcCommon.MANIFEST_NAME.equals(name)
+ ).forEach(name ->
+ globalContext.addMessage(name, ErrorLevel.WARNING,
+ Messages.MISSING_FILE_IN_MANIFEST.getErrorMessage())
+ );
+
+ }
+
+ private List<String> getManifestFileList(ManifestContent manifestContent,
+ GlobalValidationContext context) {
+ ManifestScanner manifestScanner = new ManifestScanner();
+ manifestScanner.init(context);
+ manifestScanner.scan(null, manifestContent.getData(), context);
+ return manifestScanner.getFileList();
+ }
+
+
+ private class ManifestScanner {
+ private GlobalValidationContext globalValidationContext;
+ private List<String> fileList;
+
+ public void init(GlobalValidationContext globalValidationContext) {
+ this.globalValidationContext = globalValidationContext;
+ this.fileList = new ArrayList<>();
+ }
+
+
+ public void scan(FileData fileData, List<FileData> data,
+ GlobalValidationContext globalContext) {
+ if (fileData == null) {
+ for (FileData childFileData : data) {
+ if (childFileData.getType() != null
+ && childFileData.getType().equals(FileData.Type.HEAT_ENV)) {
+ globalContext.addMessage(childFileData.getFile(), ErrorLevel.ERROR,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.ENV_NOT_ASSOCIATED_TO_HEAT.getErrorMessage()));
+ }
+ }
+ }
+ if (fileData != null) {
+ fileList.add(fileData.getFile());
+ validateFileTypeVsFileName(fileData);
+ }
+ if (data == null) {
+ return;
+ }
+ data.stream().forEach(chileFileData -> {
+ scan(chileFileData, chileFileData.getData(), globalContext);
+ });
+ }
+
+
+ public List<String> getFileList() {
+ return this.fileList;
+ }
+
+ private void validateFileTypeVsFileName(FileData fileData) {
+ String fileName = fileData.getFile();
+ if (fileName == null) {
+ this.globalValidationContext.addMessage(AsdcCommon.MANIFEST_NAME, ErrorLevel.ERROR,
+ Messages.MISSING_FILE_NAME_IN_MANIFEST.getErrorMessage());
+
+ }
+ FileData.Type type = fileData.getType();
+ if (type == null) {
+ this.globalValidationContext
+ .addMessage(fileName, ErrorLevel.ERROR, Messages.INVALID_FILE_TYPE.getErrorMessage());
+ } else if (type.equals(FileData.Type.HEAT_NET) || type.equals(FileData.Type.HEAT_VOL)
+ || type.equals(FileData.Type.HEAT)) {
+ if (fileName != null && !fileName.endsWith(".yml") && !fileName.endsWith(".yaml")) {
+ this.globalValidationContext.addMessage(fileName, ErrorLevel.ERROR,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_HEAT_FILE_EXTENSION.getErrorMessage(),
+ fileName));
+ }
+ } else if (type.equals(FileData.Type.HEAT_ENV)) {
+ if (fileName != null && !fileName.endsWith(".env")) {
+ this.globalValidationContext.addMessage(fileName, ErrorLevel.ERROR,
+ ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.WRONG_ENV_FILE_EXTENSION.getErrorMessage(),
+ fileName));
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/YamlValidator.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/YamlValidator.java
new file mode 100644
index 0000000000..4d05b2b066
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-impl/src/main/java/org/openecomp/sdc/validation/impl/validators/YamlValidator.java
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.validation.impl.validators;
+
+import org.openecomp.core.utilities.yaml.YamlUtil;
+import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
+import org.openecomp.core.validation.errors.Messages;
+import org.openecomp.core.validation.interfaces.Validator;
+import org.openecomp.core.validation.types.GlobalValidationContext;
+import org.openecomp.sdc.datatypes.error.ErrorLevel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.error.MarkedYAMLException;
+import org.yaml.snakeyaml.parser.ParserException;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Map;
+
+public class YamlValidator implements Validator {
+
+ private static final Logger logger = LoggerFactory.getLogger(YamlValidator.class);
+
+ @Override
+ public void validate(GlobalValidationContext globalContext) {
+
+ Collection<String> files = globalContext.files(
+ (fileName, globalValidationContext) -> (fileName.endsWith(".yaml")
+ || fileName.endsWith(".yml") || fileName.endsWith(".env")));
+
+ files.stream().forEach(fileName -> validate(fileName, globalContext));
+ }
+
+ private void validate(String fileName, GlobalValidationContext globalContext) {
+ InputStream rowContent = globalContext.getFileContent(fileName);
+ if (rowContent == null) {
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_YAML_FORMAT_REASON.getErrorMessage(),
+ Messages.EMPTY_YAML_FILE.getErrorMessage()));
+ return; /* no need to continue validation */
+ }
+
+ try {
+ convert(rowContent, Map.class);
+ } catch (Exception exception) {
+
+ globalContext.addMessage(fileName, ErrorLevel.ERROR, ErrorMessagesFormatBuilder
+ .getErrorWithParameters(Messages.INVALID_YAML_FORMAT_REASON.getErrorMessage(),
+ getParserExceptionReason(exception)));
+ logger.error("Exception in yaml parser. message:" + exception.getMessage());
+ }
+ }
+
+ private String getParserExceptionReason(Exception exception) {
+ String reason = null;
+
+ if (exception.getCause() instanceof MarkedYAMLException) {
+ if (exception.getCause() != null) {
+ if (exception.getCause().getCause() instanceof ParserException) {
+ reason = exception.getCause().getCause().getMessage();
+ } else {
+ reason = exception.getCause().getMessage();
+ }
+ }
+ } else if (exception instanceof MarkedYAMLException) {
+
+ reason = exception.getMessage();
+
+ } else {
+ reason = Messages.GENERAL_YAML_PARSER_ERROR.getErrorMessage();
+ }
+ return reason;
+ }
+
+
+ private <T> T convert(InputStream content, Class<T> type) {
+ return new YamlUtil().yamlToObject(content, type);
+ }
+}