package org.ovirt.engine.ui.common.widget.uicommon.popup.vm;
import java.util.ArrayList;
import java.util.Collection;
import org.gwtbootstrap3.client.ui.Container;
import org.ovirt.engine.core.common.businessentities.Quota;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.profiles.DiskProfile;
import org.ovirt.engine.core.common.businessentities.storage.DiskInterface;
import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType;
import org.ovirt.engine.core.common.businessentities.storage.StorageType;
import org.ovirt.engine.core.common.businessentities.storage.VolumeType;
import org.ovirt.engine.ui.common.CommonApplicationConstants;
import org.ovirt.engine.ui.common.CommonApplicationTemplates;
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
import org.ovirt.engine.ui.common.gin.AssetProvider;
import org.ovirt.engine.ui.common.idhandler.ElementIdHandler;
import org.ovirt.engine.ui.common.idhandler.WithElementId;
import org.ovirt.engine.ui.common.widget.Align;
import org.ovirt.engine.ui.common.widget.RadioButtonPanel;
import org.ovirt.engine.ui.common.widget.dialog.InfoIcon;
import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.EntityModelCheckBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.IntegerEntityModelTextBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor;
import org.ovirt.engine.ui.common.widget.renderer.EnumRenderer;
import org.ovirt.engine.ui.common.widget.renderer.NameRenderer;
import org.ovirt.engine.ui.common.widget.renderer.StorageDomainFreeSpaceRenderer;
import org.ovirt.engine.ui.common.widget.uicommon.popup.AbstractModelBoundPopupWidget;
import org.ovirt.engine.ui.common.widget.uicommon.storage.AbstractStorageView;
import org.ovirt.engine.ui.common.widget.uicommon.storage.FcpStorageView;
import org.ovirt.engine.ui.common.widget.uicommon.storage.IscsiStorageView;
import org.ovirt.engine.ui.uicommonweb.Linq;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.FcpStorageModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.IStorageModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.IscsiStorageModel;
import org.ovirt.engine.ui.uicommonweb.models.storage.NewEditStorageModelBehavior;
import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase;
import org.ovirt.engine.ui.uicommonweb.models.storage.StorageModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.AbstractDiskModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
public class VmDiskPopupWidget extends AbstractModelBoundPopupWidget<AbstractDiskModel> {
interface Driver extends UiCommonEditorDriver<AbstractDiskModel, VmDiskPopupWidget> {
}
interface ViewUiBinder extends UiBinder<Container, VmDiskPopupWidget> {
ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
}
interface ViewIdHandler extends ElementIdHandler<VmDiskPopupWidget> {
ViewIdHandler idHandler = GWT.create(ViewIdHandler.class);
}
@UiField
@Path("size.entity")
@WithElementId("size")
IntegerEntityModelTextBoxEditor sizeEditor;
@UiField
@Path("sizeExtend.entity")
StringEntityModelTextBoxEditor sizeExtendEditor;
@UiField
@Path("alias.entity")
@WithElementId("alias")
StringEntityModelTextBoxEditor aliasEditor;
@UiField
@Path("description.entity")
@WithElementId("description")
StringEntityModelTextBoxEditor descriptionEditor;
@UiField(provided = true)
@Path("diskInterface.selectedItem")
@WithElementId("interface")
ListModelListBoxEditor<DiskInterface> interfaceEditor;
@UiField(provided = true)
@Path("dataCenter.selectedItem")
@WithElementId("dataCenter")
ListModelListBoxEditor<StoragePool> datacenterEditor;
@UiField(provided = true)
@Path("storageDomain.selectedItem")
@WithElementId("storageDomain")
ListModelListBoxEditor<StorageDomain> storageDomainEditor;
@UiField(provided = true)
@Path("volumeType.selectedItem")
@WithElementId("volumeType")
ListModelListBoxEditor<VolumeType> volumeTypeEditor;
@UiField(provided = true)
@Path("cinderVolumeType.selectedItem")
@WithElementId("cinderVolumeType")
ListModelListBoxEditor<String> cinderVolumeTypeEditor;
@UiField(provided = true)
@Path("diskProfile.selectedItem")
@WithElementId("diskProfile")
ListModelListBoxEditor<DiskProfile> diskProfileEditor;
@UiField(provided = true)
@Path("quota.selectedItem")
@WithElementId("quota")
ListModelListBoxEditor<Quota> quotaEditor;
@UiField(provided = true)
@Path(value = "host.selectedItem")
@WithElementId("host")
ListModelListBoxEditor<VDS> hostListEditor;
@UiField(provided = true)
@Path(value = "storageType.selectedItem")
@WithElementId("storageType")
ListModelListBoxEditor<StorageType> storageTypeEditor;
@UiField(provided = true)
@Path(value = "isPlugged.entity")
@WithElementId("plugDiskToVm")
EntityModelCheckBoxEditor plugDiskToVmEditor;
@UiField(provided = true)
@Path("isWipeAfterDelete.entity")
@WithElementId("wipeAfterDelete")
EntityModelCheckBoxEditor wipeAfterDeleteEditor;
@UiField(provided = true)
@Path("isBootable.entity")
@WithElementId("isBootable")
EntityModelCheckBoxEditor isBootableEditor;
@UiField(provided = true)
@Path("isShareable.entity")
@WithElementId("isShareable")
EntityModelCheckBoxEditor isShareableEditor;
@UiField(provided = true)
@Path("isReadOnly.entity")
@WithElementId("isReadOnly")
EntityModelCheckBoxEditor isReadOnlyEditor;
@UiField(provided = true)
@Path("passDiscard.entity")
@WithElementId("passDiscard")
EntityModelCheckBoxEditor passDiscardEditor;
@UiField(provided = true)
@Path("isUsingScsiReservation.entity")
@WithElementId("isUsingScsiReservation")
EntityModelCheckBoxEditor isUsingScsiReservationEditor;
@UiField(provided = true)
@Path("isScsiPassthrough.entity")
@WithElementId("isScsiPassthrough")
EntityModelCheckBoxEditor isScsiPassthroughEditor;
@UiField(provided = true)
@Path("isSgIoUnfiltered.entity")
@WithElementId("isSgIoUnfiltered")
EntityModelCheckBoxEditor isSgIoUnfilteredEditor;
@UiField(provided = true)
@Ignore
InfoIcon interfaceInfoIcon;
@UiField(provided = true)
@Ignore
InfoIcon cinderVolumeTypeInfoIcon;
@UiField(provided = true)
@Ignore
InfoIcon scsiReservationInfoIcon;
@UiField
FlowPanel externalDiskPanel;
@UiField
RadioButtonPanel radioButtonPanel;
@UiField
Label message;
@Ignore
IscsiStorageView iscsiStorageView;
@Ignore
FcpStorageView fcpStorageView;
@Ignore
AbstractStorageView storageView;
private static final CommonApplicationTemplates templates = AssetProvider.getTemplates();
@UiField(provided = true)
static final CommonApplicationConstants constants = AssetProvider.getConstants();
private final Driver driver = GWT.create(Driver.class);
boolean isNewLunDiskEnabled;
StorageModel storageModel;
IscsiStorageModel iscsiStorageModel;
FcpStorageModel fcpStorageModel;
SanStorageModelBase sanStorageModelBase;
public VmDiskPopupWidget(boolean isLunDiskEnabled) {
this.isNewLunDiskEnabled = isLunDiskEnabled;
initManualWidgets();
initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
ViewIdHandler.idHandler.generateAndSetIds(this);
driver.initialize(this);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initManualWidgets() {
storageDomainEditor = new ListModelListBoxEditor<>(new StorageDomainFreeSpaceRenderer());
hostListEditor = new ListModelListBoxEditor<>(new NameRenderer<VDS>());
diskProfileEditor = new ListModelListBoxEditor<>(new NameRenderer<DiskProfile>());
quotaEditor = new ListModelListBoxEditor<>(new NameRenderer<Quota>());
interfaceEditor = new ListModelListBoxEditor<>(new EnumRenderer());
datacenterEditor = new ListModelListBoxEditor<>(new NameRenderer<StoragePool>());
cinderVolumeTypeEditor = new ListModelListBoxEditor<>();
volumeTypeEditor = new ListModelListBoxEditor<>(new EnumRenderer());
storageTypeEditor = new ListModelListBoxEditor<>(new EnumRenderer());
plugDiskToVmEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
wipeAfterDeleteEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isBootableEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isShareableEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isReadOnlyEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
passDiscardEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isUsingScsiReservationEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isScsiPassthroughEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
isSgIoUnfilteredEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
interfaceInfoIcon = new InfoIcon(templates.italicText(constants.diskInterfaceInfo()));
cinderVolumeTypeInfoIcon = new InfoIcon(templates.italicText(constants.cinderVolumeTypeInfoIcon()));
scsiReservationInfoIcon = new InfoIcon(templates.italicText(constants.scsiReservationInfoIcon()));
}
@Override
public void focusInput() {
sizeEditor.setFocus(true);
}
@Override
public void edit(final AbstractDiskModel disk) {
driver.edit(disk);
disk.getIsDirectLunDiskAvaialable().getEntityChangedEvent().addListener((ev, sender, args) -> {
boolean isDirectLunDiskAvaialable = ((EntityModel<Boolean>) sender).getEntity();
externalDiskPanel.setVisible(isDirectLunDiskAvaialable);
});
disk.getIsUsingScsiReservation().getEntityChangedEvent().addListener((ev, sender, args) -> scsiReservationInfoIcon.setVisible(disk.getIsUsingScsiReservation().getEntity()));
disk.getIsVirtioScsiEnabled().getEntityChangedEvent().addListener((ev, sender, args) -> {
if (disk.getVm() == null) {
// not relevant for floating disks
return;
}
boolean isVirtioScsiEnabled = Boolean.TRUE.equals(((EntityModel) sender).getEntity());
// Show the info icon if VirtIO-SCSI is supported by the cluster but disabled for the VM
interfaceInfoIcon.setVisible(!isVirtioScsiEnabled);
});
disk.getCinderVolumeType().getItemsChangedEvent().addListener((ev, sender, args) -> {
Collection<String> volumeTypes = disk.getCinderVolumeType().getItems();
cinderVolumeTypeInfoIcon.setVisible(volumeTypes == null || volumeTypes.isEmpty());
});
disk.getIsModelDisabled().getEntityChangedEvent().addListener((ev, sender, args) -> {
if (disk.getIsModelDisabled().getEntity()) {
disableWidget(getWidget());
enableWidget(radioButtonPanel);
enableWidget(datacenterEditor);
disk.getDefaultCommand().setIsExecutionAllowed(false);
disk.setIsChangeable(false);
} else {
enableWidget(getWidget());
disk.getDefaultCommand().setIsExecutionAllowed(true);
disk.setIsChangeable(true);
driver.edit(disk);
}
});
radioButtonPanel.addRadioButton(constants.imageDisk(),
disk.getDisk() == null || disk.getDisk().getDiskStorageType() == DiskStorageType.IMAGE,
disk.getIsNew(),
event -> {
if (disk.getIsNew()) {
disk.getDiskStorageType().setEntity(DiskStorageType.IMAGE);
revealDiskPanel(disk);
}
});
radioButtonPanel.addRadioButton(constants.directLunDisk(),
disk.getDisk() != null && disk.getDisk().getDiskStorageType() == DiskStorageType.LUN,
disk.getIsNew(),
event -> {
if (disk.getIsNew()) {
disk.getDiskStorageType().setEntity(DiskStorageType.LUN);
revealStorageView(disk);
revealDiskPanel(disk);
}
});
radioButtonPanel.addRadioButton(constants.cinderDisk(),
disk.getDisk() != null && disk.getDisk().getDiskStorageType() == DiskStorageType.CINDER,
disk.getIsNew(),
event -> {
if (disk.getIsNew()) {
disk.getDiskStorageType().setEntity(DiskStorageType.CINDER);
revealDiskPanel(disk);
}
});
if (disk.getStorageModel() == null) {
storageModel = new StorageModel(new NewEditStorageModelBehavior());
// Create IscsiStorageModel
iscsiStorageModel = new IscsiStorageModel();
iscsiStorageModel.setContainer(storageModel);
iscsiStorageModel.setIsGrouppedByTarget(true);
iscsiStorageModel.setIgnoreGrayedOut(true);
// Create FcpStorageModel
fcpStorageModel = new FcpStorageModel();
fcpStorageModel.setContainer(storageModel);
fcpStorageModel.setIsGrouppedByTarget(false);
fcpStorageModel.setIgnoreGrayedOut(true);
// Set 'StorageModel' items
ArrayList<IStorageModel> items = new ArrayList<>();
items.add(iscsiStorageModel);
items.add(fcpStorageModel);
storageModel.setStorageModels(items);
storageModel.setHost(disk.getHost());
disk.setStorageModel(storageModel);
} else {
storageModel = disk.getStorageModel();
iscsiStorageModel = Linq.findByType(storageModel.getStorageModels(), IscsiStorageModel.class);
iscsiStorageModel.getPropertyChangedEvent().clearListeners();
fcpStorageModel = Linq.findByType(storageModel.getStorageModels(), FcpStorageModel.class);
fcpStorageModel.getPropertyChangedEvent().clearListeners();
}
iscsiStorageView = new IscsiStorageView(false, 196, 304, 244, 275, 142, 55, -67);
iscsiStorageView.setBarTop(0, Unit.PX);
iscsiStorageView.edit(iscsiStorageModel);
fcpStorageView = new FcpStorageView(false, 278, 240);
fcpStorageView.edit(fcpStorageModel);
// SelectedItemChangedEvent handlers
disk.getStorageType().getSelectedItemChangedEvent().addListener((ev, sender, args) -> revealStorageView(disk));
disk.getHost().getSelectedItemChangedEvent().addListener((ev, sender, args) -> revealStorageView(disk));
disk.getDiskStorageType().getPropertyChangedEvent().addListener((ev, sender, args) -> {
String propName = args.propertyName;
if ("IsChangable".equals(propName)) { //$NON-NLS-1$
if (disk.getDiskStorageType().getIsChangable() && disk.isEditEnabled()) {
enableWidget(radioButtonPanel);
} else {
disableWidget(radioButtonPanel);
}
}
});
revealStorageView(disk);
revealDiskPanel(disk);
}
private void revealDiskPanel(final AbstractDiskModel disk) {
boolean isInVm = disk.getVm() != null;
// Disk type (internal/external) selection panel is visible only when
// 'Attach disk' mode is enabled or new LunDisk creation is enabled
radioButtonPanel.setVisible(isNewLunDiskEnabled);
externalDiskPanel.setVisible(isNewLunDiskEnabled && disk.getDiskStorageType().getEntity() == DiskStorageType.LUN);
aliasEditor.setFocus(!isInVm);
}
private void revealStorageView(final AbstractDiskModel diskModel) {
if (!diskModel.getIsNew()) {
return;
}
StorageType storageType = diskModel.getStorageType().getSelectedItem();
// Set view and model by storage type
if (storageType == StorageType.ISCSI) {
storageView = iscsiStorageView;
sanStorageModelBase = iscsiStorageModel;
}
else if (storageType == StorageType.FCP) {
storageView = fcpStorageView;
sanStorageModelBase = fcpStorageModel;
}
storageModel.setCurrentStorageItem(sanStorageModelBase);
diskModel.setSanStorageModelBase(sanStorageModelBase);
// Execute 'UpdateCommand' to call 'GetDeviceList'
sanStorageModelBase.getUpdateCommand().execute();
sanStorageModelBase.setWidgetModel(diskModel);
externalDiskPanel.clear();
externalDiskPanel.add(storageView);
}
public boolean handleEnterKeyDisabled() {
return storageView != null && storageView.isSubViewFocused();
}
@Override
public AbstractDiskModel flush() {
return driver.flush();
}
@Override
public void cleanup() {
driver.cleanup();
}
@Override
public int setTabIndexes(int nextTabIndex) {
sizeEditor.setTabIndex(nextTabIndex++);
sizeExtendEditor.setTabIndex(nextTabIndex++);
aliasEditor.setTabIndex(nextTabIndex++);
descriptionEditor.setTabIndex(nextTabIndex++);
interfaceEditor.setTabIndex(nextTabIndex++);
datacenterEditor.setTabIndex(nextTabIndex++);
storageDomainEditor.setTabIndex(nextTabIndex++);
volumeTypeEditor.setTabIndex(nextTabIndex++);
cinderVolumeTypeEditor.setTabIndex(nextTabIndex++);
diskProfileEditor.setTabIndex(nextTabIndex++);
quotaEditor.setTabIndex(nextTabIndex++);
hostListEditor.setTabIndex(nextTabIndex++);
storageTypeEditor.setTabIndex(nextTabIndex++);
plugDiskToVmEditor.setTabIndex(nextTabIndex++);
wipeAfterDeleteEditor.setTabIndex(nextTabIndex++);
isBootableEditor.setTabIndex(nextTabIndex++);
isShareableEditor.setTabIndex(nextTabIndex++);
isReadOnlyEditor.setTabIndex(nextTabIndex++);
passDiscardEditor.setTabIndex(nextTabIndex++);
isScsiPassthroughEditor.setTabIndexes(nextTabIndex++);
isSgIoUnfilteredEditor.setTabIndex(nextTabIndex++);
isUsingScsiReservationEditor.setTabIndex(nextTabIndex++);
return nextTabIndex;
}
}