package org.ovirt.engine.ui.uicommonweb.models.pools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.ovirt.engine.core.common.action.AddVmPoolParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VmPoolParametersBase;
import org.ovirt.engine.core.common.businessentities.DisplayType;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VmPool;
import org.ovirt.engine.core.common.businessentities.VmPoolType;
import org.ovirt.engine.core.common.businessentities.VmType;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.mode.ApplicationMode;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.SearchParameters;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.StringHelper;
import org.ovirt.engine.core.searchbackend.SearchObjects;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.uicommonweb.Cloner;
import org.ovirt.engine.ui.uicommonweb.Linq;
import org.ovirt.engine.ui.uicommonweb.UICommand;
import org.ovirt.engine.ui.uicommonweb.builders.BuilderExecutor;
import org.ovirt.engine.ui.uicommonweb.builders.vm.CoreUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.CpuProfileUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.DedicatedVmForVdsUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.KernelParamsUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.MigrationOptionsUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.NameUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.UnitToGraphicsDeviceParamsBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.UsbPolicyUnitToVmBaseBuilder;
import org.ovirt.engine.ui.uicommonweb.builders.vm.VmSpecificUnitToVmBuilder;
import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
import org.ovirt.engine.ui.uicommonweb.help.HelpTag;
import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.HasEntity;
import org.ovirt.engine.ui.uicommonweb.models.ISupportSystemTreeContext;
import org.ovirt.engine.ui.uicommonweb.models.ListWithSimpleDetailsModel;
import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel;
import org.ovirt.engine.ui.uicommonweb.models.TabName;
import org.ovirt.engine.ui.uicommonweb.models.configure.PermissionListModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.ExistingPoolModelBehavior;
import org.ovirt.engine.ui.uicommonweb.models.vms.NewPoolModelBehavior;
import org.ovirt.engine.ui.uicommonweb.models.vms.VmBasedWidgetSwitchModeCommand;
import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
import org.ovirt.engine.ui.uicompat.UIConstants;
import com.google.inject.Inject;
public class PoolListModel extends ListWithSimpleDetailsModel<Void, VmPool> implements ISupportSystemTreeContext {
private final UIConstants constants = ConstantsManager.getInstance().getConstants();
private UICommand privateNewCommand;
private VmPool privateCurrentPool;
public UICommand getNewCommand() {
return privateNewCommand;
}
private void setNewCommand(UICommand value) {
privateNewCommand = value;
}
private UICommand privateEditCommand;
@Override
public UICommand getEditCommand() {
return privateEditCommand;
}
private void setEditCommand(UICommand value) {
privateEditCommand = value;
}
private UICommand privateRemoveCommand;
public UICommand getRemoveCommand() {
return privateRemoveCommand;
}
private void setRemoveCommand(UICommand value) {
privateRemoveCommand = value;
}
private SystemTreeItemModel systemTreeSelectedItem;
@Override
public SystemTreeItemModel getSystemTreeSelectedItem() {
return systemTreeSelectedItem;
}
@Override
public void setSystemTreeSelectedItem(SystemTreeItemModel value) {
systemTreeSelectedItem = value;
}
protected Object[] getSelectedKeys() {
if (getSelectedItems() == null) {
return new Object[0];
}
else {
Object[] keys = new Object[getSelectedItems().size()];
for (int i = 0; i < getSelectedItems().size(); i++) {
keys[i] = getSelectedItems().get(i).getVmPoolId();
}
return keys;
}
}
@Inject
public PoolListModel(final PoolGeneralModel poolGeneralModel, final PoolVmListModel poolVmListModel,
final PermissionListModel<VmPool> permissionListModel) {
setDetailList(poolGeneralModel, poolVmListModel, permissionListModel);
setTitle(ConstantsManager.getInstance().getConstants().poolsTitle());
setApplicationPlace(WebAdminApplicationPlaces.poolMainTabPlace);
setDefaultSearchString("Pools:"); //$NON-NLS-1$
setSearchString(getDefaultSearchString());
setSearchObjects(new String[] { SearchObjects.VDC_POOL_OBJ_NAME, SearchObjects.VDC_POOL_PLU_OBJ_NAME });
setAvailableInModes(ApplicationMode.VirtOnly);
setNewCommand(new UICommand("New", this)); //$NON-NLS-1$
setEditCommand(new UICommand("Edit", this)); //$NON-NLS-1$
setRemoveCommand(new UICommand("Remove", this)); //$NON-NLS-1$
updateActionAvailability();
getSearchNextPageCommand().setIsAvailable(true);
getSearchPreviousPageCommand().setIsAvailable(true);
}
private void setDetailList(final PoolGeneralModel poolGeneralModel, final PoolVmListModel poolVmListModel,
final PermissionListModel<VmPool> permissionListModel) {
List<HasEntity<VmPool>> list = new ArrayList<>();
list.add(poolGeneralModel);
list.add(poolVmListModel);
list.add(permissionListModel);
setDetailModels(list);
}
@Override
public boolean isSearchStringMatch(String searchString) {
return searchString.trim().toLowerCase().startsWith("pool"); //$NON-NLS-1$
}
@Override
protected void syncSearch() {
SearchParameters tempVar = new SearchParameters(applySortOptions(getSearchString()), SearchType.VmPools, isCaseSensitiveSearch());
tempVar.setMaxCount(getSearchPageSize());
super.syncSearch(VdcQueryType.Search, tempVar);
}
@Override
public boolean supportsServerSideSorting() {
return true;
}
public void newEntity() {
if (getWindow() != null) {
return;
}
PoolModel model = new PoolModel(new NewPoolModelBehavior());
model.setIsNew(true);
model.setCustomPropertiesKeysList(AsyncDataProvider.getInstance().getCustomPropertiesList());
model.setIsAdvancedModeLocalStorageKey("wa_pool_dialog"); //$NON-NLS-1$
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().newPoolTitle());
model.setHelpTag(HelpTag.new_pool);
model.setHashName("new_pool"); //$NON-NLS-1$
model.getVmType().setSelectedItem(VmType.Desktop);
model.initialize(getSystemTreeSelectedItem());
VmBasedWidgetSwitchModeCommand switchModeCommand = new VmBasedWidgetSwitchModeCommand();
switchModeCommand.init(model);
model.getCommands().add(switchModeCommand);
UICommand command = UICommand.createDefaultOkUiCommand("OnSave", this); //$NON-NLS-1$
model.getCommands().add(command);
model.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$
}
public void edit() {
final VmPool pool = getSelectedItem();
if (getWindow() != null) {
return;
}
final PoolListModel poolListModel = this;
Frontend.getInstance().runQuery(VdcQueryType.GetVmDataByPoolId,
new IdQueryParameters(pool.getVmPoolId()),
new AsyncQuery<VdcQueryReturnValue>(result -> {
final VM vm = result.getReturnValue();
final ExistingPoolModelBehavior behavior = new ExistingPoolModelBehavior(vm, pool);
behavior.getPoolModelBehaviorInitializedEvent().addListener((ev, sender, args) -> {
final PoolModel model = behavior.getModel();
for (EntityModel<VmPoolType> item : model.getPoolType().getItems()) {
if (item.getEntity() == pool.getVmPoolType()) {
model.getPoolType().setSelectedItem(item);
break;
}
}
String cdImage = null;
if (vm != null) {
model.getDataCenterWithClustersList().setSelectedItem(null);
model.getDataCenterWithClustersList().setSelectedItem(Linq.firstOrNull(model.getDataCenterWithClustersList()
.getItems(),
new Linq.DataCenterWithClusterPredicate(vm.getStoragePoolId(), vm.getClusterId())));
model.getTemplateWithVersion().setIsChangeable(false);
cdImage = vm.getIsoPath();
model.getVmType().setSelectedItem(vm.getVmType());
}
else {
model.getDataCenterWithClustersList()
.setSelectedItem(Linq.firstOrNull(model.getDataCenterWithClustersList().getItems()));
}
model.getDataCenterWithClustersList().setIsChangeable(vm == null);
boolean hasCd = !StringHelper.isNullOrEmpty(cdImage);
model.getCdImage().setIsChangeable(hasCd);
model.getCdAttached().setEntity(hasCd);
if (hasCd) {
model.getCdImage().setSelectedItem(cdImage);
}
model.getProvisioning().setIsChangeable(false);
model.getStorageDomain().setIsChangeable(false);
});
PoolModel model = new PoolModel(behavior);
model.setCustomPropertiesKeysList(AsyncDataProvider.getInstance().getCustomPropertiesList());
model.setIsAdvancedModeLocalStorageKey("wa_pool_dialog"); //$NON-NLS-1$
setWindow(model);
VmBasedWidgetSwitchModeCommand switchModeCommand = new VmBasedWidgetSwitchModeCommand();
switchModeCommand.init(model);
model.getCommands().add(switchModeCommand);
UICommand command = UICommand.createDefaultOkUiCommand("OnSave", poolListModel); //$NON-NLS-1$
model.getCommands().add(command);
model.getCommands().add(UICommand.createCancelUiCommand("Cancel", poolListModel)); //$NON-NLS-1$
model.setTitle(ConstantsManager.getInstance().getConstants().editPoolTitle());
model.setHelpTag(HelpTag.edit_pool);
model.setHashName("edit_pool"); //$NON-NLS-1$
model.initialize(getSystemTreeSelectedItem());
model.getName().setEntity(pool.getName());
model.getDescription().setEntity(pool.getVmPoolDescription());
model.getComment().setEntity(pool.getComment());
model.getPoolStateful().setEntity(pool.isStateful());
model.getAssignedVms().setEntity(pool.getAssignedVmsCount());
model.getPrestartedVms().setEntity(pool.getPrestartedVms());
model.setPrestartedVmsHint("0-" + pool.getAssignedVmsCount()); //$NON-NLS-1$
model.getMaxAssignedVmsPerUser().setEntity(pool.getMaxAssignedVmsPerUser());
}));
}
private List<StoragePool> asList(Object returnValue) {
if (returnValue instanceof ArrayList) {
return (ArrayList<StoragePool>) returnValue;
}
if (returnValue instanceof StoragePool) {
List<StoragePool> res = new ArrayList<>();
res.add((StoragePool) returnValue);
return res;
}
throw new IllegalArgumentException("Expected ArrayList of storage_pools or a storage_pool. Given " + returnValue.getClass().getName()); //$NON-NLS-1$
}
public void remove() {
if (getWindow() != null) {
return;
}
ConfirmationModel model = new ConfirmationModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().removePoolsTitle());
model.setHelpTag(HelpTag.remove_pool);
model.setHashName("remove_pool"); //$NON-NLS-1$
ArrayList<String> list = new ArrayList<>();
for (VmPool item : getSelectedItems()) {
list.add(item.getName());
}
model.setItems(list);
UICommand tempVar = UICommand.createDefaultOkUiCommand("OnRemove", this); //$NON-NLS-1$
model.getCommands().add(tempVar);
UICommand tempVar2 = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.getCommands().add(tempVar2);
}
public void onRemove() {
ConfirmationModel model = (ConfirmationModel) getWindow();
if (model.getProgress() != null) {
return;
}
ArrayList<VdcActionParametersBase> list = new ArrayList<>();
for (Object item : getSelectedItems()) {
VmPool pool = (VmPool) item;
list.add(new VmPoolParametersBase(pool.getVmPoolId()));
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.RemoveVmPool, list,
result -> {
ConfirmationModel localModel = (ConfirmationModel) result.getState();
localModel.stopProgress();
cancel();
}, model);
}
public void onSave() {
final PoolModel model = (PoolModel) getWindow();
if (model.getProgress() != null) {
return;
}
if (!model.getIsNew() && getSelectedItem() == null) {
cancel();
return;
}
if (!model.validate()) {
return;
}
setCurrentPool(model.getIsNew() ? new VmPool() : (VmPool) Cloner.clone(getSelectedItem()));
final String name = model.getName().getEntity();
// Check name unicitate.
AsyncDataProvider.getInstance().isPoolNameUnique(new AsyncQuery<>(
isUnique -> {
if ((model.getIsNew() && !isUnique)
|| (!model.getIsNew() && !isUnique
&& name.compareToIgnoreCase(getCurrentPool().getName()) != 0)) {
model.getName()
.getInvalidityReasons()
.add(ConstantsManager.getInstance()
.getConstants()
.nameMustBeUniqueInvalidReason());
model.getName().setIsValid(false);
model.setValidTab(TabName.GENERAL_TAB, false);
model.fireValidationCompleteEvent();
return;
}
String selectedCpu = model.getCustomCpu().getSelectedItem();
if (selectedCpu != null && !selectedCpu.isEmpty() && !model.getCustomCpu()
.getItems()
.contains(selectedCpu)) {
ConfirmationModel confirmModel = new ConfirmationModel();
confirmModel.setTitle(ConstantsManager.getInstance()
.getConstants()
.vmUnsupportedCpuTitle());
confirmModel.setMessage(ConstantsManager.getInstance()
.getConstants()
.vmUnsupportedCpuMessage());
confirmModel.setHelpTag(HelpTag.edit_unsupported_cpu);
confirmModel.setHashName("edit_unsupported_cpu"); //$NON-NLS-1$
confirmModel.getCommands()
.add(new UICommand("OnSave_Phase2", PoolListModel.this) //$NON-NLS-1$
.setTitle(ConstantsManager.getInstance().getConstants().ok())
.setIsDefault(true));
confirmModel.getCommands()
.add(UICommand.createCancelUiCommand("CancelConfirmation", //$NON-NLS-1$
PoolListModel.this));
setConfirmWindow(confirmModel);
} else {
savePoolPostValidation();
}
}),
name);
}
public void savePoolPostValidation() {
final PoolModel model = (PoolModel) getWindow();
VmPool pool = getCurrentPool();
// Save changes.
pool.setName(model.getName().getEntity());
pool.setVmPoolDescription(model.getDescription().getEntity());
pool.setClusterId(model.getSelectedCluster().getId());
pool.setComment(model.getComment().getEntity());
pool.setStateful(model.getPoolStateful().getEntity());
pool.setPrestartedVms(model.getPrestartedVms().getEntity());
pool.setMaxAssignedVmsPerUser(model.getMaxAssignedVmsPerUser().getEntity());
pool.setAutoStorageSelect(model.getDisksAllocationModel().getDiskAllocationTargetEnabled().getEntity());
EntityModel<VmPoolType> poolTypeSelectedItem = model.getPoolType().getSelectedItem();
pool.setVmPoolType(poolTypeSelectedItem.getEntity());
if (model.getSpiceProxyEnabled().getEntity()) {
pool.setSpiceProxy(model.getSpiceProxy().getEntity());
}
VM vm = buildVmOnSave(model);
vm.setVmInit(model.getVmInitModel().buildCloudInitParameters(model));
vm.setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
vm.setStateless(false);
vm.setInstanceTypeId(model.getInstanceTypes().getSelectedItem().getId());
AddVmPoolParameters param =
new AddVmPoolParameters(pool, vm, model.getNumOfDesktops().getEntity());
param.setStorageDomainId(Guid.Empty);
param.setDiskInfoDestinationMap(model.getDisksAllocationModel()
.getImageToDestinationDomainMap());
param.setConsoleEnabled(model.getIsConsoleDeviceEnabled().getEntity());
param.setVirtioScsiEnabled(model.getIsVirtioScsiEnabled().getEntity());
param.setSoundDeviceEnabled(model.getIsSoundcardEnabled().getEntity());
param.setRngDevice(model.getIsRngEnabled().getEntity() ? model.generateRngDevice() : null);
param.setSoundDeviceEnabled(model.getIsSoundcardEnabled().getEntity());
param.setBalloonEnabled(model.getMemoryBalloonDeviceEnabled().getEntity());
if(model.getIsHeadlessModeEnabled().getEntity()) {
param.getVmStaticData().setDefaultDisplayType(DisplayType.none);
}
BuilderExecutor.build(model, param, new UnitToGraphicsDeviceParamsBuilder());
if (model.getQuota().getSelectedItem() != null) {
vm.setQuotaId(model.getQuota().getSelectedItem().getId());
}
model.startProgress();
if (model.getIsNew()) {
if (model.getIcon().getEntity().isCustom()) {
param.setVmLargeIcon(model.getIcon().getEntity().getIcon());
}
Frontend.getInstance().runMultipleAction(VdcActionType.AddVmPool,
new ArrayList<>(Arrays.asList(new VdcActionParametersBase[]{param})),
result -> {
cancel();
stopProgress();
},
this);
}
else {
Frontend.getInstance().runMultipleAction(VdcActionType.UpdateVmPool,
new ArrayList<>(Arrays.asList(new VdcActionParametersBase[]{param})),
result -> {
cancel();
stopProgress();
},
this);
}
}
protected static VM buildVmOnSave(PoolModel model) {
VM vm = new VM();
BuilderExecutor.build(model, vm.getStaticData(),
new NameUnitToVmBaseBuilder(),
new CoreUnitToVmBaseBuilder(),
new KernelParamsUnitToVmBaseBuilder(),
new MigrationOptionsUnitToVmBaseBuilder(),
new DedicatedVmForVdsUnitToVmBaseBuilder(),
new UsbPolicyUnitToVmBaseBuilder(),
new CpuProfileUnitToVmBaseBuilder());
BuilderExecutor.build(model, vm, new VmSpecificUnitToVmBuilder());
return vm;
}
public void cancel() {
setWindow(null);
}
@Override
protected void onSelectedItemChanged() {
super.onSelectedItemChanged();
updateActionAvailability();
}
@Override
protected void selectedItemsChanged() {
super.selectedItemsChanged();
updateActionAvailability();
}
@Override
protected void selectedItemPropertyChanged(Object sender, PropertyChangedEventArgs e) {
super.selectedItemPropertyChanged(sender, e);
updateActionAvailability();
}
private void updateActionAvailability() {
getEditCommand().setIsExecutionAllowed(getSelectedItem() != null && getSelectedItems() != null
&& getSelectedItems().size() == 1 && hasVms(getSelectedItem()));
getRemoveCommand().setIsExecutionAllowed(getSelectedItems() != null && getSelectedItems().size() > 0);
}
private boolean hasVms(Object selectedItem) {
if (selectedItem instanceof VmPool) {
return ((VmPool) selectedItem).getAssignedVmsCount() != 0;
}
return false;
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getNewCommand()) {
newEntity();
}
if (command == getEditCommand()) {
edit();
}
if (command == getRemoveCommand()) {
remove();
}
if ("Cancel".equals(command.getName())) { //$NON-NLS-1$
cancel();
}
if ("OnSave".equals(command.getName())) { //$NON-NLS-1$
onSave();
}
if ("OnSave_Phase2".equals(command.getName())) { //$NON-NLS-1$
savePoolPostValidation();
setConfirmWindow(null);
}
if ("OnRemove".equals(command.getName())) { //$NON-NLS-1$
onRemove();
}
if ("CancelConfirmation".equals(command.getName())) { //$NON-NLS-1$
cancelConfirmation();
}
}
@Override
protected String getListName() {
return "PoolListModel"; //$NON-NLS-1$
}
public VmPool getCurrentPool() {
return privateCurrentPool;
}
public void setCurrentPool(VmPool privateCurrentPool) {
this.privateCurrentPool = privateCurrentPool;
}
private void cancelConfirmation() {
setConfirmWindow(null);
}
}