1 package org.openecomp.sdc.validation.impl.validators.namingconvention;
3 import org.apache.commons.collections4.MapUtils;
4 import org.apache.commons.lang3.tuple.ImmutablePair;
5 import org.apache.commons.lang3.tuple.Pair;
6 import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder;
7 import org.openecomp.core.validation.types.GlobalValidationContext;
8 import org.openecomp.sdc.common.errors.Messages;
9 import org.openecomp.sdc.datatypes.error.ErrorLevel;
10 import org.openecomp.sdc.heat.datatypes.DefinedHeatParameterTypes;
11 import org.openecomp.sdc.heat.datatypes.model.Environment;
12 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
13 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
14 import org.openecomp.sdc.heat.datatypes.model.Resource;
15 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
16 import org.openecomp.sdc.heat.services.HeatStructureUtil;
17 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
18 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
19 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
20 import org.openecomp.sdc.validation.ResourceValidator;
21 import org.openecomp.sdc.validation.ValidationContext;
22 import org.openecomp.sdc.validation.type.NamingConventionValidationContext;
23 import org.openecomp.sdc.validation.util.ValidationUtil;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.Comparator;
29 import java.util.HashMap;
30 import java.util.LinkedList;
31 import java.util.List;
33 import java.util.Objects;
34 import java.util.TreeMap;
36 import static java.util.Objects.nonNull;
39 * Created by TALIO on 2/23/2017.
41 public class NovaServerNamingConventionGuideLineValidator implements ResourceValidator {
42 private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
45 public void validate(String fileName, Map.Entry<String, Resource> resourceEntry,
46 GlobalValidationContext globalContext, ValidationContext validationContext) {
48 NamingConventionValidationContext namingConventionValidationContext =
49 (NamingConventionValidationContext)validationContext;
50 validateHeatNovaResource(fileName, namingConventionValidationContext.getEnvFileName(),
51 namingConventionValidationContext.getHeatOrchestrationTemplate(),
55 private void validateHeatNovaResource(String fileName, String envFileName,
56 HeatOrchestrationTemplate heatOrchestrationTemplate,
57 GlobalValidationContext globalContext) {
60 mdcDataDebugMessage.debugEntryMessage("file", fileName);
62 Map<String, String> uniqueResourcePortNetworkRole = new HashMap<>();
63 //if no resources exist return
64 if (MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
68 heatOrchestrationTemplate
72 .filter(entry -> entry.getValue().getType()
73 .equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource()))
74 .forEach( entry -> validateNovaServerResourceType(entry.getKey(), fileName, envFileName,
75 entry, uniqueResourcePortNetworkRole, heatOrchestrationTemplate, globalContext));
77 mdcDataDebugMessage.debugExitMessage("file", fileName);
80 private void validateNovaServerResourceType(String resourceId, String fileName,
82 Map.Entry<String, Resource> resourceEntry,
83 Map<String, String> uniqueResourcePortNetworkRole,
84 HeatOrchestrationTemplate heatOrchestrationTemplate,
85 GlobalValidationContext globalContext) {
87 mdcDataDebugMessage.debugEntryMessage("file", fileName);
89 validateNovaServerResourceMetaData(fileName, resourceId,
90 heatOrchestrationTemplate.getResources().get(resourceId), globalContext);
91 validateNovaServerResourceNetworkUniqueRole(fileName, resourceId, uniqueResourcePortNetworkRole,
92 heatOrchestrationTemplate, globalContext);
93 validateAvailabilityZoneName(fileName, resourceEntry, globalContext);
94 validateNovaServerNameImageAndFlavor(fileName, envFileName, resourceEntry, globalContext);
96 mdcDataDebugMessage.debugExitMessage("file", fileName);
99 @SuppressWarnings("unchecked")
100 private void validateNovaServerResourceMetaData(String fileName, String resourceId,
102 GlobalValidationContext globalValidationContext) {
104 mdcDataDebugMessage.debugEntryMessage("file", fileName);
106 Map<String, Object> novaServerProp = resource.getProperties();
107 Object novaServerPropMetadata;
108 if (MapUtils.isNotEmpty(novaServerProp)) {
109 novaServerPropMetadata = novaServerProp.get("metadata");
110 if (novaServerPropMetadata == null) {
111 globalValidationContext.addMessage(
114 ErrorMessagesFormatBuilder
115 .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_METADATA.getErrorMessage(),
117 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
118 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
119 } else if (novaServerPropMetadata instanceof Map) {
120 TreeMap<String, Object> propertyMap = new TreeMap(new Comparator<String>() {
123 public int compare(String o1, String o2) {
124 return o1.compareToIgnoreCase(o2);
128 public boolean equals(Object obj) {
132 propertyMap.putAll((Map) novaServerPropMetadata);
133 if (!propertyMap.containsKey("vf_module_id")) {
134 globalValidationContext.addMessage(
137 ErrorMessagesFormatBuilder.getErrorWithParameters(
138 Messages.MISSING_NOVA_SERVER_VF_MODULE_ID.getErrorMessage(), resourceId),
139 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
140 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
142 if (!propertyMap.containsKey("vnf_id")) {
143 globalValidationContext.addMessage(
144 fileName, ErrorLevel.WARNING,
145 ErrorMessagesFormatBuilder
146 .getErrorWithParameters(Messages.MISSING_NOVA_SERVER_VNF_ID.getErrorMessage(),
148 LoggerTragetServiceName.VALIDATE_NOVA_META_DATA_NAME,
149 LoggerErrorDescription.MISSING_NOVA_PROPERTIES);
154 mdcDataDebugMessage.debugExitMessage("file", fileName);
157 private void validateNovaServerResourceNetworkUniqueRole(String fileName, String resourceId,
158 Map<String, String> uniqueResourcePortNetworkRole,
159 HeatOrchestrationTemplate heatOrchestrationTemplate,
160 GlobalValidationContext globalValidationContext) {
163 mdcDataDebugMessage.debugEntryMessage("file", fileName);
168 Object propertyNetworkValue =
169 heatOrchestrationTemplate.getResources().get(resourceId).getProperties().get("networks");
170 if (propertyNetworkValue != null && propertyNetworkValue instanceof List) {
171 List<String> portResourceIdList =
172 getNovaNetworkPortResourceList(fileName, (List) propertyNetworkValue,
173 globalValidationContext);
174 for (String portResourceId : portResourceIdList) {
175 Resource portResource = heatOrchestrationTemplate.getResources().get(portResourceId);
176 if (portResource != null && portResource.getType()
177 .equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
179 getPortNetwork(fileName, resourceId, portResource, globalValidationContext);
180 if (Objects.nonNull(portNetwork)) {
181 network = portNetwork.get("get_param");
182 if (Objects.nonNull(network)) {
183 if (network instanceof String ){
184 role = getNetworkRole((String)network);
185 }else if (network instanceof List){
186 role = getNetworkRole((String)((List) network).get(0));
188 if (role != null && uniqueResourcePortNetworkRole.containsKey(role)) {
189 globalValidationContext.addMessage(
192 ErrorMessagesFormatBuilder.getErrorWithParameters(
193 Messages.RESOURCE_CONNECTED_TO_TWO_EXTERNAL_NETWORKS_WITH_SAME_ROLE
194 .getErrorMessage(), resourceId, role),
195 LoggerTragetServiceName.VALIDATE_RESOURCE_NETWORK_UNIQUE_ROLW,
196 LoggerErrorDescription.RESOURCE_UNIQUE_NETWORK_ROLE);
198 uniqueResourcePortNetworkRole.put(role, portResourceId);
206 mdcDataDebugMessage.debugExitMessage("file", fileName);
209 private List<String> getNovaNetworkPortResourceList(String filename, List propertyNetworkValue,
210 GlobalValidationContext globalContext) {
211 List<String> portResourceIdList = new ArrayList<>();
212 for (Object propValue : propertyNetworkValue) {
213 Object portPropValue = ((Map) propValue).get("port");
214 Collection<String> portResourceIds = HeatStructureUtil
215 .getReferencedValuesByFunctionName(filename, "get_resource", portPropValue,
217 if (portResourceIds != null) {
218 portResourceIdList.addAll(portResourceIds);
222 return portResourceIdList;
225 private String getNetworkRole(String network) {
226 if (network == null) {
229 if (network.contains("_net_id")) {
230 return network.substring(0, network.indexOf("_net_id"));
231 } else if (network.contains("net_name")) {
232 return network.substring(0, network.indexOf("_net_name"));
233 } else if (network.contains("net_fqdn")) {
234 return network.substring(0, network.indexOf("_net_fqdn"));
239 private Map getPortNetwork(String fileName, String resourceId, Resource portResource,
240 GlobalValidationContext globalValidationContext) {
241 Object portNetwork = portResource.getProperties().get("network_id");
242 if (portNetwork == null) {
243 portNetwork = portResource.getProperties().get("network");
245 if (!(portNetwork instanceof Map)) {
246 globalValidationContext.addMessage(
249 ErrorMessagesFormatBuilder
250 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
251 "network or network_id", resourceId),
252 LoggerTragetServiceName.VALIDATE_RESOURCE_NETWORK_UNIQUE_ROLW,
253 LoggerErrorDescription.MISSING_GET_PARAM);
256 return (Map) portNetwork;
259 private void validateAvailabilityZoneName(String fileName,
260 Map.Entry<String, Resource> resourceEntry,
261 GlobalValidationContext globalContext) {
264 mdcDataDebugMessage.debugEntryMessage("file", fileName);
266 String[] regexList = new String[]{"availability_zone_(\\d+)"};
268 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
269 mdcDataDebugMessage.debugExitMessage("file", fileName);
273 Object availabilityZoneMap =
274 resourceEntry.getValue().getProperties().containsKey("availability_zone") ? resourceEntry
275 .getValue().getProperties().get("availability_zone") : null;
277 if (nonNull(availabilityZoneMap)) {
278 if (availabilityZoneMap instanceof Map) {
279 String availabilityZoneName = ValidationUtil.getWantedNameFromPropertyValueGetParam
280 (availabilityZoneMap);
282 if (availabilityZoneName != null) {
283 if (!ValidationUtil.evalPattern(availabilityZoneName, regexList)) {
284 globalContext.addMessage(
286 ErrorLevel.WARNING, ErrorMessagesFormatBuilder.getErrorWithParameters(
287 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(),
288 ValidationUtil.getMessagePartAccordingToResourceType(resourceEntry),
290 availabilityZoneName, resourceEntry.getKey()),
291 LoggerTragetServiceName.VALIDATE_AVAILABILITY_ZONE_NAME,
292 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
296 globalContext.addMessage(
298 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
299 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
300 "availability_zone", resourceEntry.getKey()),
301 LoggerTragetServiceName.VALIDATE_AVAILABILITY_ZONE_NAME,
302 LoggerErrorDescription.MISSING_GET_PARAM);
305 mdcDataDebugMessage.debugExitMessage("file", fileName);
308 private void validateNovaServerNameImageAndFlavor(String fileName, String envFileName,
309 Map.Entry<String, Resource> resourceEntry,
310 GlobalValidationContext globalContext) {
312 mdcDataDebugMessage.debugEntryMessage("file", fileName);
315 validateNovaServerNamingConvention(fileName, envFileName, resourceEntry, globalContext);
316 Map<String, String> legalNovaNamingConventionMap =
317 validateImageAndFlavorFromNovaServer(fileName, resourceEntry, globalContext);
319 if (Objects.nonNull(novaName)) {
320 legalNovaNamingConventionMap.put("name", novaName);
323 if (legalNovaNamingConventionMap.keySet().size() > 1) {
324 validateNovaServerNameImageAndFlavorSync(fileName, resourceEntry,
325 legalNovaNamingConventionMap, globalContext);
328 mdcDataDebugMessage.debugExitMessage("file", fileName);
331 private String validateNovaServerNamingConvention(String fileName, String envFileName,
332 Map.Entry<String, Resource> resourceEntry,
333 GlobalValidationContext globalContext) {
335 mdcDataDebugMessage.debugEntryMessage("file", fileName);
337 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
338 mdcDataDebugMessage.debugExitMessage("file", fileName);
342 mdcDataDebugMessage.debugExitMessage("file", fileName);
343 return checkIfNovaNameByGuidelines(fileName, envFileName, resourceEntry, globalContext);
346 private Map<String, String> validateImageAndFlavorFromNovaServer(String fileName,
347 Map.Entry<String, Resource> resourceEntry,
348 GlobalValidationContext globalContext) {
350 mdcDataDebugMessage.debugEntryMessage("file", fileName);
352 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
353 mdcDataDebugMessage.debugExitMessage("file", fileName);
357 Pair<String, String> imagePair = new ImmutablePair<>("image", ".*_image_name");
358 Pair<String, String> flavorPair = new ImmutablePair<>("flavor", ".*_flavor_name");
359 List<Pair<String, String>> imageFlavorPairs = Arrays.asList(imagePair, flavorPair);
360 Map<String, Object> propertiesMap = resourceEntry.getValue().getProperties();
361 Map<String, String> imageAndFlavorLegalNames = new HashMap<>();
363 for (Pair<String, String> imageOrFlavor : imageFlavorPairs) {
364 boolean isErrorInImageOrFlavor =
365 isErrorExistWhenValidatingImageOrFlavorNames(fileName, imageOrFlavor, resourceEntry,
366 propertiesMap, globalContext);
367 if (!isErrorInImageOrFlavor) {
368 Object nameValue = propertiesMap.get(imageOrFlavor.getKey()) == null ? null
369 : propertiesMap.get(imageOrFlavor.getKey());
370 String imageOrFlavorName = ValidationUtil.getWantedNameFromPropertyValueGetParam(nameValue);
371 imageAndFlavorLegalNames.put(imageOrFlavor.getKey(), imageOrFlavorName);
375 mdcDataDebugMessage.debugExitMessage("file", fileName);
376 return imageAndFlavorLegalNames;
379 private String checkIfNovaNameByGuidelines(String fileName, String envFileName,
380 Map.Entry<String, Resource> resourceEntry,
381 GlobalValidationContext globalContext) {
382 if (MapUtils.isEmpty(resourceEntry.getValue().getProperties())) {
385 Object novaNameGetParam = getNovaServerName(resourceEntry);
386 String novaName = null;
387 if (nonNull(novaNameGetParam)) {
389 checkNovaNameGetParamValueMap(fileName, novaNameGetParam, resourceEntry, globalContext);
390 checkIfNovaNameParameterInEnvIsStringOrList(fileName, envFileName, resourceEntry, novaName,
393 globalContext.addMessage(
395 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
396 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(),
397 "nova server name", resourceEntry.getKey()),
398 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
399 LoggerErrorDescription.MISSING_GET_PARAM);
405 private boolean isErrorExistWhenValidatingImageOrFlavorNames(String fileName,
406 Pair<String, String> propertyNameAndRegex,
407 Map.Entry<String, Resource> resourceEntry,
408 Map<String, Object> propertiesMap,
409 GlobalValidationContext globalContext) {
410 String propertyName = propertyNameAndRegex.getKey();
412 propertiesMap.get(propertyName) == null ? null : propertiesMap.get(propertyName);
413 String[] regexList = new String[]{propertyNameAndRegex.getValue()};
415 if (nonNull(nameValue)) {
416 if (nameValue instanceof Map) {
417 if (ValidationUtil.validateMapPropertyValue(fileName, resourceEntry, globalContext,
419 nameValue, regexList)) {
423 globalContext.addMessage(
425 ErrorLevel.WARNING, ErrorMessagesFormatBuilder
426 .getErrorWithParameters(Messages.MISSING_GET_PARAM.getErrorMessage(), propertyName,
427 resourceEntry.getKey()),
428 LoggerTragetServiceName.VALIDATE_IMAGE_AND_FLAVOR_NAME,
429 LoggerErrorDescription.MISSING_GET_PARAM);
438 private Object getNovaServerName(Map.Entry<String, Resource> resourceEntry) {
439 Object novaServerName = resourceEntry.getValue().getProperties().get("name");
441 if (nonNull(novaServerName)) {
442 if (novaServerName instanceof Map) {
443 novaNameMap = (Map) novaServerName;
444 return novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction()) == null ? null
445 : novaNameMap.get(ResourceReferenceFunctions.GET_PARAM.getFunction());
451 @SuppressWarnings("unchecked")
452 private String checkNovaNameGetParamValueMap(String fileName, Object getParamValue,
453 Map.Entry<String, Resource> resourceEntry,
454 GlobalValidationContext globalContext) {
455 if (getParamValue instanceof List) {
456 List<Object> getParamNameList = (List) getParamValue;
457 String[] regexName = new String[]{".*_names"};
458 return isNovaNameAsListLegal(fileName, getParamNameList, regexName, resourceEntry,
460 } else if (getParamValue instanceof String) {
461 String[] regexName = new String[]{".*_name_(\\d+)"};
462 return isNovaNameAsStringLegal(fileName, (String) getParamValue, regexName, resourceEntry,
469 private void checkIfNovaNameParameterInEnvIsStringOrList(String fileName, String envFileName,
470 Map.Entry<String, Resource> resourceEntry,
471 String novaServerName,
472 GlobalValidationContext globalContext) {
473 if (nonNull(envFileName)) {
474 Environment environment = ValidationUtil.validateEnvContent(envFileName, globalContext);
476 if (environment != null && MapUtils.isNotEmpty(environment.getParameters())) {
477 Object novaServerNameEnvValue =
478 environment.getParameters().containsKey(novaServerName) ? environment.getParameters()
479 .get(novaServerName) : null;
480 if (Objects.nonNull(novaServerNameEnvValue)) {
481 if (!DefinedHeatParameterTypes
482 .isNovaServerEnvValueIsFromRightType(novaServerNameEnvValue)) {
483 globalContext.addMessage(
485 ErrorLevel.WARNING, ErrorMessagesFormatBuilder.getErrorWithParameters(
486 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
487 "Name", novaServerNameEnvValue.toString(), resourceEntry.getKey()),
488 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
489 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
496 private String isNovaNameAsListLegal(String fileName, List<Object> getParamNameList,
498 Map.Entry<String, Resource> resourceEntry,
499 GlobalValidationContext globalContext) {
501 if (getParamNameList.size() != 2 || !ValidationUtil.evalPattern(getParamNameList.get(0),
503 globalContext.addMessage(
506 ErrorMessagesFormatBuilder.getErrorWithParameters(
507 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
508 "name", getParamNameList.toString(), resourceEntry.getKey()),
509 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
510 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
514 return (String) getParamNameList.get(0);
517 private String isNovaNameAsStringLegal(String fileName, String novaName, String[] regexName,
518 Map.Entry<String, Resource> resourceEntry,
519 GlobalValidationContext globalContext) {
520 if (!ValidationUtil.evalPattern(novaName, regexName)) {
521 globalContext.addMessage(
524 ErrorMessagesFormatBuilder.getErrorWithParameters(
525 Messages.PARAMETER_NAME_NOT_ALIGNED_WITH_GUIDELINES.getErrorMessage(), "Server",
526 "name", novaName, resourceEntry.getKey()),
527 LoggerTragetServiceName.VALIDATE_NOVA_SERVER_NAME,
528 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
534 private void validateNovaServerNameImageAndFlavorSync(String fileName,
535 Map.Entry<String, Resource> resourceEntry,
536 Map<String, String> legalNovaNamingConventionNames,
537 GlobalValidationContext globalContext) {
539 mdcDataDebugMessage.debugEntryMessage("file", fileName);
541 List<String> vmNames = new LinkedList<>();
543 for (Map.Entry<String, String> nameEntry : legalNovaNamingConventionNames.entrySet()) {
544 vmNames.add(getVmName(nameEntry.getValue(), nameEntry.getKey()));
547 vmNames.removeIf(VMName -> VMName == null);
549 if (!isVmNameSync(vmNames)) {
550 globalContext.addMessage(
553 ErrorMessagesFormatBuilder.getErrorWithParameters(
554 Messages.NOVA_NAME_IMAGE_FLAVOR_NOT_CONSISTENT.getErrorMessage(),
555 resourceEntry.getKey()),
556 LoggerTragetServiceName.VALIDATE_IMAGE_AND_FLAVOR_NAME,
557 LoggerErrorDescription.NAME_NOT_ALIGNED_WITH_GUIDELINES);
559 mdcDataDebugMessage.debugExitMessage("file", fileName);
562 private String getVmName(String nameToGetVmNameFrom, String stringToGetIndexOf) {
564 nameToGetVmNameFrom == null ? -1 : nameToGetVmNameFrom.indexOf(stringToGetIndexOf);
565 String vmName = vmIndex < 0 ? null
566 : trimNonAlphaNumericCharactersFromEndOfString(nameToGetVmNameFrom.substring(0, vmIndex));
572 private boolean isVmNameSync(List<String> namesToCompare) {
573 int size = namesToCompare.size();
574 for (int i = 0; i < size - 1; i++) {
575 if (!namesToCompare.get(i).equals(namesToCompare.get(i + 1))) {
582 private String trimNonAlphaNumericCharactersFromEndOfString(String toTrim) {
583 int stringSize = toTrim.length();
584 int stringLength = stringSize - 1;
585 String[] regexList = new String[]{"[^a-zA-Z0-9]"};
587 while (stringLength >= 0) {
588 if (!ValidationUtil.evalPattern(String.valueOf(toTrim.charAt(stringLength)), regexList)) {
594 return toTrim.substring(0, stringLength + 1);