package org.ovirt.engine.core.bll.validator;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import org.ovirt.engine.core.bll.ValidationResult;
import org.ovirt.engine.core.common.businessentities.Nameable;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.businessentities.network.NetworkFilter;
import org.ovirt.engine.core.common.businessentities.network.VnicProfile;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.common.utils.customprop.ValidationError;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.dao.StoragePoolDao;
import org.ovirt.engine.core.dao.VmDao;
import org.ovirt.engine.core.dao.network.NetworkFilterDao;
import org.ovirt.engine.core.utils.ReplacementUtils;
import org.ovirt.engine.core.utils.customprop.DevicePropertiesUtils;
public class VnicProfileValidator {
static final String VAR_VNIC_PROFILE_NAME = "VAR_VNIC_PROFILE_NAME";
static final String VAR_NETWORK_FILTER_ID = "VAR_NETWORK_FILTER_ID";
private final VmDao vmDao;
private final StoragePoolDao dcDao;
private final NetworkFilterDao networkFilterDao;
private VnicProfile vnicProfile;
private VnicProfile oldVnicProfile;
private Network network;
private List<VnicProfile> vnicProfiles;
private List<VM> vms;
public VnicProfileValidator(VnicProfile vnicProfile, VmDao vmDao, StoragePoolDao dcDao, NetworkFilterDao networkFilterDao) {
this.vnicProfile = vnicProfile;
this.vmDao = vmDao;
this.dcDao = dcDao;
this.networkFilterDao = networkFilterDao;
}
protected DbFacade getDbFacade() {
return DbFacade.getInstance();
}
public ValidationResult vnicProfileIsSet() {
return vnicProfile == null
? new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VNIC_PROFILE_NOT_EXISTS)
: ValidationResult.VALID;
}
public ValidationResult vnicProfileExists() {
return getOldVnicProfile() == null
? new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VNIC_PROFILE_NOT_EXISTS)
: ValidationResult.VALID;
}
public ValidationResult networkExists() {
return new NetworkValidator(vmDao, getNetwork()).networkIsSet(vnicProfile.getNetworkId());
}
public ValidationResult networkQosExistsOrNull() {
return vnicProfile.getNetworkQosId() == null
|| getDbFacade().getNetworkQosDao().get(vnicProfile.getNetworkQosId()) != null
? ValidationResult.VALID
: new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_NETWORK_QOS_NOT_EXISTS);
}
public ValidationResult vnicProfileNameNotUsed() {
for (VnicProfile profile : getVnicProfiles()) {
if (profile.getName().equals(vnicProfile.getName()) && !profile.getId().equals(vnicProfile.getId())) {
return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VNIC_PROFILE_NAME_IN_USE);
}
}
return ValidationResult.VALID;
}
public ValidationResult networkNotChanged() {
if (Objects.equals(vnicProfile.getNetworkId(), getOldVnicProfile().getNetworkId())) {
return ValidationResult.VALID;
}
return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_CANNOT_CHANGE_VNIC_PROFILE_NETWORK);
}
public ValidationResult vnicProfileNotUsedByVms() {
return vnicProfileNotUsed(getVmsUsingProfile(), EngineMessage.VAR__ENTITIES__VMS, EngineMessage.VAR__ENTITIES__VM);
}
public ValidationResult vnicProfileNotUsedByTemplates() {
return vnicProfileNotUsed(getDbFacade().getVmTemplateDao().getAllForVnicProfile(vnicProfile.getId()),
EngineMessage.VAR__ENTITIES__VM_TEMPLATES, EngineMessage.VAR__ENTITIES__VM_TEMPLATE);
}
public ValidationResult vnicProfileForVmNetworkOnly() {
return getNetwork().isVmNetwork() ? ValidationResult.VALID
: new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_CANNOT_ADD_VNIC_PROFILE_TO_NON_VM_NETWORK);
}
protected ValidationResult vnicProfileNotUsed(List<? extends Nameable> entities, EngineMessage entitiesReplacementPlural, EngineMessage entitiesReplacementSingular) {
if (entities.isEmpty()) {
return ValidationResult.VALID;
}
Collection<String> replacements = ReplacementUtils.replaceWithNameable("ENTITIES_USING_VNIC_PROFILE", entities);
EngineMessage replacementMessageToUse = entities.size() == 1 ? entitiesReplacementSingular : entitiesReplacementPlural;
replacements.add(replacementMessageToUse.name());
return new ValidationResult(getVNicProfileInUseValidationMessage(entities.size()), replacements);
}
private EngineMessage getVNicProfileInUseValidationMessage(int numberOfEntities) {
boolean singular = numberOfEntities == 1;
if (singular) {
return EngineMessage.ACTION_TYPE_FAILED_VNIC_PROFILE_IN_ONE_USE;
} else {
return EngineMessage.ACTION_TYPE_FAILED_VNIC_PROFILE_IN_MANY_USES;
}
}
public ValidationResult portMirroringNotChangedIfUsedByVms() {
if (vnicProfile.isPortMirroring() == getOldVnicProfile().isPortMirroring()) {
return ValidationResult.VALID;
}
return vnicProfileNotUsedByVms();
}
public ValidationResult passthroughNotChangedIfUsedByVms() {
if (vnicProfile.isPassthrough() == getOldVnicProfile().isPassthrough()) {
return ValidationResult.VALID;
}
return vnicProfileNotUsedByVms();
}
public ValidationResult passthroughProfileContainsSupportedProperties() {
boolean conditionOccurs = vnicProfile.isPassthrough()
&& (vnicProfile.isPortMirroring()
|| vnicProfile.getNetworkQosId() != null
|| vnicProfile.getNetworkFilterId() != null
);
return ValidationResult.failWith(EngineMessage.ACTION_TYPE_FAILED_PASSTHROUGH_PROFILE_CONTAINS_NOT_SUPPORTED_PROPERTIES)
.when(conditionOccurs);
}
public boolean validateCustomProperties(List<String> messages) {
StoragePool dataCenter = dcDao.get(getNetwork().getDataCenterId());
List<ValidationError> errors =
DevicePropertiesUtils.getInstance().validateProperties(dataCenter.getCompatibilityVersion(),
VmDeviceGeneralType.INTERFACE,
vnicProfile.getCustomProperties());
if (!errors.isEmpty()) {
DevicePropertiesUtils.getInstance().handleCustomPropertiesError(errors, messages);
return false;
}
return true;
}
public ValidationResult portMirroringNotSetIfExternalNetwork() {
return !vnicProfile.isPortMirroring() || !getNetwork().isExternal()
? ValidationResult.VALID
: new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_EXTERNAL_NETWORK_CANNOT_BE_PORT_MIRRORED);
}
protected Network getNetwork() {
if (network == null) {
network = getDbFacade().getNetworkDao().get(vnicProfile.getNetworkId());
}
return network;
}
protected List<VnicProfile> getVnicProfiles() {
if (vnicProfiles == null) {
vnicProfiles = getDbFacade().getVnicProfileDao().getAllForNetwork(vnicProfile.getNetworkId());
}
return vnicProfiles;
}
protected VnicProfile getOldVnicProfile() {
if (oldVnicProfile == null) {
oldVnicProfile = getDbFacade().getVnicProfileDao().get(vnicProfile.getId());
}
return oldVnicProfile;
}
protected List<VM> getVmsUsingProfile() {
if (vms == null) {
vms = getDbFacade().getVmDao().getAllForVnicProfile(vnicProfile.getId());
}
return vms;
}
public ValidationResult validNetworkFilterId() {
final Guid networkFilterId = getNetworkFilterId();
if (networkFilterId == null) {
return ValidationResult.VALID;
}
NetworkFilter networkFilter = networkFilterDao.getNetworkFilterById(networkFilterId);
return ValidationResult.failWith(EngineMessage.ACTION_TYPE_FAILED_INVALID_VNIC_PROFILE_NETWORK_FILTER_ID,
ReplacementUtils.createSetVariableString(VAR_VNIC_PROFILE_NAME, vnicProfile.getName()),
ReplacementUtils.createSetVariableString(VAR_NETWORK_FILTER_ID, networkFilterId))
.when(networkFilter == null);
}
public ValidationResult validUseDefaultNetworkFilterFlag(boolean useDefaultNetworkFilterId) {
return ValidationResult.failWith(EngineMessage.ACTION_TYPE_FAILED_INVALID_VNIC_PROFILE_NETWORK_ID_CONFIGURATION,
ReplacementUtils.createSetVariableString(VAR_VNIC_PROFILE_NAME, vnicProfile.getName()),
ReplacementUtils.createSetVariableString(VAR_NETWORK_FILTER_ID, vnicProfile.getNetworkFilterId()))
.when(useDefaultNetworkFilterId && vnicProfile.getNetworkFilterId() != null);
}
private Guid getNetworkFilterId() {
return vnicProfile.getNetworkFilterId();
}
}