package org.ovirt.engine.ui.uicommonweb.models.disks;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.ovirt.engine.core.common.action.ChangeQuotaParameters;
import org.ovirt.engine.core.common.action.GetDiskAlignmentParameters;
import org.ovirt.engine.core.common.action.RemoveDiskParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.VmEntityType;
import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
import org.ovirt.engine.core.common.businessentities.storage.Disk;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType;
import org.ovirt.engine.core.common.businessentities.storage.ImageStatus;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.mode.ApplicationMode;
import org.ovirt.engine.core.common.queries.SearchParameters;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.searchbackend.SearchObjects;
import org.ovirt.engine.ui.frontend.Frontend;
import org.ovirt.engine.ui.uicommonweb.UICommand;
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.configure.PermissionListModel;
import org.ovirt.engine.ui.uicommonweb.models.quota.ChangeQuotaItemModel;
import org.ovirt.engine.ui.uicommonweb.models.quota.ChangeQuotaModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.ExportRepoImageModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase;
import org.ovirt.engine.ui.uicommonweb.models.storage.UploadImageModel;
import org.ovirt.engine.ui.uicommonweb.models.templates.CopyDiskModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.AbstractDiskModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.MoveDiskModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.NewDiskModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.RemoveDiskModel;
import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
import org.ovirt.engine.ui.uicompat.ConstantsManager;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
import com.google.inject.Inject;
public class DiskListModel extends ListWithSimpleDetailsModel<Void, Disk> implements ISupportSystemTreeContext {
private UICommand privateNewCommand;
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 UICommand privateMoveCommand;
public UICommand getMoveCommand() {
return privateMoveCommand;
}
private void setMoveCommand(UICommand value) {
privateMoveCommand = value;
}
private UICommand privateScanAlignmentCommand;
public UICommand getScanAlignmentCommand() {
return privateScanAlignmentCommand;
}
private void setScanAlignmentCommand(UICommand value) {
privateScanAlignmentCommand = value;
}
private UICommand exportCommand;
public UICommand getExportCommand() {
return exportCommand;
}
public void setExportCommand(UICommand exportCommand) {
this.exportCommand = exportCommand;
}
private UICommand privateChangeQuotaCommand;
public UICommand getChangeQuotaCommand() {
return privateChangeQuotaCommand;
}
private void setChangeQuotaCommand(UICommand value) {
privateChangeQuotaCommand = value;
}
private UICommand privateCopyCommand;
public UICommand getCopyCommand() {
return privateCopyCommand;
}
private void setCopyCommand(UICommand value) {
privateCopyCommand = value;
}
private UICommand privateUploadCommand;
public UICommand getUploadCommand() {
return privateUploadCommand;
}
private void setUploadCommand(UICommand value) {
privateUploadCommand= value;
}
private UICommand privateCancelUploadCommand;
public UICommand getCancelUploadCommand() {
return privateCancelUploadCommand;
}
private void setCancelUploadCommand(UICommand value) {
privateCancelUploadCommand = value;
}
private UICommand privatePauseUploadCommand;
public UICommand getPauseUploadCommand() {
return privatePauseUploadCommand;
}
private void setPauseUploadCommand(UICommand value) {
privatePauseUploadCommand = value;
}
private UICommand privateResumeUploadCommand;
public UICommand getResumeUploadCommand() {
return privateResumeUploadCommand;
}
private void setResumeUploadCommand(UICommand value) {
privateResumeUploadCommand = value;
}
private EntityModel<DiskStorageType> diskViewType;
public EntityModel<DiskStorageType> getDiskViewType() {
return diskViewType;
}
public void setDiskViewType(EntityModel<DiskStorageType> diskViewType) {
this.diskViewType = diskViewType;
}
private SystemTreeItemModel systemTreeSelectedItem;
@Override
public SystemTreeItemModel getSystemTreeSelectedItem() {
return systemTreeSelectedItem;
}
@Override
public void setSystemTreeSelectedItem(SystemTreeItemModel value) {
systemTreeSelectedItem = value;
onPropertyChanged(new PropertyChangedEventArgs("SystemTreeSelectedItem")); //$NON-NLS-1$
}
private final DiskVmListModel diskVmListModel;
private final DiskTemplateListModel diskTemplateListModel;
private final DiskStorageListModel diskStorageListModel;
@Inject
public DiskListModel(final DiskVmListModel diskVmListModel, final DiskTemplateListModel diskTemplateListModel,
final DiskStorageListModel diskStorageListModel, final DiskGeneralModel diskGeneralModel,
final PermissionListModel<Disk> permissionListModel) {
this.diskVmListModel = diskVmListModel;
this.diskTemplateListModel = diskTemplateListModel;
this.diskStorageListModel = diskStorageListModel;
setDetailList(diskGeneralModel, permissionListModel);
setTitle(ConstantsManager.getInstance().getConstants().disksTitle());
setApplicationPlace(WebAdminApplicationPlaces.diskMainTabPlace);
setDefaultSearchString("Disks: disk_type = image"); //$NON-NLS-1$
setSearchString(getDefaultSearchString());
setSearchObjects(new String[] { SearchObjects.DISK_OBJ_NAME, SearchObjects.DISK_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$
setMoveCommand(new UICommand("Move", this)); //$NON-NLS-1$
setChangeQuotaCommand(new UICommand("changeQuota", this)); //$NON-NLS-1$
setCopyCommand(new UICommand("Copy", this)); //$NON-NLS-1$
setScanAlignmentCommand(new UICommand("Check Alignment", this)); //$NON-NLS-1$
setExportCommand(new UICommand("Export", this)); //$NON-NLS-1$
setUploadCommand(new UICommand("Upload", this)); //$NON-NLS-1$
setCancelUploadCommand(new UICommand("CancelUpload", this)); //$NON-NLS-1$
setPauseUploadCommand(new UICommand("PauseUpload", this)); //$NON-NLS-1$
setResumeUploadCommand(new UICommand("ResumeUpload", this)); //$NON-NLS-1$
updateActionAvailability();
getSearchNextPageCommand().setIsAvailable(true);
getSearchPreviousPageCommand().setIsAvailable(true);
setDiskViewType(new EntityModel<DiskStorageType>());
}
private void setDetailList(final DiskGeneralModel diskGeneralModel,
final PermissionListModel<Disk> permissionListModel) {
diskVmListModel.setIsAvailable(false);
diskTemplateListModel.setIsAvailable(false);
diskStorageListModel.setIsAvailable(false);
List<HasEntity<? extends Disk>> list = new ArrayList<>();
list.add(diskGeneralModel);
list.add(diskVmListModel);
list.add(diskTemplateListModel);
list.add(diskStorageListModel);
list.add(permissionListModel);
// TODO: find better type bound for list
setDetailModels((List) list);
}
@Override
protected void syncSearch() {
SearchParameters tempVar = new SearchParameters(applySortOptions(getSearchString()), SearchType.Disk, isCaseSensitiveSearch());
tempVar.setMaxCount(getSearchPageSize());
super.syncSearch(VdcQueryType.Search, tempVar);
}
@Override
public boolean supportsServerSideSorting() {
return true;
}
@Override
public void setItems(Collection<Disk> disks) {
if (disks == null) {
super.setItems(null);
return;
}
super.setItems(disks);
}
@Override
protected void updateDetailsAvailability() {
if (getSelectedItem() != null) {
Disk disk = getSelectedItem();
diskVmListModel.setIsAvailable(disk.getVmEntityType() == null || !disk.getVmEntityType().isTemplateType());
diskTemplateListModel.setIsAvailable(disk.getVmEntityType() != null && disk.getVmEntityType().isTemplateType());
diskStorageListModel.setIsAvailable(disk.getDiskStorageType() == DiskStorageType.IMAGE ||
disk.getDiskStorageType() == DiskStorageType.CINDER);
}
}
public void cancel() {
setWindow(null);
}
@Override
protected void onSelectedItemChanged() {
super.onSelectedItemChanged();
updateActionAvailability();
}
@Override
protected void selectedItemsChanged() {
super.selectedItemsChanged();
updateActionAvailability();
}
private void newEntity() {
NewDiskModel model = new NewDiskModel(getSystemTreeSelectedItem());
model.setTitle(ConstantsManager.getInstance().getConstants().newVirtualDiskTitle());
model.setHelpTag(HelpTag.new_virtual_disk);
model.setHashName("new_virtual_disk"); //$NON-NLS-1$
setWindow(model);
UICommand cancelCommand = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.setCancelCommand(cancelCommand);
model.initialize();
}
private void edit() {
}
private void move() {
ArrayList<DiskImage> disks = (ArrayList<DiskImage>) asImages(getSelectedItems());
if (disks == null || getWindow() != null) {
return;
}
MoveDiskModel model = new MoveDiskModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().moveDisksTitle());
model.setHelpTag(HelpTag.move_disks);
model.setHashName("move_disks"); //$NON-NLS-1$
model.setIsSourceStorageDomainNameAvailable(true);
model.setEntity(this);
model.init(disks);
model.startProgress();
}
private void scanAlignment() {
ArrayList<VdcActionParametersBase> parameterList = new ArrayList<>();
for (Disk disk : getSelectedItems()) {
parameterList.add(new GetDiskAlignmentParameters(disk.getId()));
}
Frontend.getInstance().runMultipleAction(VdcActionType.GetDiskAlignment, parameterList,
result -> {
},
this);
}
private void export() {
@SuppressWarnings("unchecked")
ArrayList<DiskImage> disks = (ArrayList<DiskImage>) asImages(getSelectedItems());
if (disks == null || getWindow() != null) {
return;
}
ExportRepoImageModel model = new ExportRepoImageModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().exportImagesTitle());
model.setHelpTag(HelpTag.export_disks);
model.setHashName("export_disks"); //$NON-NLS-1$
model.setEntity(this);
model.init(disks);
UICommand cancelCommand = UICommand.createCancelUiCommand("Cancel", this); //$NON-NLS-1$
model.setCancelCommand(cancelCommand);
model.getCommands().add(cancelCommand);
}
private void changeQuota() {
ArrayList<DiskImage> disks = (ArrayList<DiskImage>) asImages(getSelectedItems());
if (disks == null || getWindow() != null) {
return;
}
ChangeQuotaModel model = new ChangeQuotaModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().assignQuotaForDisk());
model.setHelpTag(HelpTag.change_quota_disks);
model.setHashName("change_quota_disks"); //$NON-NLS-1$
model.startProgress();
model.init(disks);
UICommand command = UICommand.createDefaultOkUiCommand("onChangeQuota", this); //$NON-NLS-1$
model.getCommands().add(command);
model.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$
}
private void onChangeQuota() {
ChangeQuotaModel model = (ChangeQuotaModel) getWindow();
ArrayList<VdcActionParametersBase> paramerterList = new ArrayList<>();
for (ChangeQuotaItemModel item : model.getItems()) {
ChangeQuotaItemModel itemModel = item;
DiskImage disk = itemModel.getEntity();
VdcActionParametersBase parameters =
new ChangeQuotaParameters(itemModel.getQuota().getSelectedItem().getId(),
disk.getId(),
itemModel.getStorageDomainId(),
disk.getStoragePoolId());
paramerterList.add(parameters);
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.ChangeQuotaForDisk, paramerterList,
result -> {
DiskListModel localModel = (DiskListModel) result.getState();
localModel.stopProgress();
cancel();
},
this);
}
private void copy() {
ArrayList<DiskImage> disks = (ArrayList<DiskImage>) asImages(getSelectedItems());
if (disks == null || getWindow() != null) {
return;
}
CopyDiskModel model = new CopyDiskModel();
setWindow(model);
model.setTitle(ConstantsManager.getInstance().getConstants().copyDisksTitle());
model.setHelpTag(HelpTag.copy_disks);
model.setHashName("copy_disks"); //$NON-NLS-1$
model.setEntity(this);
model.init(disks);
model.startProgress();
}
private void remove() {
if (getWindow() != null) {
return;
}
RemoveDiskModel model = new RemoveDiskModel();
setWindow(model);
model.initialize(null, getSelectedItems(), this);
model.getLatch().setIsAvailable(false);
}
private void onRemove() {
RemoveDiskModel model = (RemoveDiskModel) getWindow();
ArrayList<VdcActionParametersBase> paramerterList = new ArrayList<>();
for (Object item : getSelectedItems()) {
Disk disk = (Disk) item;
VdcActionParametersBase parameters = new RemoveDiskParameters(disk.getId());
paramerterList.add(parameters);
}
model.startProgress();
Frontend.getInstance().runMultipleAction(VdcActionType.RemoveDisk, paramerterList,
result -> {
DiskListModel localModel = (DiskListModel) result.getState();
localModel.stopProgress();
cancel();
},
this);
}
private void upload() {
if (getWindow() != null) {
return;
}
UploadImageModel.showUploadDialog(
this,
HelpTag.upload_disk_image,
null,
null);
}
private void resumeUpload() {
if (getSelectedItem() == null || getWindow() != null) {
return;
}
UploadImageModel.showUploadDialog(
this,
HelpTag.resume_upload_image,
null,
(DiskImage) getSelectedItem());
}
private void cancelUpload() {
UploadImageModel.showCancelUploadDialog(this, HelpTag.cancel_upload_image, getSelectedItems());
}
private void onCancelUpload() {
UploadImageModel.onCancelUpload((ConfirmationModel) getWindow(), getSelectedItems());
}
private void pauseUpload() {
if (getWindow() != null) {
return;
}
UploadImageModel.pauseUploads(getSelectedItems());
}
private void updateActionAvailability() {
Disk disk = getSelectedItem();
ArrayList<Disk> disks = getSelectedItems() != null ? (ArrayList<Disk>) getSelectedItems() : null;
boolean shouldAllowEdit = true;
if (disk != null) {
shouldAllowEdit = !disk.isOvfStore() && !isDiskLocked(disk);
}
getNewCommand().setIsExecutionAllowed(true);
getEditCommand().setIsExecutionAllowed(disk != null && disks != null && disks.size() == 1 && shouldAllowEdit);
getRemoveCommand().setIsExecutionAllowed(disks != null && disks.size() > 0 && isRemoveCommandAvailable());
getScanAlignmentCommand().setIsExecutionAllowed(
disks != null && disks.size() > 0 && isScanAlignmentCommandAvailable());
getExportCommand().setIsExecutionAllowed(isExportCommandAvailable());
updateCopyAndMoveCommandAvailability(disks);
ChangeQuotaModel.updateChangeQuotaActionAvailability(getItems() != null ? getItems() : null,
getSelectedItems() != null ? getSelectedItems() : null,
getSystemTreeSelectedItem(),
getChangeQuotaCommand());
getCancelUploadCommand().setIsExecutionAllowed(UploadImageModel.isCancelAllowed(disks));
getPauseUploadCommand().setIsExecutionAllowed(UploadImageModel.isPauseAllowed(disks));
getResumeUploadCommand().setIsExecutionAllowed(UploadImageModel.isResumeAllowed(disks));
}
private boolean isDiskLocked(Disk disk) {
switch (disk.getDiskStorageType()) {
case IMAGE:
return ((DiskImage) disk).getImageStatus() == ImageStatus.LOCKED;
case CINDER:
return ((CinderDisk) disk).getImageStatus() == ImageStatus.LOCKED;
}
return false;
}
private void updateCopyAndMoveCommandAvailability(List<Disk> disks) {
boolean isCopyAllowed = true;
boolean isMoveAllowed = true;
if (disks == null || disks.isEmpty() || disks.get(0).getDiskStorageType() != DiskStorageType.IMAGE) {
disableMoveAndCopyCommands();
return;
}
Guid datacenterId = ((DiskImage) disks.get(0)).getStoragePoolId();
boolean foundTemplateDisk = false;
boolean foundVmDisk = false;
boolean foundUnattachedDisk = false;
for (Disk disk : disks) {
if ((!isCopyAllowed && !isMoveAllowed) || disk.getDiskStorageType() != DiskStorageType.IMAGE) {
disableMoveAndCopyCommands();
return;
}
DiskImage diskImage = (DiskImage) disk;
if (diskImage.getImageStatus() != ImageStatus.OK || !datacenterId.equals(diskImage.getStoragePoolId()) || diskImage.isOvfStore()) {
disableMoveAndCopyCommands();
return;
}
VmEntityType vmEntityType = disk.getVmEntityType();
if (vmEntityType == null) {
foundUnattachedDisk = true;
} else if (vmEntityType.isTemplateType()) {
foundTemplateDisk = true;
} else if (vmEntityType.isVmType()) {
foundVmDisk = true;
}
if (foundTemplateDisk && (foundUnattachedDisk || foundVmDisk)) {
isCopyAllowed = false;
}
if (vmEntityType != null && vmEntityType.isTemplateType()) {
isMoveAllowed = false;
}
}
getCopyCommand().setIsExecutionAllowed(isCopyAllowed);
getMoveCommand().setIsExecutionAllowed(isMoveAllowed);
}
private void disableMoveAndCopyCommands() {
getCopyCommand().setIsExecutionAllowed(false);
getMoveCommand().setIsExecutionAllowed(false);
}
private boolean isRemoveCommandAvailable() {
List<Disk> disks = getSelectedItems() != null ? getSelectedItems() : new ArrayList<Disk>();
for (Disk disk : disks) {
// check if the disk is template disk
if (disk.getVmEntityType() != null && disk.getVmEntityType().isTemplateType()) {
return false;
}
if (disk.getDiskStorageType() == DiskStorageType.IMAGE || disk.getDiskStorageType() == DiskStorageType.CINDER) {
ImageStatus imageStatus = ((DiskImage) disk).getImageStatus();
if (imageStatus == ImageStatus.LOCKED) {
return false;
}
if (disk.isOvfStore() && imageStatus != ImageStatus.ILLEGAL) {
return false;
}
}
}
return true;
}
private boolean isScanAlignmentCommandAvailable() {
List<Disk> disks = getSelectedItems() != null ? getSelectedItems() : new ArrayList<Disk>();
for (Disk disk : disks) {
if (disk.getDiskStorageType() == DiskStorageType.IMAGE &&
((DiskImage) disk).getImageStatus() != ImageStatus.OK) {
return false;
}
}
return true;
}
private boolean isExportCommandAvailable() {
List<DiskImage> disks = asImages(getSelectedItems());
if (disks == null || disks.isEmpty()) {
return false;
}
for (Disk disk : disks) {
if (disk.getDiskStorageType() != DiskStorageType.IMAGE) {
return false;
}
DiskImage diskImage = (DiskImage) disk;
if (diskImage.getImageStatus() != ImageStatus.OK || !diskImage.getParentId().equals(Guid.Empty)) {
return false;
}
}
return true;
}
private void cancelConfirm() {
AbstractDiskModel model = (AbstractDiskModel) getWindow();
SanStorageModelBase sanStorageModelBase = model.getSanStorageModelBase();
sanStorageModelBase.setForce(false);
setConfirmWindow(null);
}
@Override
public void executeCommand(UICommand command) {
super.executeCommand(command);
if (command == getNewCommand()) {
newEntity();
}
else if (command == getEditCommand()) {
edit();
}
else if (command == getRemoveCommand()) {
remove();
}
else if (command == getMoveCommand()) {
move();
}
else if (command == getCopyCommand()) {
copy();
}
else if (command == getScanAlignmentCommand()) {
scanAlignment();
}
else if (command == getExportCommand()) {
export();
}
else if (RemoveDiskModel.CANCEL_REMOVE.equals(command.getName()) || "Cancel".equals(command.getName())) { //$NON-NLS-1$
cancel();
}
else if ("CancelConfirm".equals(command.getName())) { //$NON-NLS-1$
cancelConfirm();
}
else if (RemoveDiskModel.ON_REMOVE.equals(command.getName())) {
onRemove();
} else if (command == getChangeQuotaCommand()) {
changeQuota();
} else if (command.getName().equals("onChangeQuota")) { //$NON-NLS-1$
onChangeQuota();
}
else if (command == getUploadCommand()) {
upload();
}
else if (command == getCancelUploadCommand()) {
cancelUpload();
}
else if ("OnCancelUpload".equals(command.getName())) { //$NON-NLS-1$
onCancelUpload();
}
else if (command == getPauseUploadCommand()) {
pauseUpload();
}
else if (command == getResumeUploadCommand()) {
resumeUpload();
}
}
private List<DiskImage> asImages(List<Disk> disks) {
if (disks == null) {
return null;
}
List<DiskImage> res = new ArrayList<>();
for (Disk disk : disks) {
if (disk.getDiskStorageType().isInternal()) {
res.add((DiskImage) disk);
}
}
return res;
}
@Override
public boolean isSearchStringMatch(String searchString) {
return searchString.trim().toLowerCase().startsWith("disk"); //$NON-NLS-1$
}
@Override
protected String getListName() {
return "DiskListModel"; //$NON-NLS-1$
}
}