2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.validation.impl.validators.namingconvention;
22 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE;
23 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE;
24 import static org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE;
26 import java.util.List;
28 import java.util.Objects;
29 import java.util.Optional;
31 import java.util.stream.Collectors;
32 import java.util.stream.Stream;
34 import org.openecomp.core.validation.ErrorMessageCode;
35 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
36 import org.openecomp.core.validation.types.GlobalValidationContext;
37 import org.openecomp.sdc.datatypes.error.ErrorLevel;
38 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
39 import org.openecomp.sdc.heat.datatypes.model.Resource;
40 import org.openecomp.sdc.heat.services.HeatConstants;
41 import org.openecomp.sdc.heat.services.HeatResourceUtil;
42 import org.openecomp.sdc.heat.services.HeatStructureUtil;
43 import org.openecomp.sdc.validation.ResourceValidator;
44 import org.openecomp.sdc.validation.ValidationContext;
45 import org.openecomp.sdc.validation.type.NamingConventionValidationContext;
47 public class VirtualMachineInterfaceGuidelineValidator implements ResourceValidator {
48 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE1 = new ErrorMessageCode
50 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE2 = new ErrorMessageCode
52 private static final ErrorMessageCode ERROR_CODE_VLAN_GUIDELINE3 = new ErrorMessageCode
57 public void validate(String fileName, Map.Entry<String, Resource> resourceEntry,
58 GlobalValidationContext globalContext, ValidationContext validationContext) {
59 NamingConventionValidationContext namingConventionValidationContext =
60 (NamingConventionValidationContext) validationContext;
61 Optional<Object> tagPropertyValue = getVlanTagPropertyValue(resourceEntry.getValue());
63 if (tagPropertyValue.isPresent()) {
64 validateModeledByResourceGroup(fileName, resourceEntry, globalContext,
65 namingConventionValidationContext);
66 validateSingleVirtualMachineInterfaceInFile(fileName, globalContext,
67 namingConventionValidationContext);
68 validateSubInterfaceNamingConvention(fileName, resourceEntry, globalContext);
72 private void validateModeledByResourceGroup(String fileName,
73 Map.Entry<String, Resource> resourceEntry,
74 GlobalValidationContext globalContext,
75 NamingConventionValidationContext namingConventionValidationContext) {
77 Object refsPropertyValue = resourceEntry.getValue().getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME);
78 if (Objects.isNull(refsPropertyValue)) {
79 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
80 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP, resourceEntry.getKey());
83 final boolean modeledThroughResourceGroup = isModeledThroughResourceGroup(fileName, globalContext,
84 namingConventionValidationContext, refsPropertyValue);
85 if (!modeledThroughResourceGroup) {
86 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE1,
87 Messages.VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP, resourceEntry.getKey());
93 private void validateSubInterfaceNamingConvention(String fileName, Map.Entry<String, Resource> resourceEntry,
94 GlobalValidationContext globalContext) {
95 final String resourceId = resourceEntry.getKey();
96 final Optional<String> networkRole = HeatResourceUtil.extractNetworkRoleFromSubInterfaceId(resourceId, resourceEntry
97 .getValue().getType());
98 if (!networkRole.isPresent()) {
99 addViolationToContext(fileName, globalContext, ErrorLevel.WARNING, ERROR_CODE_VLAN_GUIDELINE3,
100 Messages.VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION, resourceId);
104 private void validateSingleVirtualMachineInterfaceInFile(String fileName,
105 GlobalValidationContext globalContext,
106 NamingConventionValidationContext
107 namingConventionValidationContext) {
108 Set<String> forbiddenTypes = Stream.of(NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
109 NEUTRON_PORT_RESOURCE_TYPE.getHeatResource()).collect(Collectors.toSet());
111 final Map<String, Resource> resources =
112 namingConventionValidationContext.getHeatOrchestrationTemplate().getResources();
114 if ((countVlanResources(resources) > 1) || fileContainsNonVlanResources(resources,
116 addViolationToContext(fileName, globalContext, ErrorLevel.ERROR, ERROR_CODE_VLAN_GUIDELINE2,
117 Messages.VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN, fileName);
123 private boolean fileContainsNonVlanResources(Map<String, Resource> resources,
124 Set<String> forbiddenTypes) {
125 for (Map.Entry<String, Resource> resourceEntry : resources.entrySet()) {
126 if (forbiddenTypes.contains(resourceEntry.getValue().getType())) {
133 private int countVlanResources(Map<String, Resource> resources) {
134 int numVlanResources = 0;
135 for (Map.Entry<String, Resource> resourceEntry : resources.entrySet()) {
136 final String resourceType = resourceEntry.getValue().getType();
137 if (resourceType.equals
138 (CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
143 return numVlanResources;
147 private void addViolationToContext(String fileName, GlobalValidationContext globalContext,
148 ErrorLevel error, ErrorMessageCode errorCodeVlanGuideline1,
149 Messages vlanGuidelineValidationNotModeledThroughResourceGroup,
151 globalContext.addMessage(fileName, error, ErrorMessagesFormatBuilder
152 .getErrorWithParameters(errorCodeVlanGuideline1,
153 vlanGuidelineValidationNotModeledThroughResourceGroup.getErrorMessage(),
158 private Optional<Object> getVlanTagPropertyValue(Resource resource) {
159 Object vmiProperties = resource.getProperties().get(HeatConstants.VMI_PROPERTIES_PROPERTY_NAME);
160 if (Objects.nonNull(vmiProperties) && vmiProperties instanceof Map) {
161 return Optional.ofNullable(((Map) vmiProperties)
162 .get(HeatConstants.VMI_SUB_INTERFACE_VLAN_TAG_PROPERTY_NAME));
164 return Optional.empty();
169 * This method verifies whether the propertyValue is a list containing a single get_param
170 * whose value is string
172 * @param fileName on which the validation is currently run
173 * @param globalContext global validation context
174 * @param namingConventionValidationContext heat resource validation context
175 * @param propertyValue the value which is examined
176 * @return whether the propertyValue is a list containing a single get_param
177 * whose value is string
179 private static boolean isModeledThroughResourceGroup(String fileName, GlobalValidationContext
180 globalContext, NamingConventionValidationContext namingConventionValidationContext,
181 Object propertyValue) {
182 final boolean isList = propertyValue instanceof List;
183 if (!isList || ((List) propertyValue).size() != 1) {
187 final Object listValue = ((List) propertyValue).get(0);
189 final Set<String> getParamValues =
190 HeatStructureUtil.getReferencedValuesByFunctionName(fileName, "get_param",
191 listValue, globalContext);
192 if (getParamValues.isEmpty()) {
193 return false; //this is not a get_param
196 //validating get_param value
197 return (getParamValues.size() == 1) &&
198 validateGetParamValueOfType(getParamValues, namingConventionValidationContext,
199 DefinedHeatParameterTypes.STRING.getType());
203 private static boolean validateGetParamValueOfType(Set<String> values,
204 NamingConventionValidationContext
205 namingConventionValidationContext,
208 return values.stream().anyMatch(e -> Objects.equals(
209 namingConventionValidationContext.getHeatOrchestrationTemplate().getParameters().get(e)
215 private enum Messages {
216 VLAN_GUIDELINE_VALIDATION_NOT_MODELED_THROUGH_RESOURCE_GROUP("VLAN Resource will not be " +
217 "translated as the VLAN Sub-interface [%s] is not modeled as resource group"),
218 VLAN_GUIDELINE_VALIDATION_SINGLE_VLAN("There should not be any Compute Server Node, Port, " +
219 "Parent Port in nested file [%s]"),
220 VLAN_GUIDELINE_VALIDATION_NAMING_CONVENTION(
221 "Network role associated with VLAN Sub-interface id[%s] is not following the naming convention");
223 private final String errorMessage;
225 Messages(String errorMessage) {
226 this.errorMessage = errorMessage;
229 String getErrorMessage() {