package org.ovirt.engine.core.bll.validator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.ovirt.engine.core.bll.ValidationResult;
import org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
import org.ovirt.engine.core.bll.validator.network.NetworkType;
import org.ovirt.engine.core.common.businessentities.BusinessEntityMap;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.businessentities.network.NetworkAttachment;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.utils.NetworkUtils;
import org.ovirt.engine.core.utils.ReplacementUtils;
import org.ovirt.engine.core.utils.collections.MultiValueMapUtils;
/**
* The {@code NetworkAttachmentsValidator} performs validation on the entire network attachments as a whole and for
* cross network attachments configuration. For a specific network attachment entity validation use
* {@link org.ovirt.engine.core.bll.validator.NetworkAttachmentValidator};
*/
public class NetworkAttachmentsValidator {
private static final String LIST_SUFFIX = "_LIST";
private final Collection<NetworkAttachment> attachmentsToConfigure;
private final BusinessEntityMap<Network> networkBusinessEntityMap;
private final NetworkExclusivenessValidator networkExclusivenessValidator;
public NetworkAttachmentsValidator(Collection<NetworkAttachment> attachmentsToConfigure,
BusinessEntityMap<Network> networkBusinessEntityMap,
NetworkExclusivenessValidator networkExclusivenessValidator) {
Objects.requireNonNull(networkExclusivenessValidator, "networkExclusivenessValidator cannot be null");
this.attachmentsToConfigure = attachmentsToConfigure;
this.networkBusinessEntityMap = networkBusinessEntityMap;
this.networkExclusivenessValidator = networkExclusivenessValidator;
}
public ValidationResult validateNetworkExclusiveOnNics() {
Map<String, List<NetworkType>> nicNameToNetworkTypesMap = createNicNameToNetworkTypesMap();
List<String> violatedNics = findViolatedNics(nicNameToNetworkTypesMap);
if (violatedNics.isEmpty()) {
return ValidationResult.VALID;
} else {
final EngineMessage violationMessage = networkExclusivenessValidator.getViolationMessage();
return new ValidationResult(violationMessage,
ReplacementUtils.replaceWith(violationMessage + LIST_SUFFIX, violatedNics));
}
}
private List<String> findViolatedNics(Map<String, List<NetworkType>> nicNameToNetworkTypesMap) {
List<String> violatedNics = new ArrayList<>();
for (Entry<String, List<NetworkType>> nicNameToNetworkTypes : nicNameToNetworkTypesMap.entrySet()) {
String nicName = nicNameToNetworkTypes.getKey();
List<NetworkType> networkTypes = nicNameToNetworkTypes.getValue();
if (!networkExclusivenessValidator.isNetworkExclusive(networkTypes)) {
violatedNics.add(nicName);
}
}
return violatedNics;
}
private Map<String, List<NetworkType>> createNicNameToNetworkTypesMap() {
Map<String, List<NetworkType>> nicNameToNetworkTypes = new HashMap<>();
for (NetworkAttachment attachment : attachmentsToConfigure) {
String nicName = attachment.getNicName();
// have to check since if null, multiple results would be merged producing invalid results.
if (nicName == null) {
throw new IllegalArgumentException("nic name cannot be null");
}
Network networkToConfigure = networkBusinessEntityMap.get(attachment.getNetworkId());
NetworkType networkTypeToAdd = determineNetworkType(networkToConfigure);
MultiValueMapUtils.ListCreator<NetworkType> listCreator = new MultiValueMapUtils.ListCreator<>();
MultiValueMapUtils.addToMap(nicName, networkTypeToAdd, nicNameToNetworkTypes, listCreator);
}
return nicNameToNetworkTypes;
}
NetworkType determineNetworkType(Network network) {
return NetworkUtils.isVlan(network)
? NetworkType.VLAN
: network.isVmNetwork() ? NetworkType.VM : NetworkType.NON_VM;
}
public ValidationResult verifyUserAttachmentsDoesNotReferenceSameNetworkDuplicately() {
Map<String, List<Guid>> networkNameToIdsOfReferencingAttachments = new HashMap<>();
MultiValueMapUtils.ListCreator<Guid> creator = new MultiValueMapUtils.ListCreator<>();
for (NetworkAttachment networkAttachment : attachmentsToConfigure) {
Network network = networkBusinessEntityMap.get(networkAttachment.getNetworkId());
MultiValueMapUtils.addToMap(network.getName(),
networkAttachment.getId(),
networkNameToIdsOfReferencingAttachments,
creator);
}
for (Entry<String, List<Guid>> entry : networkNameToIdsOfReferencingAttachments.entrySet()) {
List<Guid> referencingAttachments = entry.getValue();
String networkName = entry.getKey();
if (referencingAttachments.size() > 1) {
List<String> replacements = new ArrayList<>();
replacements.addAll(ReplacementUtils.replaceWith(
"ACTION_TYPE_FAILED_NETWORK_ATTACHMENTS_REFERENCES_SAME_NETWORK_DUPLICATELY_LIST",
referencingAttachments));
replacements.add(ReplacementUtils.createSetVariableString(
"ACTION_TYPE_FAILED_NETWORK_ATTACHMENTS_REFERENCES_SAME_NETWORK_DUPLICATELY_ENTITY", networkName));
return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_NETWORK_ATTACHMENTS_REFERENCES_SAME_NETWORK_DUPLICATELY,
replacements);
}
}
return ValidationResult.VALID;
}
}