1 package org.openecomp.sdc.validation.impl.validators.namingconvention;
3 import static java.util.Objects.nonNull;
5 import org.apache.commons.collections4.MapUtils;
6 import org.apache.commons.lang3.tuple.ImmutablePair;
7 import org.apache.commons.lang3.tuple.Pair;
8 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
9 import org.openecomp.core.validation.types.GlobalValidationContext;
10 import org.openecomp.sdc.common.errors.Messages;
11 import org.openecomp.sdc.datatypes.error.ErrorLevel;
12 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
13 import org.openecomp.sdc.heat.datatypes.model.Environment;
14 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
15 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
16 import org.openecomp.sdc.heat.datatypes.model.Resource;
17 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
18 import org.openecomp.sdc.heat.services.HeatStructureUtil;
19 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
20 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
21 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
22 import org.openecomp.sdc.validation.ResourceValidator;
23 import org.openecomp.sdc.validation.ValidationContext;
24 import org.openecomp.sdc.validation.type.NamingConventionValidationContext;
25 import org.openecomp.sdc.validation.util.ValidationUtil;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.LinkedList;
33 import java.util.List;
35 import java.util.Objects;
36 import java.util.TreeMap;
38 public class NovaServerNamingConventionGuideLineValidator implements ResourceValidator {
39 private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
42 public void validate(String fileName, Map.Entry<String, Resource> resourceEntry,
43 GlobalValidationContext globalContext, ValidationContext validationContext) {
45 NamingConventionValidationContext namingConventionValidationContext =
46 (NamingConventionValidationContext)validationContext;
47 validateHeatNovaResource(fileName, namingConventionValidationContext.getEnvFileName(),
48 namingConventionValidationContext.getHeatOrchestrationTemplate(),
52 private void validateHeatNovaResource(String fileName, String envFileName,
53 HeatOrchestrationTemplate heatOrchestrationTemplate,
54 GlobalValidationContext globalContext) {
57 mdcDataDebugMessage.debugEntryMessage("file", fileName);
59 Map<String, String> uniqueResourcePortNetworkRole = new HashMap<>();
60 //if no resources exist return
61 if (MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
65 heatOrchestrationTemplate
69 .filter(entry -> entry.getValue().getType()
70 .equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource()))
71 .forEach( entry -> validateNovaServerResourceType(entry.getKey(), fileName, envFileName,
72 entry, uniqueResourcePortNetworkRole, heatOrchestrationTemplate, globalContext));
74 mdcDataDebugMessage.debugExitMessage("file", fileName);
77 private void validateNovaServerResourceType(String resourceId, String fileName,
79 Map.Entry<String, Resource> resourceEntry,
80 Map<String, String> uniqueResourcePortNetworkRole,
81 HeatOrchestrationTemplate heatOrchestrationTemplate,
82 GlobalValidationContext globalContext) {
84 mdcDataDebugMessage.debugEntryMessage("file", fileName);
86 validateNovaServerResourceMetaData(fileName, resourceId,
87 heatOrchestrationTemplate.getResources().get(resourceId), globalContext);
88 validateNovaServerResourceNetworkUniqueRole(fileName, resourceId, uniqueResourcePortNetworkRole,
89 heatOrchestrationTemplate, globalContext);
90 validateAvailabilityZoneName(fileName, resourceEntry, globalContext);
91 validateNovaServerNameImageAndFlavor(fileName, envFileName, resourceEntry, globalContext);
93 mdcDataDebugMessage.debugExitMessage("file", fileName);
96 @SuppressWarnings("unchecked")
97 private void validateNovaServerResourceMetaData(String fileName, String resourceId,
99 GlobalValidationContext globalValidationContext) {
101 mdcDataDebugMessage.debugEntryMessage("file", fileName);
103 Map<String, Object> novaServerProp = resource.getProperties();
104 Object novaServerPropMetadata;
105 if (MapUtils.isNotEmpty(novaServerProp)) {
106 novaServerPropMetadata = novaServerProp.get("metadata");
107 if (novaServerPropMetadata == null) {
108 globalValidationContext.addMessage(
111 ErrorMessagesFormatBuilder
112 .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_METADATA.getErrorMessage(),
114 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
115 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
116 } else if (novaServerPropMetadata instanceof Map) {
117 TreeMap<String, Object> propertyMap = new TreeMap(new Comparator<String>() {
120 public int compare(String o1, String o2) {
121 return o1.compareToIgnoreCase(o2);
125 public boolean equals(Object obj) {
130 public int hashCode() {
131 return super.hashCode();
134 propertyMap.putAll((Map) novaServerPropMetadata);
135 if (!propertyMap.containsKey("vf_module_id")) {
136 globalValidationContext.addMessage(
139 ErrorMessagesFormatBuilder.getErrorWithParameters(
140 Messages.MISSING_NOVA_SERVER_VF_MODULE_ID.getErrorMessage(), resourceId),
141 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
142 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
144 if (!propertyMap.containsKey("vnf_id")) {
145 globalValidationContext.addMessage(
146 fileName, ErrorLevel.WARNING,
147 ErrorMessagesFormatBuilder
148 .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_VNF_ID.getErrorMessage(),
150 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
151 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
156 mdcDataDebugMessage.debugExitMessage("file", fileName);
159 private void validateNovaServerResourceNetworkUniqueRole(String fileName, String resourceId,
160 Map<String, String> uniqueResourcePortNetworkRole,
161 HeatOrchestrationTemplate heatOrchestrationTemplate,
162 GlobalValidationContext globalValidationContext) {
165 mdcDataDebugMessage.debugEntryMessage("file", fileName);
170 Object propertyNetworkValue =
171 heatOrchestrationTemplate.getResources().get(resourceId).getProperties().get("networks");
172 if (propertyNetworkValue != null && propertyNetworkValue instanceof List) {
173 List<String> portResourceIdList =
174 getNovaNetworkPortResourceList(fileName, (List) propertyNetworkValue,
175 globalValidationContext);
176 for (String portResourceId : portResourceIdList) {
177 Resource portResource = heatOrchestrationTemplate.getResources().get(portResourceId);
178 if (portResource != null && portResource.getType()
179 .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
181 getPortNetwork(fileName, resourceId, portResource, globalValidationContext);
182 if (Objects.nonNull(portNetwork)) {
183 network = portNetwork.get("get_param");
184 if (Objects.nonNull(network)) {
185 if (network instanceof String ){
186 role = getNetworkRole((String)network);
187 }else if (network instanceof List){
188 role = getNetworkRole((String)((List) network).get(0));
190 if (role != null && uniqueResourcePortNetworkRole.containsKey(role)) {
191 globalValidationContext.addMessage(
194 ErrorMessagesFormatBuilder.getErrorWithParameters(
195 Messages.RESOURCE_CONNECTED_TO_TWO_EXTERNAL_NETWORKS_WITH_SAME_ROLE
196 .getErrorMessage(), resourceId, role),
197 LoggerTragetServiceName.VALIDATE_RESOURCE_NETWORK_UNIQUE_ROLW,
198 LoggerErrorDescription.RESOURCE_UNIQUE_NETWORK_ROLE);
200 uniqueResourcePortNetworkRole.put(role, portResourceId);
208 mdcDataDebugMessage.debugExitMessage("file", fileName);
211 private List<String> getNovaNetworkPortResourceList(String filename, List propertyNetworkValue,
212 GlobalValidationContext globalContext) {
213 List<String> portResourceIdList = new ArrayList<>();
214 for (Object propValue : propertyNetworkValue) {
215 Object portPropValue = ((Map) propValue).get("port");
216 Collection<String> portResourceIds = HeatStructureUtil
217 .getReferencedValuesByFunctionName(filename, "get_resource", portPropValue,
219 if (portResourceIds != null) {
220 portResourceIdList.addAll(portResourceIds);
224 return portResourceIdList;
227 private String getNetworkRole(String network) {
228 if (network == null) {
231 if (network.contains("_net_id")) {
232 return network.substring(0, network.indexOf("_net_id"));
233 } else if (network.contains("_net_name")) {
234 return network.substring(0, network.indexOf("_net_name"));
235 } else if (network.contains("_net_fqdn")) {
236 return network.substring(0, network.indexOf("_net_fqdn"));
241 private Map getPortNetwork(String fileName, String resourceId, Resource portResource,
242 GlobalValidationContext globalValidationContext) {
243 Object portNetwork = portResource.getProperties().get("network_id");
244 if (portNetwork == null) {
245 portNetwork = portResource.getProperties().get("network");
247 if (!(portNetwork instanceof Map)) {
248 globalValidationContext.addMessage(
251 ErrorMessagesFormatBuilder
252 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
253 "network or network_id", resourceId),
254 LoggerTragetServiceName.VALIDATE_RESOURCE_NETWORK_UNIQUE_ROLW,
255 LoggerErrorDescription.MISSING_GET_PARAM);
258 return (Map) portNetwork;
261 private void validateAvailabilityZoneName(String fileName,
262 Map.Entry<String, Resource> resourceEntry,
263 GlobalValidationContext globalContext) {
266 mdcDataDebugMessage.debugEntryMessage("file", fileName);
268 String[] regexList = new String[]{"availability_zone_(\\d+)"};
270 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
271 mdcDataDebugMessage.debugExitMessage("file", fileName);
275 Object availabilityZoneMap =
276 resourceEntry.getValue().getProperties().containsKey("availability_zone") ? resourceEntry
277 .getValue().getProperties().get("availability_zone") : null;
279 if (nonNull(availabilityZoneMap)) {
280 if (availabilityZoneMap instanceof Map) {
281 String availabilityZoneName = ValidationUtil.getWantedNameFromPropertyValueGetParam
282 (availabilityZoneMap);
284 if (availabilityZoneName != null) {
285 if (!ValidationUtil.evalPattern(availabilityZoneName, regexList)) {
286 globalContext.addMessage(
288 ErrorLevel.WARNING, ErrorMessagesFormatBuilder.getErrorWithParameters(
289 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(),
290 ValidationUtil.getMessagePartAccordingToResourceType(resourceEntry),
292 availabilityZoneName, resourceEntry.getKey()),
293 LoggerTragetServiceName.VALIDATE_AVAILABILITY_ZONE_NAME,
294 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
298 globalContext.addMessage(
300 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
301 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
302 "availability_zone", resourceEntry.getKey()),
303 LoggerTragetServiceName.VALIDATE_AVAILABILITY_ZONE_NAME,
304 LoggerErrorDescription.MISSING_GET_PARAM);
307 mdcDataDebugMessage.debugExitMessage("file", fileName);
310 private void validateNovaServerNameImageAndFlavor(String fileName, String envFileName,
311 Map.Entry<String, Resource> resourceEntry,
312 GlobalValidationContext globalContext) {
314 mdcDataDebugMessage.debugEntryMessage("file", fileName);
317 validateNovaServerNamingConvention(fileName, envFileName, resourceEntry, globalContext);
318 Map<String, String> legalNovaNamingConventionMap =
319 validateImageAndFlavorFromNovaServer(fileName, resourceEntry, globalContext);
321 if (Objects.nonNull(novaName)) {
322 legalNovaNamingConventionMap.put("name", novaName);
325 if (legalNovaNamingConventionMap.keySet().size() > 1) {
326 validateNovaServerNameImageAndFlavorSync(fileName, resourceEntry,
327 legalNovaNamingConventionMap, globalContext);
330 mdcDataDebugMessage.debugExitMessage("file", fileName);
333 private String validateNovaServerNamingConvention(String fileName, String envFileName,
334 Map.Entry<String, Resource> resourceEntry,
335 GlobalValidationContext globalContext) {
337 mdcDataDebugMessage.debugEntryMessage("file", fileName);
339 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
340 mdcDataDebugMessage.debugExitMessage("file", fileName);
344 mdcDataDebugMessage.debugExitMessage("file", fileName);
345 return checkIfNovaNameByGuidelines(fileName, envFileName, resourceEntry, globalContext);
348 private Map<String, String> validateImageAndFlavorFromNovaServer(String fileName,
349 Map.Entry<String, Resource> resourceEntry,
350 GlobalValidationContext globalContext) {
352 mdcDataDebugMessage.debugEntryMessage("file", fileName);
354 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
355 mdcDataDebugMessage.debugExitMessage("file", fileName);
359 Pair<String, String> imagePair = new ImmutablePair<>("image", ".*_image_name");
360 Pair<String, String> flavorPair = new ImmutablePair<>("flavor", ".*_flavor_name");
361 List<Pair<String, String>> imageFlavorPairs = Arrays.asList(imagePair, flavorPair);
362 Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
363 Map<String, String> imageAndFlavorLegalNames = new HashMap<>();
365 for (Pair<String, String> imageOrFlavor : imageFlavorPairs) {
366 boolean isErrorInImageOrFlavor =
367 isErrorExistWhenValidatingImageOrFlavorNames(fileName, imageOrFlavor, resourceEntry,
368 propertiesMap, globalContext);
369 if (!isErrorInImageOrFlavor) {
370 Object nameValue = propertiesMap.get(imageOrFlavor.getKey()) == null ? null
371 : propertiesMap.get(imageOrFlavor.getKey());
372 String imageOrFlavorName = ValidationUtil.getWantedNameFromPropertyValueGetParam(nameValue);
373 imageAndFlavorLegalNames.put(imageOrFlavor.getKey(), imageOrFlavorName);
377 mdcDataDebugMessage.debugExitMessage("file", fileName);
378 return imageAndFlavorLegalNames;
381 private String checkIfNovaNameByGuidelines(String fileName, String envFileName,
382 Map.Entry<String, Resource> resourceEntry,
383 GlobalValidationContext globalContext) {
384 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
387 Object novaNameGetParam = getNovaServerName(resourceEntry);
388 String novaName = null;
389 if (nonNull(novaNameGetParam)) {
391 checkNovaNameGetParamValueMap(fileName, novaNameGetParam, resourceEntry, globalContext);
392 checkIfNovaNameParameterInEnvIsStringOrList(fileName, envFileName, resourceEntry, novaName,
395 globalContext.addMessage(
397 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
398 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
399 "nova server name", resourceEntry.getKey()),
400 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
401 LoggerErrorDescription.MISSING_GET_PARAM);
407 private boolean isErrorExistWhenValidatingImageOrFlavorNames(String fileName,
408 Pair<String, String> propertyNameAndRegex,
409 Map.Entry<String, Resource> resourceEntry,
410 Map<String, Object> propertiesMap,
411 GlobalValidationContext globalContext) {
412 String propertyName = propertyNameAndRegex.getKey();
414 propertiesMap.get(propertyName) == null ? null : propertiesMap.get(propertyName);
415 String[] regexList = new String[]{propertyNameAndRegex.getValue()};
417 if (nonNull(nameValue)) {
418 if (nameValue instanceof Map) {
419 if (ValidationUtil.validateMapPropertyValue(fileName, resourceEntry, globalContext,
421 nameValue, regexList)) {
425 globalContext.addMessage(
427 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
428 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(), propertyName,
429 resourceEntry.getKey()),
430 LoggerTragetServiceName.VALIDATE_IMAGE_AND_FLAVOR_NAME,
431 LoggerErrorDescription.MISSING_GET_PARAM);
440 private Object getNovaServerName(Map.Entry<String, Resource> resourceEntry) {
441 Object novaServerName = resourceEntry.getValue().getProperties().get("name");
443 if (nonNull(novaServerName)) {
444 if (novaServerName instanceof Map) {
445 novaNameMap = (Map) novaServerName;
446 return novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction()) == null ? null
447 : novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction());
453 @SuppressWarnings("unchecked")
454 private String checkNovaNameGetParamValueMap(String fileName, Object getParamValue,
455 Map.Entry<String, Resource> resourceEntry,
456 GlobalValidationContext globalContext) {
457 if (getParamValue instanceof List) {
458 List<Object> getParamNameList = (List) getParamValue;
459 String[] regexName = new String[]{".*_names"};
460 return isNovaNameAsListLegal(fileName, getParamNameList, regexName, resourceEntry,
462 } else if (getParamValue instanceof String) {
463 String[] regexName = new String[]{".*_name_(\\d+)"};
464 return isNovaNameAsStringLegal(fileName, (String) getParamValue, regexName, resourceEntry,
471 private void checkIfNovaNameParameterInEnvIsStringOrList(String fileName, String envFileName,
472 Map.Entry<String, Resource> resourceEntry,
473 String novaServerName,
474 GlobalValidationContext globalContext) {
475 if (nonNull(envFileName)) {
476 Environment environment = ValidationUtil.validateEnvContent(envFileName, globalContext);
478 if (environment != null && MapUtils.isNotEmpty(environment.getParameters())) {
479 Object novaServerNameEnvValue =
480 environment.getParameters().containsKey(novaServerName) ? environment.getParameters()
481 .get(novaServerName) : null;
482 if (Objects.nonNull(novaServerNameEnvValue)) {
483 if (!DefinedHeatParameterTypes
484 .isNovaServerEnvValueIsFromRightType(novaServerNameEnvValue)) {
485 globalContext.addMessage(
487 ErrorLevel.WARNING, ErrorMessagesFormatBuilder.getErrorWithParameters(
488 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
489 "Name", novaServerNameEnvValue.toString(), resourceEntry.getKey()),
490 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
491 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
498 private String isNovaNameAsListLegal(String fileName, List<Object> getParamNameList,
500 Map.Entry<String, Resource> resourceEntry,
501 GlobalValidationContext globalContext) {
503 if (getParamNameList.size() != 2 || !ValidationUtil.evalPattern(getParamNameList.get(0),
505 globalContext.addMessage(
508 ErrorMessagesFormatBuilder.getErrorWithParameters(
509 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
510 "name", getParamNameList.toString(), resourceEntry.getKey()),
511 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
512 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
516 return (String) getParamNameList.get(0);
519 private String isNovaNameAsStringLegal(String fileName, String novaName, String[] regexName,
520 Map.Entry<String, Resource> resourceEntry,
521 GlobalValidationContext globalContext) {
522 if (!ValidationUtil.evalPattern(novaName, regexName)) {
523 globalContext.addMessage(
526 ErrorMessagesFormatBuilder.getErrorWithParameters(
527 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
528 "name", novaName, resourceEntry.getKey()),
529 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
530 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
536 private void validateNovaServerNameImageAndFlavorSync(String fileName,
537 Map.Entry<String, Resource> resourceEntry,
538 Map<String, String> legalNovaNamingConventionNames,
539 GlobalValidationContext globalContext) {
541 mdcDataDebugMessage.debugEntryMessage("file", fileName);
543 List<String> vmNames = new LinkedList<>();
545 for (Map.Entry<String, String> nameEntry : legalNovaNamingConventionNames.entrySet()) {
546 vmNames.add(getVmName(nameEntry.getValue(), nameEntry.getKey()));
549 vmNames.removeIf(VMName -> VMName == null);
551 if (!isVmNameSync(vmNames)) {
552 globalContext.addMessage(
555 ErrorMessagesFormatBuilder.getErrorWithParameters(
556 Messages.NOVA_NAME_IMAGE_FLAVOR_NOT_CONSISTENT.getErrorMessage(),
557 resourceEntry.getKey()),
558 LoggerTragetServiceName.VALIDATE_IMAGE_AND_FLAVOR_NAME,
559 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
561 mdcDataDebugMessage.debugExitMessage("file", fileName);
564 private String getVmName(String nameToGetVmNameFrom, String stringToGetIndexOf) {
566 nameToGetVmNameFrom == null ? -1 : nameToGetVmNameFrom.indexOf(stringToGetIndexOf);
567 String vmName = vmIndex < 0 ? null
568 : trimNonAlphaNumericCharactersFromEndOfString(nameToGetVmNameFrom.substring(0, vmIndex));
574 private boolean isVmNameSync(List<String> namesToCompare) {
575 int size = namesToCompare.size();
576 for (int i = 0; i < size - 1; i++) {
577 if (!namesToCompare.get(i).equals(namesToCompare.get(i + 1))) {
584 private String trimNonAlphaNumericCharactersFromEndOfString(String toTrim) {
585 int stringSize = toTrim.length();
586 int stringLength = stringSize - 1;
587 String[] regexList = new String[]{"[^a-zA-Z0-9]"};
589 while (stringLength >= 0) {
590 if (!ValidationUtil.evalPattern(String.valueOf(toTrim.charAt(stringLength)), regexList)) {
596 return toTrim.substring(0, stringLength + 1);