1 package org.openecomp.sdc.validation.impl.validators.namingconvention;
3 import org.openecomp.core.validation.ErrorMessageCode;
4 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
5 import org.openecomp.core.validation.types.GlobalValidationContext;
6 import org.openecomp.sdc.common.togglz.ToggleableFeature;
7 import org.openecomp.sdc.datatypes.error.ErrorLevel;
8 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
9 import org.openecomp.sdc.heat.datatypes.model.Resource;
10 import org.openecomp.sdc.heat.services.HeatConstants;
11 import org.openecomp.sdc.heat.services.HeatStructureUtil;
12 import org.openecomp.sdc.validation.ResourceValidator;
13 import org.openecomp.sdc.validation.ValidationContext;
14 import org.openecomp.sdc.validation.type.NamingConventionValidationContext;
16 import java.util.Arrays;
17 import java.util.List;
19 import java.util.Objects;
20 import java.util.Optional;
22 import java.util.stream.Collectors;
23 import java.util.stream.Stream;
25 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE;
26 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE;
27 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE;
31 * @since February 05, 2018
34 public class VirtualMachineInterfaceGuidelineValidator implements ResourceValidator {
35 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE1 = new ErrorMessageCode
37 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE2 = new ErrorMessageCode
39 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE3 = new ErrorMessageCode
41 private static final String UNDERSCORE = "_";
42 private static final String VMI = "vmi";
46 public void validate(String fileName, Map.Entry<String, Resource> resourceEntry,
47 GlobalValidationContext globalContext, ValidationContext validationContext) {
48 if (ToggleableFeature.VLAN_TAGGING.isActive()) {
49 NamingConventionValidationContext namingConventionValidationContext =
50 (NamingConventionValidationContext) validationContext;
51 Optional<Object> tagPropertyValue = getVlanTagPropertyValue(resourceEntry.getValue());
53 if (tagPropertyValue.isPresent()) {
54 validateModeledByResourceGroup(fileName, resourceEntry, globalContext,
55 namingConventionValidationContext);
56 validateSingleVirtualMachineInterfaceInFile(fileName, globalContext,
57 namingConventionValidationContext);
58 validateNamingConvention(fileName, resourceEntry, globalContext
65 private void validateModeledByResourceGroup(String fileName,
66 Map.Entry<String, Resource> resourceEntry,
67 GlobalValidationContext globalContext,
68 NamingConventionValidationContext namingConventionValidationContext) {
70 Object refsPropertyValue = resourceEntry.getValue().getProperties()
71 .get(HeatConstants.VMI_REFS_PROPERTY_NAME);
72 if (Objects.isNull(refsPropertyValue)) {
73 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
74 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP,
75 resourceEntry.getKey());
78 final boolean modeledThroughResourceGroup =
79 isModeledThroughResourceGroup(fileName, globalContext,
80 namingConventionValidationContext,
82 if (!modeledThroughResourceGroup) {
83 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
84 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP,
85 resourceEntry.getKey());
91 private void validateNamingConvention(String fileName, Map.Entry<String, Resource>
92 resourceEntry, GlobalValidationContext globalContext) {
93 final String resourceId = resourceEntry.getKey();
94 final String networkRole = extractNetworkRoleFromResourceId(resourceId);
95 if (Objects.isNull(networkRole)) {
96 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE3,
97 Messages.VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION, resourceId);
101 private void validateSingleVirtualMachineInterfaceInFile(String fileName,
102 GlobalValidationContext globalContext,
103 NamingConventionValidationContext
104 namingConventionValidationContext) {
105 Set<String> forbiddenTypes = Stream.of(NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
106 NEUTRON_PORT_RESOURCE_TYPE.getHeatResource()).collect(Collectors.toSet());
108 final Map<String, Resource> resources =
109 namingConventionValidationContext.getHeatOrchestrationTemplate().getResources();
111 if ((countVlanResources(resources) > 1) || fileContainsNonVlanResources(resources,
113 addViolationToContext(fileName, globalContext, ErrorLevel.ERROR, ERROR_CODE_VLAN_GUIDELINE2,
114 Messages.VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN, fileName);
120 private boolean fileContainsNonVlanResources(Map<String, Resource> resources,
121 Set<String> forbiddenTypes) {
122 for (String resourceName : resources.keySet()) {
123 if (forbiddenTypes.contains(resources.get(resourceName).getType())) {
130 private int countVlanResources(Map<String, Resource> resources) {
131 int numVlanResources = 0;
132 for (String resourceName : resources.keySet()) {
133 final String resourceType = resources.get(resourceName).getType();
134 if (resourceType.equals
135 (CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
140 return numVlanResources;
144 private void addViolationToContext(String fileName, GlobalValidationContext globalContext,
145 ErrorLevel error, ErrorMessageCode errorCodeVlanGuideline1,
146 Messages vlanGuidelineValidationNotModeledThroughResourceGroup,
148 globalContext.addMessage(fileName, error, ErrorMessagesFormatBuilder
149 .getErrorWithParameters(errorCodeVlanGuideline1,
150 vlanGuidelineValidationNotModeledThroughResourceGroup.getErrorMessage(),
155 private Optional<Object> getVlanTagPropertyValue(Resource resource) {
156 Object vmiProperties = resource.getProperties()
157 .get(HeatConstants.VMI_PROPERTIES_PROPERTY_NAME);
158 if (Objects.nonNull(vmiProperties) && vmiProperties instanceof Map) {
159 return Optional.ofNullable(((Map) vmiProperties)
160 .get(HeatConstants.VMI_SUB_INTERFACE_VLAN_TAG_PROPERTY_NAME));
162 return Optional.empty();
167 * This method verifies whether the propertyValue is a list containing a single get_param
168 * whose value is string
170 * @param fileName on which the validation is currently run
171 * @param globalContext global validation context
172 * @param namingConventionValidationContext heat resource validation context
173 * @param propertyValue the value which is examined
174 * @return whether the propertyValue is a list containing a single get_param
175 * whose value is string
177 private static boolean isModeledThroughResourceGroup(String fileName, GlobalValidationContext
178 globalContext, NamingConventionValidationContext namingConventionValidationContext,
179 Object propertyValue) {
180 final boolean isList = propertyValue instanceof List;
181 if (!isList || ((List) propertyValue).size() != 1) {
185 final Object listValue = ((List) propertyValue).get(0);
187 final Set<String> getParamValues =
188 HeatStructureUtil.getReferencedValuesByFunctionName(fileName, "get_param",
189 listValue, globalContext);
190 if (getParamValues.isEmpty()) {
191 return false; //this is not a get_param
194 //validating get_param value
195 return (getParamValues.size() == 1) &&
196 validateGetParamValueOfType(getParamValues, namingConventionValidationContext,
197 DefinedHeatParameterTypes.STRING.getType());
201 private static boolean validateGetParamValueOfType(Set<String> values,
202 NamingConventionValidationContext
203 namingConventionValidationContext,
206 return values.stream().anyMatch(e -> Objects.equals(
207 namingConventionValidationContext.getHeatOrchestrationTemplate().getParameters().get(e)
212 private static String extractNetworkRoleFromResourceId(String resourceId) {
214 List<String> splitSubInterfaceResourceId =
215 Arrays.asList(resourceId.toLowerCase().split(UNDERSCORE));
217 int vmiIndex = splitSubInterfaceResourceId.indexOf(VMI);
219 return splitSubInterfaceResourceId.get(vmiIndex - 1);
226 private enum Messages {
227 VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP("VLAN Resource will not be " +
228 "translated as the VLAN Sub-interface [%s] is not modeled as resource group"),
229 VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN("There should not be any Compute Server Node, Port, " +
230 "Parent Port in nested file [%s]"),
231 VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION(
232 "Network role associated with VLAN Sub-interface " +
234 "[%s] is not following the naming convention");
236 private final String errorMessage;
238 Messages(String errorMessage) {
239 this.errorMessage = errorMessage;
242 String getErrorMessage() {