1 package org.openecomp.sdc.validation.impl.validators.namingconvention;
3 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE;
4 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE;
5 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE;
9 import java.util.Objects;
10 import java.util.Optional;
12 import java.util.stream.Collectors;
13 import java.util.stream.Stream;
15 import org.openecomp.core.validation.ErrorMessageCode;
16 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
17 import org.openecomp.core.validation.types.GlobalValidationContext;
18 import org.openecomp.sdc.datatypes.error.ErrorLevel;
19 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
20 import org.openecomp.sdc.heat.datatypes.model.Resource;
21 import org.openecomp.sdc.heat.services.HeatConstants;
22 import org.openecomp.sdc.heat.services.HeatResourceUtil;
23 import org.openecomp.sdc.heat.services.HeatStructureUtil;
24 import org.openecomp.sdc.validation.ResourceValidator;
25 import org.openecomp.sdc.validation.ValidationContext;
26 import org.openecomp.sdc.validation.type.NamingConventionValidationContext;
28 public class VirtualMachineInterfaceGuidelineValidator implements ResourceValidator {
29 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE1 = new ErrorMessageCode
31 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE2 = new ErrorMessageCode
33 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE3 = new ErrorMessageCode
38 public void validate(String fileName, Map.Entry<String, Resource> resourceEntry,
39 GlobalValidationContext globalContext, ValidationContext validationContext) {
40 NamingConventionValidationContext namingConventionValidationContext =
41 (NamingConventionValidationContext) validationContext;
42 Optional<Object> tagPropertyValue = getVlanTagPropertyValue(resourceEntry.getValue());
44 if (tagPropertyValue.isPresent()) {
45 validateModeledByResourceGroup(fileName, resourceEntry, globalContext,
46 namingConventionValidationContext);
47 validateSingleVirtualMachineInterfaceInFile(fileName, globalContext,
48 namingConventionValidationContext);
49 validateSubInterfaceNamingConvention(fileName, resourceEntry, globalContext);
53 private void validateModeledByResourceGroup(String fileName,
54 Map.Entry<String, Resource> resourceEntry,
55 GlobalValidationContext globalContext,
56 NamingConventionValidationContext namingConventionValidationContext) {
58 Object refsPropertyValue = resourceEntry.getValue().getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME);
59 if (Objects.isNull(refsPropertyValue)) {
60 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
61 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP, resourceEntry.getKey());
64 final boolean modeledThroughResourceGroup = isModeledThroughResourceGroup(fileName, globalContext,
65 namingConventionValidationContext, refsPropertyValue);
66 if (!modeledThroughResourceGroup) {
67 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
68 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP, resourceEntry.getKey());
74 private void validateSubInterfaceNamingConvention(String fileName, Map.Entry<String, Resource> resourceEntry,
75 GlobalValidationContext globalContext) {
76 final String resourceId = resourceEntry.getKey();
77 final Optional<String> networkRole = HeatResourceUtil.extractNetworkRoleFromSubInterfaceId(resourceId, resourceEntry
78 .getValue().getType());
79 if (!networkRole.isPresent()) {
80 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE3,
81 Messages.VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION, resourceId);
85 private void validateSingleVirtualMachineInterfaceInFile(String fileName,
86 GlobalValidationContext globalContext,
87 NamingConventionValidationContext
88 namingConventionValidationContext) {
89 Set<String> forbiddenTypes = Stream.of(NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
90 NEUTRON_PORT_RESOURCE_TYPE.getHeatResource()).collect(Collectors.toSet());
92 final Map<String, Resource> resources =
93 namingConventionValidationContext.getHeatOrchestrationTemplate().getResources();
95 if ((countVlanResources(resources) > 1) || fileContainsNonVlanResources(resources,
97 addViolationToContext(fileName, globalContext, ErrorLevel.ERROR, ERROR_CODE_VLAN_GUIDELINE2,
98 Messages.VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN, fileName);
104 private boolean fileContainsNonVlanResources(Map<String, Resource> resources,
105 Set<String> forbiddenTypes) {
106 for (Map.Entry<String, Resource> resourceEntry : resources.entrySet()) {
107 if (forbiddenTypes.contains(resourceEntry.getValue().getType())) {
114 private int countVlanResources(Map<String, Resource> resources) {
115 int numVlanResources = 0;
116 for (Map.Entry<String, Resource> resourceEntry : resources.entrySet()) {
117 final String resourceType = resourceEntry.getValue().getType();
118 if (resourceType.equals
119 (CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
124 return numVlanResources;
128 private void addViolationToContext(String fileName, GlobalValidationContext globalContext,
129 ErrorLevel error, ErrorMessageCode errorCodeVlanGuideline1,
130 Messages vlanGuidelineValidationNotModeledThroughResourceGroup,
132 globalContext.addMessage(fileName, error, ErrorMessagesFormatBuilder
133 .getErrorWithParameters(errorCodeVlanGuideline1,
134 vlanGuidelineValidationNotModeledThroughResourceGroup.getErrorMessage(),
139 private Optional<Object> getVlanTagPropertyValue(Resource resource) {
140 Object vmiProperties = resource.getProperties().get(HeatConstants.VMI_PROPERTIES_PROPERTY_NAME);
141 if (Objects.nonNull(vmiProperties) && vmiProperties instanceof Map) {
142 return Optional.ofNullable(((Map) vmiProperties)
143 .get(HeatConstants.VMI_SUB_INTERFACE_VLAN_TAG_PROPERTY_NAME));
145 return Optional.empty();
150 * This method verifies whether the propertyValue is a list containing a single get_param
151 * whose value is string
153 * @param fileName on which the validation is currently run
154 * @param globalContext global validation context
155 * @param namingConventionValidationContext heat resource validation context
156 * @param propertyValue the value which is examined
157 * @return whether the propertyValue is a list containing a single get_param
158 * whose value is string
160 private static boolean isModeledThroughResourceGroup(String fileName, GlobalValidationContext
161 globalContext, NamingConventionValidationContext namingConventionValidationContext,
162 Object propertyValue) {
163 final boolean isList = propertyValue instanceof List;
164 if (!isList || ((List) propertyValue).size() != 1) {
168 final Object listValue = ((List) propertyValue).get(0);
170 final Set<String> getParamValues =
171 HeatStructureUtil.getReferencedValuesByFunctionName(fileName, "get_param",
172 listValue, globalContext);
173 if (getParamValues.isEmpty()) {
174 return false; //this is not a get_param
177 //validating get_param value
178 return (getParamValues.size() == 1) &&
179 validateGetParamValueOfType(getParamValues, namingConventionValidationContext,
180 DefinedHeatParameterTypes.STRING.getType());
184 private static boolean validateGetParamValueOfType(Set<String> values,
185 NamingConventionValidationContext
186 namingConventionValidationContext,
189 return values.stream().anyMatch(e -> Objects.equals(
190 namingConventionValidationContext.getHeatOrchestrationTemplate().getParameters().get(e)
196 private enum Messages {
197 VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP("VLAN Resource will not be " +
198 "translated as the VLAN Sub-interface [%s] is not modeled as resource group"),
199 VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN("There should not be any Compute Server Node, Port, " +
200 "Parent Port in nested file [%s]"),
201 VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION(
202 "Network role associated with VLAN Sub-interface id[%s] is not following the naming convention");
204 private final String errorMessage;
206 Messages(String errorMessage) {
207 this.errorMessage = errorMessage;
210 String getErrorMessage() {