package org.ovirt.engine.ui.uicommonweb.models.vms;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.businessentities.network.VmInterfaceType;
import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
import org.ovirt.engine.core.common.businessentities.network.VnicProfileView;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.ui.frontend.AsyncQuery;
public abstract class BaseInterfaceCreatingManager {
protected VmInterfaceType defaultType;
protected Collection<VmInterfaceType> supportedInterfaceTypes;
private PostVnicCreatedCallback callback;
public BaseInterfaceCreatingManager(PostVnicCreatedCallback callback) {
this.callback = callback;
}
public PostVnicCreatedCallback getCallback() {
return callback;
}
public static interface PostVnicCreatedCallback {
void vnicCreated(Guid vmId, UnitVmModel unitVmModel);
void queryFailed();
}
public void updateVnics(final Guid vmId,
final Iterable<VnicInstanceType> vnicsWithProfiles,
final UnitVmModel unitVmModel) {
getNics(new AsyncQuery<>(existingVnics -> {
if (existingVnics == null) {
existingVnics = new ArrayList<>();
}
Map<String, VmNetworkInterface> existingVnicForName = new HashMap<>();
for (VmNetworkInterface vnic : existingVnics) {
existingVnicForName.put(vnic.getName(), vnic);
}
final ArrayList<VdcActionParametersBase> createVnicParameters = new ArrayList<>();
final ArrayList<VdcActionParametersBase> updateVnicParameters = new ArrayList<>();
final ArrayList<VdcActionParametersBase> removeVnicParameters = new ArrayList<>();
final Set<String> vnicsEncountered = new HashSet<>();
// iterate over edited VNICs, see if any need to be added or have been assigned a different profile
for (VnicInstanceType vnicWithProfile : vnicsWithProfiles) {
VmNetworkInterface editedVnic = vnicWithProfile.getNetworkInterface();
String vnicName = editedVnic.getName();
VmNetworkInterface existingVnic = existingVnicForName.get(vnicName);
VnicProfileView profile = vnicWithProfile.getSelectedItem();
updateVnicType(profile, existingVnic, editedVnic);
if (existingVnic == null) {
createVnicParameters.add(createAddInterfaceParameter(vmId, editedVnic));
} else {
vnicsEncountered.add(vnicName);
Guid existingProfileId = existingVnic.getVnicProfileId();
Guid editedProfileId = editedVnic.getVnicProfileId();
if ((editedProfileId == null && existingProfileId != null)
|| (editedProfileId != null && !editedProfileId.equals(existingProfileId))) {
existingVnic.setVnicProfileId(editedProfileId);
existingVnic.setNetworkName(editedVnic.getNetworkName());
updateVnicParameters.add(createAddInterfaceParameter(vmId, existingVnic));
}
}
}
// iterate over existing VNICs, see if any have not been encountered and thus removed in editing
for (VmNetworkInterface existingVnic : existingVnics) {
if (!vnicsEncountered.contains(existingVnic.getName())) {
removeVnicParameters.add(createRemoveInterfaceParameter(vmId, existingVnic.getId()));
}
}
doNicManipulation(createVnicParameters, updateVnicParameters, removeVnicParameters, unitVmModel.getIsNew(), vmId, unitVmModel);
}), vmId, unitVmModel);
}
private void updateVnicType(VnicProfileView profile, VmNetworkInterface existingVnic, VmNetworkInterface editedVnic) {
boolean shouldBePciPassthroughType = profile != null && profile.isPassthrough()
&& supportedInterfaceTypes != null && supportedInterfaceTypes.contains(VmInterfaceType.pciPassthrough);
if (existingVnic == null) {
if (shouldBePciPassthroughType) {
editedVnic.setType(VmInterfaceType.pciPassthrough.getValue());
} else {
editedVnic.setType(defaultType == null ? null : defaultType.getValue());
}
} else {
VmInterfaceType existingInterfaceType = VmInterfaceType.forValue(existingVnic.getType());
boolean shouldRestoreToDefault =
profile != null && !profile.isPassthrough()
&& VmInterfaceType.pciPassthrough.equals(existingInterfaceType);
if (shouldBePciPassthroughType) {
existingVnic.setType(VmInterfaceType.pciPassthrough.getValue());
} else if (shouldRestoreToDefault
|| supportedInterfaceTypes == null
|| !supportedInterfaceTypes.contains(existingInterfaceType)) {
existingVnic.setType(defaultType == null ? null : defaultType.getValue());
}
}
}
protected abstract VdcActionParametersBase createAddInterfaceParameter(Guid id, VmNetworkInterface editedVnic);
protected abstract VdcActionParametersBase createRemoveInterfaceParameter(Guid id, Guid nicId);
protected abstract void getNics(AsyncQuery<List<VmNetworkInterface>> getNicsQuery, Guid id, UnitVmModel unitVmModel);
protected abstract void doNicManipulation(
ArrayList<VdcActionParametersBase> createVnicParameters,
final ArrayList<VdcActionParametersBase> updateVnicParameters,
final ArrayList<VdcActionParametersBase> removeVnicParameters,
final boolean isAddingNewVm,
final Guid id,
final UnitVmModel unitVmModel);
}