Shubhendu Tripathi has uploaded a new change for review. Change subject: webadmin: UI for gluster volume snapshots ......................................................................
webadmin: UI for gluster volume snapshots Introduced UI dialog for gluster volume snapshot creation and a subtab to list the snapshots details. Change-Id: I5161753920ef72c245f1785e754df97465a19602 Signed-off-by: Shubhendu Tripathi <[email protected]> --- M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeSnapshotEntity.java M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/place/WebAdminApplicationPlaces.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java M frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/ClientGinjectorExtension.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/gluster/SubTabGlusterVolumeSnapshotPresenter.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/gluster/SubTabGlusterVolumeSnapshotView.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusCell.java A frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusColumn.java 24 files changed, 1,165 insertions(+), 186 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/34/36334/1 diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeSnapshotEntity.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeSnapshotEntity.java index edc3907..bde66d4 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeSnapshotEntity.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeSnapshotEntity.java @@ -133,4 +133,9 @@ return true; } + + @Override + public Object getQueryableId() { + return this.snapshotId; + } } diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index e568410..af5d542 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -2867,6 +2867,9 @@ @DefaultStringValue("Cannot ${action} ${type}. Gluster Volume is down.") String ACTION_TYPE_FAILED_GLUSTER_VOLUME_IS_DOWN(); + @DefaultStringValue("Cannot ${action} ${type}. Gluster volume is not thinly provisioned") + String ACTION_TYPE_FAILED_GLUSTER_VOLUME_IS_NOT_THINLY_PROVISIONED(); + @DefaultStringValue("Cannot ${action} ${type}. Cannot remove all the bricks from a Volume.") String ACTION_TYPE_FAILED_CAN_NOT_REMOVE_ALL_BRICKS_FROM_VOLUME(); diff --git a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml index 11bccb2..7f5cf11 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml +++ b/frontend/webadmin/modules/gwt-common/src/main/resources/org/ovirt/engine/core/Common.gwt.xml @@ -355,6 +355,8 @@ <include name="common/businessentities/gluster/GlusterGeoRepSession.java"/> <include name="common/businessentities/gluster/GlusterGeoRepSessionDetails.java"/> <include name="common/businessentities/gluster/GlusterGeoRepSessionConfiguration.java"/> + <include name="common/businessentities/gluster/GlusterVolumeSnapshotEntity.java"/> + <include name="common/businessentities/gluster/GlusterSnapshotStatus.java"/> <!-- Scheduling --> <include name="common/scheduling/*.java"/> <include name="common/scheduling/parameters/*.java"/> diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java index 07cf87f..e9e7f1a 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java @@ -41,6 +41,7 @@ import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession; import org.ovirt.engine.core.common.businessentities.network.HostNetworkQos; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.core.common.businessentities.network.Network; import org.ovirt.engine.core.common.businessentities.network.NetworkInterface; import org.ovirt.engine.core.common.businessentities.network.NetworkQoS; @@ -139,6 +140,15 @@ } } + public static class GlusterVolumeSnapshotComparer implements Comparator<GlusterVolumeSnapshotEntity>, Serializable { + private static final long serialVersionUID = -6085272225112945249L; + + @Override + public int compare(GlusterVolumeSnapshotEntity snapshot0, GlusterVolumeSnapshotEntity snapshot1) { + return snapshot0.getSnapshotName().compareTo(snapshot1.getSnapshotName()); + } + } + public static class DiskImageByLastModifiedComparer implements Comparator<DiskImage>, Serializable { diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java index b11a5a4..451db51 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/dataprovider/AsyncDataProvider.java @@ -77,6 +77,7 @@ import org.ovirt.engine.core.common.businessentities.gluster.GlusterHookEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.core.common.businessentities.gluster.ServiceType; import org.ovirt.engine.core.common.businessentities.network.HostNetworkQos; import org.ovirt.engine.core.common.businessentities.network.Network; @@ -1580,6 +1581,16 @@ Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeGeoRepSessions, new IdQueryParameters(masterVolumeId), aQuery); } + public void getGlusterVolumeSnapshotsForVolume(AsyncQuery aQuery, Guid volumeId) { + aQuery.converterCallback = new IAsyncConverter() { + @Override + public Object Convert(Object source, AsyncQuery asyncQuery) { + return source != null ? source : new ArrayList<GlusterVolumeSnapshotEntity>(); + } + }; + Frontend.getInstance().runQuery(VdcQueryType.GetGlusterVolumeSnapshotsByVolumeId, new IdQueryParameters(volumeId), aQuery); + } + public void getGlusterHook(AsyncQuery aQuery, Guid hookId, boolean includeServerHooks) { aQuery.converterCallback = new IAsyncConverter() { @Override diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java index 55ec0a6..30a9ae2 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/help/HelpTag.java @@ -332,6 +332,8 @@ new_volume("new_volume", HelpTagType.WEBADMIN, "[gluster] Volumes main tab -> New"), //$NON-NLS-1$ //$NON-NLS-2$ + new_volume_snapshot("new_volume_snapshot", HelpTagType.WEBADMIN, "[gluster] Volumes main tab -> Snapshot -> New"), //$NON-NLS-1$ //$NON-NLS-2$ + parameters("parameters", HelpTagType.UNKNOWN), //$NON-NLS-1$ permissions("permissions", HelpTagType.UNKNOWN), //$NON-NLS-1$ @@ -482,6 +484,8 @@ volume_stop("volume_stop", HelpTagType.WEBADMIN, "Volumes Tab > Stop Volume"), //$NON-NLS-1$ //$NON-NLS-2$ + volume_snapshots("volume_snapshots", HelpTagType.WEBADMIN), //$NON-NLS-1$ + new_role("new_role", HelpTagType.WEBADMIN), //$NON-NLS-1$ edit_role("edit_role", HelpTagType.WEBADMIN), //$NON-NLS-1$ diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java new file mode 100644 index 0000000..8815df0 --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotListModel.java @@ -0,0 +1,187 @@ +package org.ovirt.engine.ui.uicommonweb.models.gluster; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; +import org.ovirt.engine.core.common.action.gluster.CreateGlusterVolumeSnapshotParameters; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.ui.frontend.AsyncQuery; +import org.ovirt.engine.ui.frontend.Frontend; +import org.ovirt.engine.ui.frontend.INewAsyncCallback; +import org.ovirt.engine.ui.uicommonweb.Linq; +import org.ovirt.engine.ui.uicommonweb.UICommand; +import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; +import org.ovirt.engine.ui.uicommonweb.help.HelpTag; +import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel; +import org.ovirt.engine.ui.uicompat.ConstantsManager; +import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult; +import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback; +import org.ovirt.engine.ui.uicompat.UIConstants; + +public class GlusterVolumeSnapshotListModel extends SearchableListModel { + + private UICommand newSnapshotCommand; + + public UICommand getNewSnapshotCommand() { + return newSnapshotCommand; + } + + public void setNewSnapshotCommand(UICommand value) { + this.newSnapshotCommand = value; + } + + @Override + public String getListName() { + return "GlusterVolumeSnapshotModel"; //$NON-NLS-1$ + } + + public GlusterVolumeSnapshotListModel() { + setTitle(ConstantsManager.getInstance().getConstants().snapshotsTitle()); + setHelpTag(HelpTag.volume_snapshots); + setHashName("volume_snapshots");//$NON-NLS-1$ + setNewSnapshotCommand(new UICommand("createSnapshot", this));//$NON-NLS-1$ + } + + @Override + protected void onEntityChanged() { + super.onEntityChanged(); + getSearchCommand().execute(); + } + + @Override + protected void onSelectedItemChanged() { + super.onSelectedItemChanged(); + updateActionAvailability(); + } + + @Override + protected void selectedItemsChanged() + { + super.selectedItemsChanged(); + updateActionAvailability(); + } + + @Override + protected void syncSearch() { + if (getEntity() == null) { + return; + } + + AsyncDataProvider.getInstance().getGlusterVolumeSnapshotsForVolume(new AsyncQuery(this, + new INewAsyncCallback() { + + @Override + public void onSuccess(Object model, Object returnValue) { + List<GlusterVolumeSnapshotEntity> snapshots = + (ArrayList<GlusterVolumeSnapshotEntity>) returnValue; + Collections.sort(snapshots, new Linq.GlusterVolumeSnapshotComparer()); + setItems(snapshots); + } + }), getEntity().getId()); + } + + private void updateActionAvailability() { + boolean allowCreateSnapshot = true; + + if (getEntity() == null || getEntity().getStatus() == GlusterStatus.DOWN) { + allowCreateSnapshot = false; + } + + getNewSnapshotCommand().setIsAvailable(allowCreateSnapshot); + } + + @Override + public void executeCommand(UICommand command) { + super.executeCommand(command); + + if (command.equals(getNewSnapshotCommand())) { + newSnapshot(); + } else if (command.getName().equalsIgnoreCase("onCreateSnapshot")) {//$NON-NLS-1$ + onCreateSnapshot(); + } else if (command.getName().equalsIgnoreCase("Cancel")) {//$NON-NLS-1$ + setWindow(null); + } + } + + @Override + public GlusterVolumeEntity getEntity() { + return (GlusterVolumeEntity) super.getEntity(); + } + + public void setEntity(GlusterVolumeEntity value) { + super.setEntity(value); + } + + private void newSnapshot() { + if (getWindow() != null) { + return; + } + + final UIConstants constants = ConstantsManager.getInstance().getConstants(); + + GlusterVolumeEntity volumeEntity = getEntity(); + GlusterVolumeSnapshotModel snapshotModel = new GlusterVolumeSnapshotModel(); + snapshotModel.setHelpTag(HelpTag.new_volume_snapshot); + snapshotModel.setHashName("new_volume_snapshot"); //$NON-NLS-1$ + snapshotModel.setTitle(ConstantsManager.getInstance().getConstants().createSnapshotTitle()); + setWindow(snapshotModel); + + snapshotModel.getClusterName().setEntity(volumeEntity.getVdsGroupName()); + snapshotModel.getVolumeName().setEntity(volumeEntity.getName()); + + UICommand okCommand = new UICommand("onCreateSnapshot", this); //$NON-NLS-1$ + okCommand.setTitle(constants.ok()); + okCommand.setIsDefault(true); + snapshotModel.getCommands().add(okCommand); + + UICommand cancelCommand = new UICommand("Cancel", this); //$NON-NLS-1$ + cancelCommand.setTitle(constants.cancel()); + cancelCommand.setIsCancel(true); + snapshotModel.getCommands().add(cancelCommand); + } + + private void onCreateSnapshot() { + GlusterVolumeSnapshotModel snapshotModel = (GlusterVolumeSnapshotModel) getWindow(); + + if (!snapshotModel.validate()) { + return; + } + + final GlusterVolumeSnapshotEntity snapshot = new GlusterVolumeSnapshotEntity(); + GlusterVolumeEntity volumeEntity = (GlusterVolumeEntity) getEntity(); + snapshot.setClusterId(volumeEntity.getClusterId()); + snapshot.setSnapshotName(snapshotModel.getSnapshotName().getEntity()); + snapshot.setVolumeId(volumeEntity.getId()); + snapshot.setDescription(snapshotModel.getDescription().getEntity()); + boolean force = snapshotModel.getForceCreate().getEntity(); + + CreateGlusterVolumeSnapshotParameters parameter = + new CreateGlusterVolumeSnapshotParameters(snapshot, force); + + snapshotModel.startProgress(null); + Frontend.getInstance().runAction(VdcActionType.CreateGlusterVolumeSnapshot, + parameter, + new IFrontendActionAsyncCallback() { + @Override + public void executed(FrontendActionAsyncResult result) { + GlusterVolumeSnapshotListModel localModel = (GlusterVolumeSnapshotListModel) result.getState(); + localModel.stopProgress(); + localModel.postOnCreateSnapshot(result.getReturnValue(), snapshot); + } + }, + this); + } + + public void postOnCreateSnapshot(VdcReturnValueBase returnValue, GlusterVolumeSnapshotEntity snapshot) { + GlusterVolumeSnapshotModel model = (GlusterVolumeSnapshotModel) getWindow(); + + if (returnValue != null && returnValue.getSucceeded()) { + setWindow(null); + } + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java new file mode 100644 index 0000000..0f9e70c --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/gluster/GlusterVolumeSnapshotModel.java @@ -0,0 +1,117 @@ +package org.ovirt.engine.ui.uicommonweb.models.gluster; + +import org.ovirt.engine.ui.uicommonweb.models.EntityModel; +import org.ovirt.engine.ui.uicommonweb.models.Model; +import org.ovirt.engine.ui.uicommonweb.validation.AsciiNameValidation; +import org.ovirt.engine.ui.uicommonweb.validation.IValidation; +import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; +import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; + +public class GlusterVolumeSnapshotModel extends Model { + private EntityModel<String> dataCenter; + private EntityModel<String> clusterName; + private EntityModel<String> volumeName; + private EntityModel<String> snapshotName; + private EntityModel<String> description; + private EntityModel<Boolean> forceCreate; + private EntityModel<Boolean> activate; + private String volumeQuotaMessage = ""; + + public GlusterVolumeSnapshotModel() { + init(); + setAvailabilities(); + } + + private void init() { + setDataCenter(new EntityModel<String>()); + setClusterName(new EntityModel<String>()); + setVolumeName(new EntityModel<String>()); + setSnapshotName(new EntityModel<String>()); + setDescription(new EntityModel<String>()); + setForceCreate(new EntityModel<Boolean>()); + setActivate(new EntityModel<Boolean>()); + + getForceCreate().setEntity(false); + getActivate().setEntity(true); + } + + private void setAvailabilities() { + getClusterName().setIsAvailable(true); + getVolumeName().setIsAvailable(true); + getSnapshotName().setIsAvailable(true); + getDescription().setIsAvailable(true); + getForceCreate().setIsAvailable(true); + getActivate().setIsAvailable(true); + } + + public EntityModel<String> getDataCenter() { + return this.dataCenter; + } + + public void setDataCenter(EntityModel<String> dataCenter) { + this.dataCenter = dataCenter; + } + + public EntityModel<String> getClusterName() { + return clusterName; + } + + public void setClusterName(EntityModel<String> clusterName) { + this.clusterName = clusterName; + } + + public EntityModel<String> getVolumeName() { + return volumeName; + } + + public void setVolumeName(EntityModel<String> volumeName) { + this.volumeName = volumeName; + } + + public EntityModel<String> getSnapshotName() { + return snapshotName; + } + + public void setSnapshotName(EntityModel<String> snapshotName) { + this.snapshotName = snapshotName; + } + + public EntityModel<String> getDescription() { + return description; + } + + public void setDescription(EntityModel<String> description) { + this.description = description; + } + + public EntityModel<Boolean> getForceCreate() { + return forceCreate; + } + + public void setForceCreate(EntityModel<Boolean> forceCreate) { + this.forceCreate = forceCreate; + } + + public EntityModel<Boolean> getActivate() { + return activate; + } + + public void setActivate(EntityModel<Boolean> activate) { + this.activate = activate; + } + + public String getVolumeQuotaMessage() { + return this.volumeQuotaMessage; + } + + public void setVolumeQuotaMessage(String value) { + this.volumeQuotaMessage = value; + } + + public boolean validate() { + getSnapshotName().validateEntity(new IValidation[] { new NotEmptyValidation(), new LengthValidation(50), + new AsciiNameValidation() }); + + return getSnapshotName().getIsValid(); + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java index db5b5cb..cf39e52 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java @@ -60,6 +60,7 @@ import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeProfileStatisticsModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeRebalanceStatusModel; import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotListModel; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult; import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; @@ -106,6 +107,7 @@ private UICommand startVolumeProfilingCommand; private UICommand showVolumeProfileDetailsCommand; private UICommand stopVolumeProfilingCommand; + private UICommand createSnapshotCommand; public UICommand getStartRebalanceCommand() { return startRebalanceCommand; @@ -122,6 +124,7 @@ public void setStopRebalanceCommand(UICommand stopRebalanceCommand) { this.stopRebalanceCommand = stopRebalanceCommand; } + private UICommand statusRebalanceCommand; public UICommand getStatusRebalanceCommand() { @@ -168,6 +171,12 @@ return geoRepListModel; } + private final GlusterVolumeSnapshotListModel snapshotListModel; + + public GlusterVolumeSnapshotListModel getSnapshotListModel() { + return snapshotListModel; + } + public UICommand getStartVolumeProfilingCommand() { return startVolumeProfilingCommand; } @@ -192,20 +201,33 @@ this.stopVolumeProfilingCommand = stopVolumeProfilingCommand; } + public UICommand getCreateSnapshotCommand() { + return this.createSnapshotCommand; + } + + public void setCreateSnapshotCommand(UICommand command) { + this.createSnapshotCommand = command; + } + @Inject - public VolumeListModel(final VolumeBrickListModel volumeBrickListModel, final VolumeGeneralModel volumeGeneralModel, + public VolumeListModel(final VolumeBrickListModel volumeBrickListModel, + final VolumeGeneralModel volumeGeneralModel, final VolumeParameterListModel volumeParameterListModel, - final PermissionListModel<VolumeListModel> permissionListModel, - final VolumeEventListModel volumeEventListModel, final VolumeGeoRepListModel geoRepListModel) { + final PermissionListModel permissionListModel, + final VolumeEventListModel volumeEventListModel, + final VolumeGeoRepListModel geoRepListModel, + final GlusterVolumeSnapshotListModel snapshotListModel) { this.brickListModel = volumeBrickListModel; this.geoRepListModel = geoRepListModel; + this.snapshotListModel = snapshotListModel; setDetailList(volumeGeneralModel, volumeParameterListModel, permissionListModel, volumeEventListModel); setTitle(ConstantsManager.getInstance().getConstants().volumesTitle()); setApplicationPlace(WebAdminApplicationPlaces.volumeMainTabPlace); setDefaultSearchString("Volumes:"); //$NON-NLS-1$ setSearchString(getDefaultSearchString()); - setSearchObjects(new String[] { SearchObjects.GLUSTER_VOLUME_OBJ_NAME, SearchObjects.GLUSTER_VOLUME_PLU_OBJ_NAME }); + setSearchObjects(new String[] { SearchObjects.GLUSTER_VOLUME_OBJ_NAME, + SearchObjects.GLUSTER_VOLUME_PLU_OBJ_NAME }); setAvailableInModes(ApplicationMode.GlusterOnly); setNewVolumeCommand(new UICommand("Create Volume", this)); //$NON-NLS-1$ @@ -219,6 +241,7 @@ setShowVolumeProfileDetailsCommand(new UICommand("showProfileDetails", this));//$NON-NLS-1$ setStopVolumeProfilingCommand(new UICommand("stopProfiling", this));//$NON-NLS-1$ setOptimizeForVirtStoreCommand(new UICommand("OptimizeForVirtStore", this)); //$NON-NLS-1$ + setCreateSnapshotCommand(new UICommand("createSnapshot", this)); //$NON-NLS-1$ getRemoveVolumeCommand().setIsExecutionAllowed(false); getStartCommand().setIsExecutionAllowed(false); @@ -245,6 +268,7 @@ list.add(getGeoRepListModel()); list.add(permissionListModel); list.add(volumeEventListModel); + list.add(getSnapshotListModel()); setDetailModels(list); } @@ -282,7 +306,7 @@ if (dc.getId().equals(cluster.getStoragePoolId())) { innerVolumeModel.getDataCenter() - .setItems(new ArrayList<StoragePool>(Arrays.asList(new StoragePool[] {dc}))); + .setItems(new ArrayList<StoragePool>(Arrays.asList(new StoragePool[] { dc }))); innerVolumeModel.getDataCenter().setSelectedItem(dc); break; } @@ -323,7 +347,7 @@ command.setTitle(ConstantsManager.getInstance().getConstants().ok()); command.setIsDefault(true); innerVolumeModel.getCommands().add(command); - command = new UICommand("Cancel", volumeListModel); //$NON-NLS-1$ + command = new UICommand("Cancel", volumeListModel); //$NON-NLS-1$ command.setTitle(ConstantsManager.getInstance().getConstants().cancel()); command.setIsCancel(true); innerVolumeModel.getCommands().add(command); @@ -408,7 +432,8 @@ @Override protected void syncSearch() { - SearchParameters tempVar = new SearchParameters(getSearchString(), SearchType.GlusterVolume, isCaseSensitiveSearch()); + SearchParameters tempVar = + new SearchParameters(getSearchString(), SearchType.GlusterVolume, isCaseSensitiveSearch()); tempVar.setMaxCount(getSearchPageSize()); super.syncSearch(VdcQueryType.Search, tempVar); } @@ -417,9 +442,10 @@ protected void onSelectedItemChanged() { super.onSelectedItemChanged(); updateActionAvailability(); - GlusterVolumeEntity selectedVolume = (GlusterVolumeEntity)provideDetailModelEntity(getSelectedItem()); + GlusterVolumeEntity selectedVolume = (GlusterVolumeEntity) provideDetailModelEntity(getSelectedItem()); getBrickListModel().setVolumeEntity(selectedVolume); getGeoRepListModel().setEntity(selectedVolume); + getSnapshotListModel().setEntity(selectedVolume); } @Override @@ -440,6 +466,7 @@ boolean allowStartProfiling = false; boolean allowStopProfiling = false; boolean allowProfileStatisticsDetails = false; + boolean allowCreateSnapshot = false; if (getSelectedItems() == null || getSelectedItems().size() == 0) { allowStart = false; @@ -486,6 +513,7 @@ } allowStatusRebalance = getRebalanceStatusAvailability(getSelectedItems()); allowProfileStatisticsDetails = getProfileStatisticsAvailability(list); + allowCreateSnapshot = isCreateSnapshotAvailable(list); } getStartCommand().setIsExecutionAllowed(allowStart); getStopCommand().setIsExecutionAllowed(allowStop); @@ -494,6 +522,7 @@ getStopRebalanceCommand().setIsExecutionAllowed(allowStopRebalance); getStatusRebalanceCommand().setIsExecutionAllowed(allowStatusRebalance); getOptimizeForVirtStoreCommand().setIsExecutionAllowed(allowOptimize); + getCreateSnapshotCommand().setIsExecutionAllowed(allowCreateSnapshot); // System tree dependent actions. boolean isAvailable = @@ -506,6 +535,15 @@ getShowVolumeProfileDetailsCommand().setIsExecutionAllowed(allowProfileStatisticsDetails); } + private boolean isCreateSnapshotAvailable(List<GlusterVolumeEntity> list) { + if (getSelectedItems().size() == 1) { + GlusterVolumeEntity volumeEntity = list.get(0); + return (volumeEntity.getStatus() == GlusterStatus.UP); + } else { + return false; + } + } + private boolean isStopProfileAvailable(List<GlusterVolumeEntity> list) { if (getSelectedItems().size() == 0) { return false; @@ -514,7 +552,7 @@ if (volumeEntity.getStatus() == GlusterStatus.DOWN) { return false; } - if ((volumeEntity.getOptionValue("diagnostics.latency-measurement") == null)|| (!(volumeEntity.getOptionValue("diagnostics.latency-measurement").equals("on")))) {//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + if ((volumeEntity.getOptionValue("diagnostics.latency-measurement") == null) || (!(volumeEntity.getOptionValue("diagnostics.latency-measurement").equals("on")))) {//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ return false; } } @@ -550,9 +588,9 @@ } private boolean getProfileStatisticsAvailability(List<GlusterVolumeEntity> selectedVolumes) { - if(selectedVolumes.size() == 1) { + if (selectedVolumes.size() == 1) { GlusterVolumeEntity selectedVolume = selectedVolumes.get(0); - if(selectedVolume.getStatus() == GlusterStatus.UP) { + if (selectedVolume.getStatus() == GlusterStatus.UP) { return true; } } @@ -571,7 +609,7 @@ } else if (command.equals(getRemoveVolumeCommand())) { removeVolume(); - } else if(command.getName().equals("rebalanceNotStarted")) {//$NON-NLS-1$ + } else if (command.getName().equals("rebalanceNotStarted")) {//$NON-NLS-1$ closeConfirmationWindow(); } else if (command.getName().equals("Cancel")) { //$NON-NLS-1$ @@ -594,30 +632,33 @@ setConfirmWindow(null); } else if (command.getName().equals("CancelRebalanceStatus")) {//$NON-NLS-1$ cancelRebalanceStatus(); - }else if (command.equals(getOptimizeForVirtStoreCommand())) { + } else if (command.equals(getOptimizeForVirtStoreCommand())) { optimizeForVirtStore(); } else if (command.getName().equals("onStop")) {//$NON-NLS-1$ onStop(); } else if (command.getName().equals("OnRemove")) { //$NON-NLS-1$ onRemoveVolume(); - } else if(command.getName().equals("stop_rebalance_from_status")) {//$NON-NLS-1$ + } else if (command.getName().equals("stop_rebalance_from_status")) {//$NON-NLS-1$ stopRebalance(); - } else if(command.equals(getStartVolumeProfilingCommand()) || command.getName().equals("startProfiling")) {//$NON-NLS-1$ + } else if (command.equals(getStartVolumeProfilingCommand()) || command.getName().equals("startProfiling")) {//$NON-NLS-1$ startVolumeProfiling(); - } else if(command.equals(getStopVolumeProfilingCommand()) || command.getName().equals("stopProfiling")) {//$NON-NLS-1$ + } else if (command.equals(getStopVolumeProfilingCommand()) || command.getName().equals("stopProfiling")) {//$NON-NLS-1$ stopVolumeProfiling(); - } else if(command.equals(getShowVolumeProfileDetailsCommand()) || command.getName().equals("showProfileDetails")) {//$NON-NLS-1$ + } else if (command.equals(getShowVolumeProfileDetailsCommand()) + || command.getName().equals("showProfileDetails")) {//$NON-NLS-1$ showVolumeProfiling(); - }else if(command.getName().equalsIgnoreCase("closeProfileStats")) {//$NON-NLS-1$ + } else if (command.getName().equalsIgnoreCase("closeProfileStats")) {//$NON-NLS-1$ setWindow(null); - } else if(command.getName().equalsIgnoreCase("CancelOptimizeForVirtStore")) {//$NON-NLS-1$ + } else if (command.getName().equalsIgnoreCase("CancelOptimizeForVirtStore")) {//$NON-NLS-1$ setConfirmWindow(null); } else if (command.getName().equalsIgnoreCase("ConfirmOptimiseForVirtStore")) {//$NON-NLS-1$ List<GlusterVolumeEntity> selectedVolumes = new ArrayList<GlusterVolumeEntity>(); - for(Object selectedVolume : getSelectedItems()) { + for (Object selectedVolume : getSelectedItems()) { selectedVolumes.add((GlusterVolumeEntity) selectedVolume); } optimizeVolumesForVirtStore(selectedVolumes); + } else if (command.equals(getCreateSnapshotCommand())) { + getSnapshotListModel().getNewSnapshotCommand().execute(); } } @@ -648,7 +689,7 @@ } private void closeConfirmationWindow() { - if(getConfirmWindow() == null) { + if (getConfirmWindow() == null) { return; } getConfirmWindow().stopProgress(); @@ -707,20 +748,23 @@ model.startProgress(null); final GlusterVolumeEntity volumeEntity = (GlusterVolumeEntity) getSelectedItem(); - GlusterVolumeRebalanceParameters param = new GlusterVolumeRebalanceParameters(volumeEntity.getId(), false, false); + GlusterVolumeRebalanceParameters param = + new GlusterVolumeRebalanceParameters(volumeEntity.getId(), false, false); - Frontend.getInstance().runAction(VdcActionType.StopRebalanceGlusterVolume, param, new IFrontendActionAsyncCallback() { + Frontend.getInstance().runAction(VdcActionType.StopRebalanceGlusterVolume, + param, + new IFrontendActionAsyncCallback() { - @Override - public void executed(FrontendActionAsyncResult result) { - ConfirmationModel localModel = (ConfirmationModel) getConfirmWindow(); - localModel.stopProgress(); - setConfirmWindow(null); - if (result.getReturnValue().getSucceeded()) { - showRebalanceStatus(); - } - } - }); + @Override + public void executed(FrontendActionAsyncResult result) { + ConfirmationModel localModel = (ConfirmationModel) getConfirmWindow(); + localModel.stopProgress(); + setConfirmWindow(null); + if (result.getReturnValue().getSucceeded()) { + showRebalanceStatus(); + } + } + }); } private void showRebalanceStatus() { @@ -745,9 +789,11 @@ public void onSuccess(Object model, Object returnValue) { cModel.stopProgress(); VdcQueryReturnValue vdcValue = (VdcQueryReturnValue) returnValue; - GlusterVolumeTaskStatusEntity rebalanceStatusEntity =vdcValue.getReturnValue(); + GlusterVolumeTaskStatusEntity rebalanceStatusEntity = vdcValue.getReturnValue(); if ((rebalanceStatusEntity == null) || !(vdcValue.getSucceeded())) { - cModel.setMessage(ConstantsManager.getInstance().getMessages().rebalanceStatusFailed(volumeEntity.getName())); + cModel.setMessage(ConstantsManager.getInstance() + .getMessages() + .rebalanceStatusFailed(volumeEntity.getName())); } else { setConfirmWindow(null); if (getWindow() == null) { @@ -762,7 +808,8 @@ rebalanceStatusModel.getVolume().setEntity(volumeEntity.getName()); rebalanceStatusModel.getCluster().setEntity(volumeEntity.getVdsGroupName()); - UICommand stopRebalanceFromStatus = new UICommand("stop_rebalance_from_status", VolumeListModel.this);//$NON-NLS-1$ + UICommand stopRebalanceFromStatus = + new UICommand("stop_rebalance_from_status", VolumeListModel.this);//$NON-NLS-1$ stopRebalanceFromStatus.setTitle(ConstantsManager.getInstance().getConstants().stopRebalance()); rebalanceStatusModel.getCommands().add(stopRebalanceFromStatus); rebalanceStatusModel.setStopReblanceFromStatus(stopRebalanceFromStatus); @@ -773,7 +820,7 @@ rebalanceStatusModel.getCommands().add(cancelRebalance); rebalanceStatusModel.showStatus(rebalanceStatusEntity); - }else { + } else { VolumeRebalanceStatusModel statusModel = (VolumeRebalanceStatusModel) getWindow(); statusModel.getCommands().get(0).setIsExecutionAllowed(false); statusModel.showStatus(rebalanceStatusEntity); @@ -787,11 +834,14 @@ } private void showVolumeProfiling() { - if(getSelectedItem() == null || getWindow()!= null) { + if (getSelectedItem() == null || getWindow() != null) { return; } - GlusterVolumeEntity selectedVolume = (GlusterVolumeEntity)getSelectedItem(); - VolumeProfileStatisticsModel profileStatsModel = new VolumeProfileStatisticsModel(selectedVolume.getClusterId(), selectedVolume.getId(), selectedVolume.getName()); + GlusterVolumeEntity selectedVolume = (GlusterVolumeEntity) getSelectedItem(); + VolumeProfileStatisticsModel profileStatsModel = + new VolumeProfileStatisticsModel(selectedVolume.getClusterId(), + selectedVolume.getId(), + selectedVolume.getName()); setWindow(profileStatsModel); setHelpTag(HelpTag.volume_profile_statistics); @@ -813,7 +863,7 @@ { return; } - ((VolumeRebalanceStatusModel)getWindow()).cancelRefresh(); + ((VolumeRebalanceStatusModel) getWindow()).cancelRefresh(); cancel(); } @@ -829,14 +879,14 @@ for (Object item : getSelectedItems()) { GlusterVolumeEntity volume = (GlusterVolumeEntity) item; volumesForOptimiseForVirtStore.add(volume); - if(volume.getReplicaCount() != 3) { + if (volume.getReplicaCount() != 3) { discouragedConfigVolumeNamesBuilder.append(volume.getName() + "\n");//$NON-NLS-1$ isDiscouragedVolumePresent = true; } } discouragedConfigVolumeNamesBuilder.append(constants.optimiseForVirtStoreContinueMessage()); - if(isDiscouragedVolumePresent) { + if (isDiscouragedVolumePresent) { ConfirmationModel cModel = new ConfirmationModel(); cModel.setMessage(discouragedConfigVolumeNamesBuilder.toString()); @@ -857,7 +907,7 @@ } private void optimizeVolumesForVirtStore(final List<GlusterVolumeEntity> volumeList) { - if(getConfirmWindow() != null) { + if (getConfirmWindow() != null) { setConfirmWindow(null); } AsyncQuery aQuery = new AsyncQuery(); @@ -888,20 +938,25 @@ { Guid volumeId = volume.getId(); - list.add(new GlusterVolumeOptionParameters(getOption(volumeId, "group", optionGroupVirt)));//$NON-NLS-1$ + list.add(new GlusterVolumeOptionParameters(getOption(volumeId, + "group", optionGroupVirt)));//$NON-NLS-1$ - list.add(new GlusterVolumeOptionParameters(getOption(volumeId, "storage.owner-uid", optionOwnerUserVirt)));//$NON-NLS-1$ + list.add(new GlusterVolumeOptionParameters(getOption(volumeId, + "storage.owner-uid", optionOwnerUserVirt)));//$NON-NLS-1$ - list.add(new GlusterVolumeOptionParameters(getOption(volumeId, "storage.owner-gid", optionOwnerGroupVirt)));//$NON-NLS-1$ + list.add(new GlusterVolumeOptionParameters(getOption(volumeId, + "storage.owner-gid", optionOwnerGroupVirt)));//$NON-NLS-1$ - final GlusterVolumeOptionEntity checkOption = getOption(volumeId, "network.ping-timeout", "10");//$NON-NLS-1$//$NON-NLS-2$ - List<PredicateFilter<GlusterVolumeOptionEntity>> predicaetFilters = Collections.singletonList(new PredicateFilter<GlusterVolumeOptionEntity>(new Predicate<GlusterVolumeOptionEntity>() { - @Override - public boolean evaluate(GlusterVolumeOptionEntity obj) { - return obj.getKey().equalsIgnoreCase(checkOption.getKey()); - } - })); - if(!isOptionEnabledOnVolume(volume, predicaetFilters)) { + final GlusterVolumeOptionEntity checkOption = + getOption(volumeId, "network.ping-timeout", "10");//$NON-NLS-1$//$NON-NLS-2$ + List<PredicateFilter<GlusterVolumeOptionEntity>> predicaetFilters = + Collections.singletonList(new PredicateFilter<GlusterVolumeOptionEntity>(new Predicate<GlusterVolumeOptionEntity>() { + @Override + public boolean evaluate(GlusterVolumeOptionEntity obj) { + return obj.getKey().equalsIgnoreCase(checkOption.getKey()); + } + })); + if (!isOptionEnabledOnVolume(volume, predicaetFilters)) { list.add(new GlusterVolumeOptionParameters(checkOption));//$NON-NLS-1$ } } @@ -909,28 +964,33 @@ } }; - AsyncDataProvider.getInstance().getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionOwnerGroupVirtValue, - AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), - aQueryInner1); + AsyncDataProvider.getInstance() + .getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionOwnerGroupVirtValue, + AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), + aQueryInner1); } }; - AsyncDataProvider.getInstance().getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionOwnerUserVirtValue, - AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), - aQueryInner); + AsyncDataProvider.getInstance() + .getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionOwnerUserVirtValue, + AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), + aQueryInner); } }; - AsyncDataProvider.getInstance().getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionGroupVirtValue, - AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), - aQuery); + AsyncDataProvider.getInstance() + .getConfigFromCache(new GetConfigurationValueParameters(ConfigurationValues.GlusterVolumeOptionGroupVirtValue, + AsyncDataProvider.getInstance().getDefaultConfigurationVersion()), + aQuery); } - private boolean isOptionEnabledOnVolume(GlusterVolumeEntity volume, List<PredicateFilter<GlusterVolumeOptionEntity>> predicates) { - List<GlusterVolumeOptionEntity> volumeOptionsEnabled = new ArrayList<GlusterVolumeOptionEntity>(volume.getOptions()); + private boolean isOptionEnabledOnVolume(GlusterVolumeEntity volume, + List<PredicateFilter<GlusterVolumeOptionEntity>> predicates) { + List<GlusterVolumeOptionEntity> volumeOptionsEnabled = + new ArrayList<GlusterVolumeOptionEntity>(volume.getOptions()); List<GlusterVolumeOptionEntity> filteredOptions = volumeOptionsEnabled; - for(PredicateFilter<GlusterVolumeOptionEntity> predicate : predicates) { - filteredOptions = ListUtils.filter(filteredOptions, predicate); + for (PredicateFilter<GlusterVolumeOptionEntity> predicate : predicates) { + filteredOptions = ListUtils.filter(filteredOptions, predicate); } - if(filteredOptions.size() > 0) { + if (filteredOptions.size() > 0) { return true; } return false; @@ -1027,7 +1087,6 @@ Frontend.getInstance().runMultipleAction(VdcActionType.StartGlusterVolume, list); } - private void onCreateVolume() { VolumeModel volumeModel = (VolumeModel) getWindow(); @@ -1088,14 +1147,17 @@ CreateGlusterVolumeParameters parameter = new CreateGlusterVolumeParameters(volume, volumeModel.isForceAddBricks()); - Frontend.getInstance().runAction(VdcActionType.CreateGlusterVolume, parameter, new IFrontendActionAsyncCallback() { + Frontend.getInstance().runAction(VdcActionType.CreateGlusterVolume, + parameter, + new IFrontendActionAsyncCallback() { - @Override - public void executed(FrontendActionAsyncResult result) { - VolumeListModel localModel = (VolumeListModel) result.getState(); - localModel.postOnCreateVolume(result.getReturnValue(), volume); - } - }, this); + @Override + public void executed(FrontendActionAsyncResult result) { + VolumeListModel localModel = (VolumeListModel) result.getState(); + localModel.postOnCreateVolume(result.getReturnValue(), volume); + } + }, + this); } public void postOnCreateVolume(VdcReturnValueBase returnValue, GlusterVolumeEntity volume) diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/place/WebAdminApplicationPlaces.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/place/WebAdminApplicationPlaces.java index 776698c..459b9cb 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/place/WebAdminApplicationPlaces.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/place/WebAdminApplicationPlaces.java @@ -311,6 +311,8 @@ public static final String volumeGeoRepSubTabPlace = volumeMainTabPlace + SUB_TAB_PREFIX + "geo_rep"; //$NON-NLS-1$ + public static final String volumeSnapshotSubTabPlace = volumeMainTabPlace + SUB_TAB_PREFIX + "volume_snapshots"; //$NON-NLS-1$ + // Disk public static final String diskGeneralSubTabPlace = diskMainTabPlace + SUB_TAB_PREFIX + "general"; //$NON-NLS-1$ @@ -322,7 +324,6 @@ public static final String diskStorageSubTabPlace = diskMainTabPlace + SUB_TAB_PREFIX + "storage"; //$NON-NLS-1$ public static final String diskPermissionSubTabPlace = diskMainTabPlace + SUB_TAB_PREFIX + "permissions"; //$NON-NLS-1$ - // Network public static final String networkGeneralSubTabPlace = networkMainTabPlace + SUB_TAB_PREFIX + "general"; //$NON-NLS-1$ @@ -347,7 +348,6 @@ public static final String networkPermissionSubTabPlace = networkMainTabPlace + SUB_TAB_PREFIX + "permissions"; //$NON-NLS-1$ - // Provider public static final String providerGeneralSubTabPlace = providerMainTabPlace + SUB_TAB_PREFIX + "general"; //$NON-NLS-1$ diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java index 2650117..7b99c35 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java @@ -435,6 +435,10 @@ String AuditLogType___REMOVE_GLUSTER_VOLUME_BRICKS_NOT_FOUND_FROM_CLI(); + String AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CREATED(); + + String AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CREATE_FAILED(); + String VdcActionType___ActivateVds(); String VdcActionType___RecoveryStoragePool(); @@ -720,6 +724,8 @@ String VdcActionType___StartRebalanceGlusterVolume(); + String VdcActionType___CreateGlusterVolumeSnapshot(); + String VdcActionType___ReplaceGlusterVolumeBrick(); String VdcActionType___GlusterHostAdd(); diff --git a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties index f50b0f9..091004c 100644 --- a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties +++ b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties @@ -217,6 +217,8 @@ AuditLogType___GLUSTER_BRICK_STATUS_CHANGED=Detected change in status of brick AuditLogType___GLUSTER_VOLUME_REBALANCE_NOT_FOUND_FROM_CLI=Could not find information for rebalance on volume from CLI. Marking it as unknown. AuditLogType___REMOVE_GLUSTER_VOLUME_BRICKS_NOT_FOUND_FROM_CLI=Could not find information for remove brick on volume from CLI. Marking it as unknown. +AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CREATED=Snapshot created for the volume +AuditLogType___GLUSTER_VOLUME_SNAPSHOT_CREATE_FAILED=Failed create snapshot for the volume VdcActionType___ActivateVds=Activate Host @@ -335,6 +337,7 @@ VdcActionType___GlusterVolumeRemoveBricks=Remove Gluster Volume Bricks VdcActionType___AddBricksToGlusterVolume=Add Brick To Gluster Volume VdcActionType___StartRebalanceGlusterVolume=Start Rebalance Gluster Volume +VdcActionType___CreateGlusterVolumeSnapshot=Create Gluster Volume Snapshot VdcActionType___ReplaceGlusterVolumeBrick=Start Gluster Volume Replace Brick VdcActionType___GlusterHostAdd=Add Gluster server vdcActionType___StartGlusterVolumeProfile=Start Gluster Volume Profile diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java index f1d55e4..acab44f 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/ApplicationConstants.java @@ -106,6 +106,9 @@ @DefaultStringValue("Geo-Replication") String volumeGeoRepSubTabLabel(); + @DefaultStringValue("Snapshots") + String volumeSnapshotSubTabLabel(); + @DefaultStringValue("Destination Host") String volumeSubTabGeoRepSlaveClusterHostColumn(); @@ -819,7 +822,8 @@ @DefaultStringValue("CPU Threads") String clusterPopupCpuThreadsPanelTitle(); - @DefaultStringValue("Allow guests to use host threads as virtual CPU cores, utilizing AMD Clustered MultiThreading or Intel" + + @DefaultStringValue("Allow guests to use host threads as virtual CPU cores, utilizing AMD Clustered MultiThreading or Intel" + + " Hyper-Threading technology on the virtualization host. Enabling this option may be useful for less" + " CPU-intensive workloads, or to run guests with CPU configurations that would otherwise be restricted.") String clusterPopupCpuThreadsInfo(); @@ -3652,7 +3656,7 @@ @DefaultStringValue("Remove brick in progress but status unknown. Unable to fetch the status at the moment.") String removeBrickStatusUnknown(); - //Volume Rebalance Status Table Columns + // Volume Rebalance Status Table Columns @DefaultStringValue("Host") String rebalanceSessionHost(); @@ -3816,11 +3820,10 @@ @DefaultStringValue("Disk Snapshots") String snapshotsLabel(); - @DefaultStringValue("Attached by label") String attachedByLabel(); - //Gluster Volume Profiling + // Gluster Volume Profiling @DefaultStringValue("File operation") String fileOperation(); @@ -3973,4 +3976,56 @@ @DefaultStringValue("NUMA Support") String numaSupport(); + + // Volume snapshots + + @DefaultStringValue("New") + String newVolumeSnapshot(); + + @DefaultStringValue("Snapshot") + String volumeSnapshotMainTabTitle(); + + @DefaultStringValue("Cluster") + String volumeClusterLabel(); + + @DefaultStringValue("Volume") + String volumeNameLabel(); + + @DefaultStringValue("Snapshot Name") + String volumeSnapshotNameLabel(); + + @DefaultStringValue("Description") + String volumeSnapshotDescriptionLabel(); + + @DefaultStringValue("Force snapshot creation") + String forceVolumeSnapshotCreationLabel(); + + @DefaultStringValue("Note: If Force snapshot creation option is selected" + + " and the server-side quorum is met, snapshot creation" + + "succeeds even if bricks are down.") + String volumeQuorumNote(); + + @DefaultStringValue("Name") + String volumeSnapshotName(); + + @DefaultStringValue("Description") + String volumeSnapshotDescription(); + + @DefaultStringValue("Creation Time") + String volumeSnapshotCreationTime(); + + @DefaultStringValue("Restore") + String restoreVolumeSnapshot(); + + @DefaultStringValue("Delete") + String removeVolumeSnapshot(); + + @DefaultStringValue("Remove All") + String removeAllVolumeSnapshots(); + + @DefaultStringValue("Activate") + String activateVolumeSnapshot(); + + @DefaultStringValue("Deactivate") + String deactivateVolumeSnapshot(); } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/ClientGinjectorExtension.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/ClientGinjectorExtension.java index cb8f9cd..7b505cf 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/ClientGinjectorExtension.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/ClientGinjectorExtension.java @@ -26,6 +26,7 @@ import org.ovirt.engine.core.common.businessentities.gluster.GlusterServerService; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeOptionEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.core.common.businessentities.network.ExternalSubnet; import org.ovirt.engine.core.common.businessentities.network.HostNetworkQos; import org.ovirt.engine.core.common.businessentities.network.Network; @@ -78,6 +79,7 @@ import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeGeneralModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeGeoRepListModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeParameterListModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotListModel; import org.ovirt.engine.ui.uicommonweb.models.hosts.HostBricksListModel; import org.ovirt.engine.ui.uicommonweb.models.hosts.HostEventListModel; import org.ovirt.engine.ui.uicommonweb.models.hosts.HostGeneralModel; @@ -389,6 +391,8 @@ SearchableDetailModelProvider<GlusterGeoRepSession, VolumeListModel, VolumeGeoRepListModel> getSubTabVolumeGeoRepModelProvider(); + SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> getSubTabVolumeSnapshotModelProvider(); + // Disk DetailModelProvider<DiskListModel, DiskGeneralModel> getSubTabDiskGeneralModelProvider(); diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java index 5284304..9a5fa0e 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/PresenterModule.java @@ -44,6 +44,7 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.AddBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.BrickAdvancedDetailsPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.DetachGlusterHostsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget; @@ -169,6 +170,7 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.SubTabVolumeGeoRepPresenter; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.SubTabVolumeParameterPresenter; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.SubTabVolumePermissionPresenter; +import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.SubTabGlusterVolumeSnapshotPresenter; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.VolumeSubTabPanelPresenter; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.host.HostSubTabPanelPresenter; import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.host.SubTabHostBrickPresenter; @@ -283,6 +285,7 @@ import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.AddBrickPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.BrickAdvancedDetailsPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.DetachGlusterHostsPopupView; +import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.RemoveBrickStatusPopupView; import org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.ReplaceBrickPopupView; @@ -414,6 +417,7 @@ import org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster.SubTabVolumeGeoRepView; import org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster.SubTabVolumeParameterView; import org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster.SubTabVolumePermissionView; +import org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster.SubTabGlusterVolumeSnapshotView; import org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster.VolumeSubTabPanelView; import org.ovirt.engine.ui.webadmin.section.main.view.tab.host.HostSubTabPanelView; import org.ovirt.engine.ui.webadmin.section.main.view.tab.host.SubTabHostBrickView; @@ -782,6 +786,9 @@ SubTabClusterCpuProfilePresenter.ViewDef.class, SubTabClusterCpuProfileView.class, SubTabClusterCpuProfilePresenter.ProxyDef.class); + bindPresenterWidget(GlusterVolumeSnapshotCreatePopupPresenterWidget.class, + GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef.class, + GlusterVolumeSnapshotCreatePopupView.class); // Host bindPresenter(HostSubTabPanelPresenter.class, @@ -866,7 +873,6 @@ SubTabVirtualMachineEventPresenter.ViewDef.class, SubTabVirtualMachineEventView.class, SubTabVirtualMachineEventPresenter.ProxyDef.class); - // Pool bindPresenter(PoolSubTabPanelPresenter.class, @@ -1395,7 +1401,7 @@ QuotaPopupPresenterWidget.ViewDef.class, QuotaPopupView.class); - //Network QoS + // Network QoS bindPresenterWidget(NetworkQoSPopupPresenterWidget.class, NetworkQoSPopupPresenterWidget.ViewDef.class, NetworkQoSPopupView.class); @@ -1462,6 +1468,11 @@ SubTabVolumeEventView.class, SubTabVolumeEventPresenter.ProxyDef.class); + bindPresenter(SubTabGlusterVolumeSnapshotPresenter.class, + SubTabGlusterVolumeSnapshotPresenter.ViewDef.class, + SubTabGlusterVolumeSnapshotView.class, + SubTabGlusterVolumeSnapshotPresenter.ProxyDef.class); + bindPresenterWidget(AddBrickPopupPresenterWidget.class, AddBrickPopupPresenterWidget.ViewDef.class, AddBrickPopupView.class); diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java index 87f7789..ac1a2dc 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/VolumeModule.java @@ -6,6 +6,7 @@ import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeOptionEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; import org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget; import org.ovirt.engine.ui.common.presenter.popup.RemoveConfirmationPopupPresenterWidget; @@ -20,6 +21,7 @@ import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel; import org.ovirt.engine.ui.uicommonweb.models.Model; import org.ovirt.engine.ui.uicommonweb.models.configure.PermissionListModel; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotListModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeBrickListModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeEventListModel; import org.ovirt.engine.ui.uicommonweb.models.gluster.VolumeGeneralModel; @@ -29,6 +31,7 @@ import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.event.EventPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.AddBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.BrickAdvancedDetailsPopupPresenterWidget; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.RemoveBrickStatusPopupPresenterWidget; import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.ReplaceBrickPopupPresenterWidget; @@ -60,36 +63,40 @@ final Provider<VolumeListModel> modelProvider, final Provider<CommonModel> commonModelProvider) { MainTabModelProvider<GlusterVolumeEntity, VolumeListModel> result = - new MainTabModelProvider<GlusterVolumeEntity, VolumeListModel>(eventBus, defaultConfirmPopupProvider, + new MainTabModelProvider<GlusterVolumeEntity, VolumeListModel>(eventBus, + defaultConfirmPopupProvider, commonModelProvider) { - @Override - public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeListModel source, - UICommand lastExecutedCommand, Model windowModel) { - if (lastExecutedCommand == getModel().getNewVolumeCommand()) { - return popupProvider.get(); - } - else if (lastExecutedCommand == getModel().getStatusRebalanceCommand() || lastExecutedCommand.getName().equals("onStopRebalance")) {//$NON-NLS-1$ - return rebalanceStatusPopupProvider.get(); - } - else if(lastExecutedCommand == getModel().getShowVolumeProfileDetailsCommand() || lastExecutedCommand.getName().equals("showProfileDetails")) {//$NON-NLS-1$ - return volumeProfileStatsPopupProvider.get(); - } - else { - return super.getModelPopup(source, lastExecutedCommand, windowModel); - } - } + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand == getModel().getNewVolumeCommand()) { + return popupProvider.get(); + } + else if (lastExecutedCommand == getModel().getStatusRebalanceCommand() + || lastExecutedCommand.getName().equals("onStopRebalance")) {//$NON-NLS-1$ + return rebalanceStatusPopupProvider.get(); + } + else if (lastExecutedCommand == getModel().getShowVolumeProfileDetailsCommand() + || lastExecutedCommand.getName().equals("showProfileDetails")) {//$NON-NLS-1$ + return volumeProfileStatsPopupProvider.get(); + } + else { + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + } - @Override - public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(VolumeListModel source, - UICommand lastExecutedCommand) { - if (lastExecutedCommand == getModel().getStopCommand() - || lastExecutedCommand == getModel().getRemoveVolumeCommand()) { - return removeConfirmPopupProvider.get(); - } else { - return super.getConfirmModelPopup(source, lastExecutedCommand); - } - } - }; + @Override + public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(VolumeListModel source, + UICommand lastExecutedCommand) { + if (lastExecutedCommand == getModel().getStopCommand() + || lastExecutedCommand == getModel().getRemoveVolumeCommand()) { + return removeConfirmPopupProvider.get(); + } else { + return super.getConfirmModelPopup(source, lastExecutedCommand); + } + } + }; result.setModelProvider(modelProvider); return result; } @@ -108,39 +115,71 @@ final Provider<VolumeBrickListModel> modelProvider) { SearchableDetailTabModelProvider<GlusterBrickEntity, VolumeListModel, VolumeBrickListModel> result = new SearchableDetailTabModelProvider<GlusterBrickEntity, VolumeListModel, VolumeBrickListModel>( - eventBus, defaultConfirmPopupProvider) { - @Override - public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeBrickListModel source, - UICommand lastExecutedCommand, - Model windowModel) { - if (lastExecutedCommand == getModel().getAddBricksCommand()) { - return addBrickPopupProvider.get(); - } else if (lastExecutedCommand == getModel().getRemoveBricksCommand()) { - return removeBrickPopupProvider.get(); - } else if (lastExecutedCommand == getModel().getStatusRemoveBricksCommand()) { - return removeBricksStatusPopupProvider.get(); - }else if (lastExecutedCommand.getName().equals("OnStopRemoveBricks")) { //$NON-NLS-1$ - return removeBricksStatusPopupProvider.get(); - } else if (lastExecutedCommand == getModel().getReplaceBrickCommand()) { - return replaceBrickPopupProvider.get(); - } else if (lastExecutedCommand == getModel().getBrickAdvancedDetailsCommand()) { - return brickDetailsPopupProvider.get(); - } else { - return super.getModelPopup(source, lastExecutedCommand, windowModel); - } - } + eventBus, defaultConfirmPopupProvider) { + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeBrickListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand == getModel().getAddBricksCommand()) { + return addBrickPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getRemoveBricksCommand()) { + return removeBrickPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getStatusRemoveBricksCommand()) { + return removeBricksStatusPopupProvider.get(); + } else if (lastExecutedCommand.getName().equals("OnStopRemoveBricks")) { //$NON-NLS-1$ + return removeBricksStatusPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getReplaceBrickCommand()) { + return replaceBrickPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getBrickAdvancedDetailsCommand()) { + return brickDetailsPopupProvider.get(); + } else { + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + } - @Override - public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(VolumeBrickListModel source, - UICommand lastExecutedCommand) { - if (lastExecutedCommand == getModel().getRemoveBricksCommand()) { - return removeConfirmPopupProvider.get(); - } else { - return super.getConfirmModelPopup(source, lastExecutedCommand); - } - } + @Override + public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(VolumeBrickListModel source, + UICommand lastExecutedCommand) { + if (lastExecutedCommand == getModel().getRemoveBricksCommand()) { + return removeConfirmPopupProvider.get(); + } else { + return super.getConfirmModelPopup(source, lastExecutedCommand); + } + } - }; + }; + result.setMainModelProvider(mainModelProvider); + result.setModelProvider(modelProvider); + return result; + } + + @Provides + @Singleton + public SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> getVolumeSnapshotListProvider(EventBus eventBus, + Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider, + final Provider<VolumeListModel> mainModelProvider, + final Provider<GlusterVolumeSnapshotListModel> modelProvider, + final Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> snapshotPopupProvider) { + SearchableDetailTabModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> result = + new SearchableDetailTabModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel>( + eventBus, defaultConfirmPopupProvider) { + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(GlusterVolumeSnapshotListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand == getModel().getNewSnapshotCommand()) { + return snapshotPopupProvider.get(); + } + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + + @Override + public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(GlusterVolumeSnapshotListModel source, + UICommand lastExecutedCommand) { + return super.getConfirmModelPopup(source, lastExecutedCommand); + } + + }; result.setMainModelProvider(mainModelProvider); result.setModelProvider(modelProvider); return result; @@ -156,20 +195,20 @@ final Provider<VolumeParameterListModel> modelProvider) { SearchableDetailTabModelProvider<GlusterVolumeOptionEntity, VolumeListModel, VolumeParameterListModel> result = new SearchableDetailTabModelProvider<GlusterVolumeOptionEntity, VolumeListModel, VolumeParameterListModel>( - eventBus, defaultConfirmPopupProvider) { - @Override - public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeParameterListModel source, - UICommand lastExecutedCommand, - Model windowModel) { - if (lastExecutedCommand == getModel().getAddParameterCommand()) { - return addParameterPopupProvider.get(); - } else if (lastExecutedCommand == getModel().getEditParameterCommand()) { - return editParameterPopupProvider.get(); - } else { - return super.getModelPopup(source, lastExecutedCommand, windowModel); - } - } - }; + eventBus, defaultConfirmPopupProvider) { + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeParameterListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand == getModel().getAddParameterCommand()) { + return addParameterPopupProvider.get(); + } else if (lastExecutedCommand == getModel().getEditParameterCommand()) { + return editParameterPopupProvider.get(); + } else { + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + } + }; result.setMainModelProvider(mainModelProvider); result.setModelProvider(modelProvider); return result; @@ -184,18 +223,18 @@ final Provider<VolumeEventListModel> modelProvider) { SearchableDetailTabModelProvider<AuditLog, VolumeListModel, VolumeEventListModel> result = new SearchableDetailTabModelProvider<AuditLog, VolumeListModel, VolumeEventListModel>( - eventBus, defaultConfirmPopupProvider) { - @Override - public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeEventListModel source, - UICommand lastExecutedCommand, - Model windowModel) { - if (lastExecutedCommand.equals(getModel().getDetailsCommand())) { - return eventPopupProvider.get(); - } else { - return super.getModelPopup(source, lastExecutedCommand, windowModel); - } - } - }; + eventBus, defaultConfirmPopupProvider) { + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(VolumeEventListModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (lastExecutedCommand.equals(getModel().getDetailsCommand())) { + return eventPopupProvider.get(); + } else { + return super.getModelPopup(source, lastExecutedCommand, windowModel); + } + } + }; result.setMainModelProvider(mainModelProvider); result.setModelProvider(modelProvider); return result; @@ -208,18 +247,25 @@ bind(VolumeBrickListModel.class).in(Singleton.class); bind(VolumeParameterListModel.class).in(Singleton.class); bind(VolumeEventListModel.class).in(Singleton.class); - bind(new TypeLiteral<PermissionListModel<VolumeListModel>>(){}).in(Singleton.class); + bind(new TypeLiteral<PermissionListModel<VolumeListModel>>() {}).in(Singleton.class); + bind(GlusterVolumeSnapshotListModel.class).in(Singleton.class); // Form Detail Models - bind(new TypeLiteral<DetailModelProvider<VolumeListModel, VolumeGeneralModel>>(){}) - .to(new TypeLiteral<DetailTabModelProvider<VolumeListModel, VolumeGeneralModel>>(){}).in(Singleton.class); + bind(new TypeLiteral<DetailModelProvider<VolumeListModel, VolumeGeneralModel>>() { + }) + .to(new TypeLiteral<DetailTabModelProvider<VolumeListModel, VolumeGeneralModel>>() { + }).in(Singleton.class); // Search-able Detail Models - bind(new TypeLiteral<SearchableDetailModelProvider<GlusterGeoRepSession, VolumeListModel, VolumeGeoRepListModel>>(){}) - .to(new TypeLiteral<SearchableDetailTabModelProvider<GlusterGeoRepSession, VolumeListModel, VolumeGeoRepListModel>>(){}) - .in(Singleton.class); + bind(new TypeLiteral<SearchableDetailModelProvider<GlusterGeoRepSession, VolumeListModel, VolumeGeoRepListModel>>() { + }) + .to(new TypeLiteral<SearchableDetailTabModelProvider<GlusterGeoRepSession, VolumeListModel, VolumeGeoRepListModel>>() { + }) + .in(Singleton.class); // Permission Detail Model - bind(new TypeLiteral<SearchableDetailModelProvider<Permissions, VolumeListModel, PermissionListModel<VolumeListModel>>>(){}) - .to(new TypeLiteral<PermissionModelProvider<VolumeListModel>>(){}).in(Singleton.class); + bind(new TypeLiteral<SearchableDetailModelProvider<Permissions, VolumeListModel, PermissionListModel<VolumeListModel>>>() { + }) + .to(new TypeLiteral<PermissionModelProvider<VolumeListModel>>() { + }).in(Singleton.class); } } diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java new file mode 100644 index 0000000..ca5eb16 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/gluster/GlusterVolumeSnapshotCreatePopupPresenterWidget.java @@ -0,0 +1,34 @@ +package org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster; + +import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; +import org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel; +import org.ovirt.engine.ui.uicompat.Event; +import org.ovirt.engine.ui.uicompat.EventArgs; +import org.ovirt.engine.ui.uicompat.IEventListener; + +import com.google.gwt.event.shared.EventBus; +import com.google.inject.Inject; +import com.google.inject.Provider; + +public class GlusterVolumeSnapshotCreatePopupPresenterWidget extends AbstractModelBoundPopupPresenterWidget<GlusterVolumeSnapshotModel, GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef> { + @Inject + public GlusterVolumeSnapshotCreatePopupPresenterWidget(EventBus eventBus, ViewDef view, Provider<GlusterVolumeSnapshotCreatePopupPresenterWidget> snapshotPopupProvider, Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupPrivder) { + super(eventBus, view); + } + + @Override + public void init(final GlusterVolumeSnapshotModel model) { + super.init(model); + model.getForceCreate().getEntityChangedEvent().addListener(new IEventListener<EventArgs>() { + @Override + public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { + getView().setForceLabelVisibility(model.getForceCreate().getEntity()); + } + }); + } + + public interface ViewDef extends AbstractModelBoundPopupPresenterWidget.ViewDef<GlusterVolumeSnapshotModel> { + public void setForceLabelVisibility(boolean visible); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/gluster/SubTabGlusterVolumeSnapshotPresenter.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/gluster/SubTabGlusterVolumeSnapshotPresenter.java new file mode 100644 index 0000000..7220eda --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/tab/gluster/SubTabGlusterVolumeSnapshotPresenter.java @@ -0,0 +1,58 @@ +package org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster; + +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.ui.common.place.PlaceRequestFactory; +import org.ovirt.engine.ui.common.presenter.AbstractSubTabPresenter; +import org.ovirt.engine.ui.common.uicommon.model.SearchableDetailModelProvider; +import org.ovirt.engine.ui.common.widget.tab.ModelBoundTabData; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotListModel; +import org.ovirt.engine.ui.uicommonweb.models.volumes.VolumeListModel; +import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.VolumeSelectionChangeEvent; + +import com.google.gwt.event.shared.EventBus; +import com.google.inject.Inject; +import com.gwtplatform.mvp.client.TabData; +import com.gwtplatform.mvp.client.annotations.NameToken; +import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit; +import com.gwtplatform.mvp.client.annotations.ProxyEvent; +import com.gwtplatform.mvp.client.annotations.TabInfo; +import com.gwtplatform.mvp.client.proxy.PlaceManager; +import com.gwtplatform.mvp.client.proxy.TabContentProxyPlace; +import com.gwtplatform.mvp.shared.proxy.PlaceRequest; + +public class SubTabGlusterVolumeSnapshotPresenter extends AbstractSubTabPresenter<GlusterVolumeEntity, VolumeListModel, GlusterVolumeSnapshotListModel, SubTabGlusterVolumeSnapshotPresenter.ViewDef, SubTabGlusterVolumeSnapshotPresenter.ProxyDef> { + @TabInfo(container = VolumeSubTabPanelPresenter.class) + static TabData getTabData(ApplicationConstants applicationConstants, + SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> modelProvider) { + return new ModelBoundTabData(applicationConstants.volumeSnapshotSubTabLabel(), 5, modelProvider); + } + + @Inject + public SubTabGlusterVolumeSnapshotPresenter(EventBus eventBus, ViewDef view, ProxyDef proxy, + PlaceManager placeManager, + SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> modelProvider) { + super(eventBus, view, proxy, placeManager, modelProvider, + VolumeSubTabPanelPresenter.TYPE_SetTabContent); + } + + @ProxyCodeSplit + @NameToken(WebAdminApplicationPlaces.volumeSnapshotSubTabPlace) + public interface ProxyDef extends TabContentProxyPlace<SubTabGlusterVolumeSnapshotPresenter> { + } + + public interface ViewDef extends AbstractSubTabPresenter.ViewDef<GlusterVolumeEntity> { + } + + @Override + protected PlaceRequest getMainTabRequest() { + return PlaceRequestFactory.get(WebAdminApplicationPlaces.volumeMainTabPlace); + } + + @ProxyEvent + public void onVolumeSelectionChange(VolumeSelectionChangeEvent event) { + updateMainTabSelection(event.getSelectedItems()); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java new file mode 100644 index 0000000..909e918 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.java @@ -0,0 +1,124 @@ +package org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster; + +import org.ovirt.engine.ui.common.idhandler.ElementIdHandler; +import org.ovirt.engine.ui.common.idhandler.WithElementId; +import org.ovirt.engine.ui.common.view.popup.AbstractModelBoundPopupView; +import org.ovirt.engine.ui.common.widget.Align; +import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel; +import org.ovirt.engine.ui.common.widget.editor.generic.EntityModelCheckBoxEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelLabelEditor; +import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotModel; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.ApplicationResources; +import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.gluster.GlusterVolumeSnapshotCreatePopupPresenterWidget; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.editor.client.SimpleBeanEditorDriver; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.TextArea; +import com.google.inject.Inject; + +public class GlusterVolumeSnapshotCreatePopupView extends AbstractModelBoundPopupView<GlusterVolumeSnapshotModel> implements GlusterVolumeSnapshotCreatePopupPresenterWidget.ViewDef { + interface Driver extends SimpleBeanEditorDriver<GlusterVolumeSnapshotModel, GlusterVolumeSnapshotCreatePopupView> { + } + + interface ViewUiBinder extends UiBinder<SimpleDialogPanel, GlusterVolumeSnapshotCreatePopupView> { + ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class); + } + + interface ViewIdHandler extends ElementIdHandler<GlusterVolumeSnapshotCreatePopupView> { + ViewIdHandler idHandler = GWT.create(ViewIdHandler.class); + } + + @UiField + WidgetStyle style; + + @UiField + @Path(value = "clusterName.entity") + @WithElementId + StringEntityModelLabelEditor clusterNameEditor; + + @UiField + @Path(value = "volumeName.entity") + @WithElementId + StringEntityModelLabelEditor volumeNameEditor; + + @UiField + @Path(value = "snapshotName.entity") + @WithElementId + StringEntityModelTextBoxEditor snapshotNameEditor; + + @UiField + @Path(value = "description.entity") + @WithElementId + StringEntityModelTextBoxEditor snapshotDescriptionEditor; + + @UiField(provided = true) + @Path(value = "forceCreate.entity") + @WithElementId + EntityModelCheckBoxEditor forceCreateEditor; + + @UiField + @Ignore + TextArea forceWarningLabel; + + private final ApplicationConstants constants; + + private final Driver driver = GWT.create(Driver.class); + + @Inject + public GlusterVolumeSnapshotCreatePopupView(EventBus eventBus, + ApplicationResources resources, + ApplicationConstants constants) { + super(eventBus, resources); + this.constants = constants; + initEditors(); + initWidget(ViewUiBinder.uiBinder.createAndBindUi(this)); + ViewIdHandler.idHandler.generateAndSetIds(this); + localize(); + addStyles(); + driver.initialize(this); + setTitle(constants.newVolumeSnapshot()); + } + + private void initEditors() { + forceCreateEditor = new EntityModelCheckBoxEditor(Align.RIGHT); + } + + private void addStyles() { + forceCreateEditor.addContentWidgetContainerStyleName(style.checkBoxEditorWidget()); + } + + private void localize() { + clusterNameEditor.setLabel(constants.volumeClusterLabel()); + volumeNameEditor.setLabel(constants.volumeNameLabel()); + snapshotNameEditor.setLabel(constants.volumeSnapshotNameLabel()); + snapshotDescriptionEditor.setLabel(constants.volumeSnapshotDescriptionLabel()); + forceCreateEditor.setLabel(constants.forceVolumeSnapshotCreationLabel()); + forceWarningLabel.setText(constants.volumeQuorumNote()); + } + + @Override + public void edit(final GlusterVolumeSnapshotModel object) { + driver.edit(object); + setForceLabelVisibility(object.getForceCreate().getEntity()); + } + + @Override + public GlusterVolumeSnapshotModel flush() { + return driver.flush(); + } + + interface WidgetStyle extends CssResource { + String checkBoxEditorWidget(); + } + + @Override + public void setForceLabelVisibility(boolean visible) { + forceWarningLabel.setVisible(visible); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml new file mode 100644 index 0000000..c61f122 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/popup/gluster/GlusterVolumeSnapshotCreatePopupView.ui.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> +<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" + xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:d="urn:import:org.ovirt.engine.ui.common.widget.dialog" + xmlns:ge="urn:import:org.ovirt.engine.ui.common.widget.editor.generic" + xmlns:e="urn:import:org.ovirt.engine.ui.common.widget.editor" xmlns:w="urn:import:org.ovirt.engine.ui.common.widget"> + + <ui:style + type="org.ovirt.engine.ui.webadmin.section.main.view.popup.gluster.GlusterVolumeSnapshotCreatePopupView.WidgetStyle"> + .forceWarningLabel { + width: 450px; + font-size: 13px; + left: 10px; + padding-left: 15px; + padding-bottom: 10px; + color: #FF0000; + } + + .panelStyle{ + width:470px; + } + + .messageLabel { + color: #FF0000; + left: 10px; + padding-left: + 5px; + } + + .checkBoxEditorWidget{ + width: 450px; + } + </ui:style> + + <d:SimpleDialogPanel width="480px" height="400px"> + <d:content> + <g:FlowPanel addStyleNames="{style.panelStyle}"> + <ge:StringEntityModelLabelEditor + ui:field="clusterNameEditor" /> + <ge:StringEntityModelLabelEditor + ui:field="volumeNameEditor" /> + <ge:StringEntityModelTextBoxEditor + ui:field="snapshotNameEditor" /> + <ge:StringEntityModelTextBoxEditor + ui:field="snapshotDescriptionEditor" /> + <ge:EntityModelCheckBoxEditor ui:field="forceCreateEditor" /> + <g:FlowPanel addStyleNames="{style.panelStyle}"> + <g:TextArea ui:field="forceWarningLabel" addStyleNames="{style.forceWarningLabel}" /> + </g:FlowPanel> + </g:FlowPanel> + </d:content> + </d:SimpleDialogPanel> +</ui:UiBinder> \ No newline at end of file diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java index dd7087b..b1f6fd7 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/MainTabVolumeView.java @@ -60,7 +60,8 @@ statusColumn.makeSortable(new Comparator<GlusterVolumeEntity>() { @Override public int compare(GlusterVolumeEntity o1, GlusterVolumeEntity o2) { - return GlusterVolumeUtils.getVolumeStatus(o1).ordinal() - GlusterVolumeUtils.getVolumeStatus(o2).ordinal(); + return GlusterVolumeUtils.getVolumeStatus(o1).ordinal() + - GlusterVolumeUtils.getVolumeStatus(o2).ordinal(); } }); getTable().addColumn(statusColumn, constants.empty(), "30px"); //$NON-NLS-1$ @@ -142,11 +143,11 @@ }, constants.volumeCapacity(), "60px");//$NON-NLS-1$ getTable().addColumn(new VolumeActivityColumn<GlusterVolumeEntity>(new VolumeActivityCompositeCell<GlusterTaskSupport>(compositeList) { - @Override - protected boolean isVisible(GlusterTaskSupport value) { - return !(value == null || value.getAsyncTask() == null); - } - }), + @Override + protected boolean isVisible(GlusterTaskSupport value) { + return !(value == null || value.getAsyncTask() == null); + } + }), constants.activitiesOnVolume(), "100px"); //$NON-NLS-1$ @@ -187,7 +188,8 @@ } }); - List<ActionButtonDefinition<GlusterVolumeEntity>> volumeProfilingActions = new LinkedList<ActionButtonDefinition<GlusterVolumeEntity>>(); + List<ActionButtonDefinition<GlusterVolumeEntity>> volumeProfilingActions = + new LinkedList<ActionButtonDefinition<GlusterVolumeEntity>>(); volumeProfilingActions.add(new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.startVolumeProfiling()) { @Override protected UICommand resolveCommand() { @@ -206,7 +208,26 @@ return getMainModel().getStopVolumeProfilingCommand(); } }); - getTable().addActionButton(new WebAdminMenuBarButtonDefinition<GlusterVolumeEntity>(constants.volumeProfilingAction(), volumeProfilingActions, CommandLocation.ContextAndToolBar)); + + getTable().addActionButton(new WebAdminMenuBarButtonDefinition<GlusterVolumeEntity>(constants.volumeProfilingAction(), + volumeProfilingActions, + CommandLocation.ContextAndToolBar)); + + getTable().addActionButton(new WebAdminMenuBarButtonDefinition<GlusterVolumeEntity>(constants.volumeSnapshotMainTabTitle(), + getVolumeSnapshotMenu(constants), + CommandLocation.ContextAndToolBar)); + } + + private List<ActionButtonDefinition<GlusterVolumeEntity>> getVolumeSnapshotMenu(ApplicationConstants constants) { + List<ActionButtonDefinition<GlusterVolumeEntity>> snapshotMenu = new ArrayList<ActionButtonDefinition<GlusterVolumeEntity>>(); + WebAdminButtonDefinition<GlusterVolumeEntity> newSnapshotButton = new WebAdminButtonDefinition<GlusterVolumeEntity>(constants.newVolumeSnapshot()) { + @Override + protected UICommand resolveCommand() { + return getMainModel().getCreateSnapshotCommand(); + } + }; + snapshotMenu.add(newSnapshotButton); + return snapshotMenu; } private MenuCell<GlusterTaskSupport> getRebalanceActivityMenu(ApplicationConstants constants) { diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/gluster/SubTabGlusterVolumeSnapshotView.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/gluster/SubTabGlusterVolumeSnapshotView.java new file mode 100644 index 0000000..79f20a5 --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/view/tab/gluster/SubTabGlusterVolumeSnapshotView.java @@ -0,0 +1,76 @@ +package org.ovirt.engine.ui.webadmin.section.main.view.tab.gluster; + +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.ui.common.idhandler.ElementIdHandler; +import org.ovirt.engine.ui.common.uicommon.model.SearchableDetailModelProvider; +import org.ovirt.engine.ui.common.widget.table.column.TextColumnWithTooltip; +import org.ovirt.engine.ui.uicommonweb.models.gluster.GlusterVolumeSnapshotListModel; +import org.ovirt.engine.ui.uicommonweb.models.volumes.VolumeListModel; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.section.main.presenter.tab.gluster.SubTabGlusterVolumeSnapshotPresenter; +import org.ovirt.engine.ui.webadmin.section.main.view.AbstractSubTabTableView; +import org.ovirt.engine.ui.webadmin.widget.table.column.GlusterVolumeSnapshotStatusColumn; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.i18n.client.DateTimeFormat; +import com.google.inject.Inject; + +public class SubTabGlusterVolumeSnapshotView extends AbstractSubTabTableView<GlusterVolumeEntity, GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> implements SubTabGlusterVolumeSnapshotPresenter.ViewDef { + + interface ViewIdHandler extends ElementIdHandler<SubTabGlusterVolumeSnapshotView> { + ViewIdHandler idHandler = GWT.create(ViewIdHandler.class); + } + + @Inject + public SubTabGlusterVolumeSnapshotView(SearchableDetailModelProvider<GlusterVolumeSnapshotEntity, VolumeListModel, GlusterVolumeSnapshotListModel> modelProvider, + ApplicationConstants constants) { + super(modelProvider); + initTable(constants); + initWidget(getTable()); + } + + @Override + protected void generateIds() { + ViewIdHandler.idHandler.generateAndSetIds(this); + } + + void initTable(ApplicationConstants constants) { + getTable().enableColumnResizing(); + + GlusterVolumeSnapshotStatusColumn snapshotStatusColumn = new GlusterVolumeSnapshotStatusColumn(); + snapshotStatusColumn.makeSortable(); + getTable().addColumn(snapshotStatusColumn, constants.empty(), "30px"); //$NON-NLS-1$ + + TextColumnWithTooltip<GlusterVolumeSnapshotEntity> snapshotNameColumn = + new TextColumnWithTooltip<GlusterVolumeSnapshotEntity>() { + @Override + public String getValue(GlusterVolumeSnapshotEntity snapshot) { + return snapshot.getSnapshotName(); + } + }; + snapshotNameColumn.makeSortable(); + getTable().addColumn(snapshotNameColumn, constants.volumeSnapshotName(), "300px"); //$NON-NLS-1$ + + TextColumnWithTooltip<GlusterVolumeSnapshotEntity> descriptionColumn = + new TextColumnWithTooltip<GlusterVolumeSnapshotEntity>() { + @Override + public String getValue(GlusterVolumeSnapshotEntity snapshot) { + return snapshot.getDescription(); + } + }; + descriptionColumn.makeSortable(); + getTable().addColumn(descriptionColumn, constants.volumeSnapshotDescription(), "400px"); //$NON-NLS-1$ + + TextColumnWithTooltip<GlusterVolumeSnapshotEntity> creationTimeColumn = + new TextColumnWithTooltip<GlusterVolumeSnapshotEntity>() { + @Override + public String getValue(GlusterVolumeSnapshotEntity snapshot) { + DateTimeFormat df = DateTimeFormat.getFormat("yyyy-MM-dd, HH:mm:ss"); //$NON-NLS-1$ + return df.format(snapshot.getCreatedAt()); + } + }; + creationTimeColumn.makeSortable(); + getTable().addColumn(creationTimeColumn, constants.volumeSnapshotCreationTime(), "400px"); //$NON-NLS-1$ + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusCell.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusCell.java new file mode 100644 index 0000000..1560a3c --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusCell.java @@ -0,0 +1,60 @@ +package org.ovirt.engine.ui.webadmin.widget.table.column; + +import org.ovirt.engine.core.common.businessentities.gluster.GlusterSnapshotStatus; +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.ui.webadmin.ApplicationConstants; +import org.ovirt.engine.ui.webadmin.ApplicationResources; +import org.ovirt.engine.ui.webadmin.ApplicationTemplates; +import org.ovirt.engine.ui.webadmin.gin.ClientGinjectorProvider; + +import com.google.gwt.cell.client.AbstractCell; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.safehtml.shared.SafeHtml; +import com.google.gwt.safehtml.shared.SafeHtmlBuilder; +import com.google.gwt.safehtml.shared.SafeHtmlUtils; +import com.google.gwt.user.client.ui.AbstractImagePrototype; + +public class GlusterVolumeSnapshotStatusCell extends AbstractCell<GlusterVolumeSnapshotEntity> { + + private static final ApplicationResources resources = ClientGinjectorProvider.getApplicationResources(); + + private static final ApplicationConstants constants = ClientGinjectorProvider.getApplicationConstants(); + + private static final ApplicationTemplates applicationTemplates = ClientGinjectorProvider.getApplicationTemplates(); + + @Override + public void render(Context context, GlusterVolumeSnapshotEntity snapshot, SafeHtmlBuilder sb) { + // Nothing to render if no snapshot is provided: + if (snapshot == null) { + return; + } + + // Find the image corresponding to the status of the brick: + GlusterSnapshotStatus status = snapshot.getStatus(); + ImageResource statusImage = null; + String tooltip; + + switch (status) { + case STARTED: + statusImage = resources.upImage(); + tooltip = constants.up(); + break; + case STOPPED: + statusImage = resources.downImage(); + tooltip = constants.down(); + break; + case UNKNOWN: + statusImage = resources.questionMarkImage(); + tooltip = constants.unknown(); + break; + default: + statusImage = resources.downImage(); + tooltip = constants.down(); + } + + // Generate the HTML for the image: + SafeHtml statusImageHtml = + SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(statusImage).getHTML()); + sb.append(applicationTemplates.statusTemplate(statusImageHtml, tooltip)); + } +} diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusColumn.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusColumn.java new file mode 100644 index 0000000..add4a7d --- /dev/null +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/widget/table/column/GlusterVolumeSnapshotStatusColumn.java @@ -0,0 +1,27 @@ +package org.ovirt.engine.ui.webadmin.widget.table.column; + +import java.util.Comparator; + +import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; +import org.ovirt.engine.ui.common.widget.table.column.SortableColumn; + +public class GlusterVolumeSnapshotStatusColumn extends SortableColumn<GlusterVolumeSnapshotEntity, GlusterVolumeSnapshotEntity> { + + public GlusterVolumeSnapshotStatusColumn() { + super(new GlusterVolumeSnapshotStatusCell()); + } + + @Override + public GlusterVolumeSnapshotEntity getValue(GlusterVolumeSnapshotEntity object) { + return object; + } + + public void makeSortable() { + makeSortable(new Comparator<GlusterVolumeSnapshotEntity>() { + @Override + public int compare(GlusterVolumeSnapshotEntity o1, GlusterVolumeSnapshotEntity o2) { + return o1.getStatus().ordinal() - o2.getStatus().ordinal(); + } + }); + } +} -- To view, visit http://gerrit.ovirt.org/36334 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5161753920ef72c245f1785e754df97465a19602 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Shubhendu Tripathi <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
