From c0870fcad01a8efa38c674795259aa2784e3a47b Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 2 Nov 2011 12:40:12 +0530 Subject: Story #70: "Force" option in volume stop --- .../console/GlusterDataModelManager.java | 6 ++ .../console/actions/DeleteVolumeAction.java | 67 +++++++++++++------ .../console/actions/ForceStartVolumeAction.java | 2 +- .../console/actions/StartVolumeAction.java | 8 +++ .../console/actions/StopVolumeAction.java | 78 ++++++++++++++++------ .../console/views/VolumesSummaryView.java | 13 ++-- .../management/core/model/ClusterListener.java | 2 + .../core/model/DefaultClusterListener.java | 5 ++ 8 files changed, 136 insertions(+), 45 deletions(-) diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java index e43bcbae..5fff61b9 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java @@ -882,6 +882,12 @@ public class GlusterDataModelManager { } } + public void alertsRemoved() { + for (ClusterListener listener : listeners) { + listener.alertsRemoved(); + } + } + public List getVolumeOptionsInfo() { if(volumeOptionsInfo == null || volumeOptionsInfo.isEmpty()) { initializeVolumeOptionsInfo(getModel().getCluster()); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java index f5f7d209..d764dcc0 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java @@ -40,6 +40,9 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { private List selectedVolumes = new ArrayList(); private List selectedVolumeNames = new ArrayList(); private List onlineVolumeNames = new ArrayList(); + private List deletedVolumeNames = new ArrayList(); + private List failedVolumes = new ArrayList(); + private List failedVolumeNames = new ArrayList(); @Override protected void performAction(final IAction action, IProgressMonitor monitor) { @@ -76,18 +79,55 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { return; } + String errorMessage = performDeleteVolume(monitor,selectedVolumes, directoryDeleteOption, false); + + // Display the success or failure info + if (deletedVolumeNames.size() == 0) { // No volume(s) deleted successfully + String message = "volumes " + failedVolumeNames + " could not be delete! " + CoreConstants.NEWLINE + + "Error: [" + errorMessage + "]"; + errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, directoryDeleteOption, + message); + } else { + String info = "Volumes " + deletedVolumeNames + " deleted successfully!"; + if (!errorMessage.equals("")) { + String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames + + " could not be deleted! [" + errorMessage + "]"; + errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, + directoryDeleteOption, message); + } + if (errorMessage.equals("")) { + errorMessage = info; + } + } + showInfoDialog(actionDesc, errorMessage); + } + + private String performForceStopAndDeleteVolume(IProgressMonitor monitor, String actionDesc, List volumesToDelete, + Integer directoryDeleteOption, String message) { + boolean forceStop = showConfirmDialog(actionDesc, message + CoreConstants.NEWLINE + CoreConstants.NEWLINE + + "Do you want to stop forcefully and delete?"); + if (!forceStop) { + return ""; + } + return performDeleteVolume(monitor, volumesToDelete, directoryDeleteOption, true); + } + + private String performDeleteVolume(IProgressMonitor monitor, List volumeNeedsToDelete, + final Integer directoryDeleteOption, Boolean force) { + deletedVolumeNames.clear(); + failedVolumeNames.clear(); + failedVolumes.clear(); VolumesClient vc = new VolumesClient(); boolean confirmDeleteDir = (directoryDeleteOption == 1) ? true : false; - List deletedVolumeNames = new ArrayList(); - List failedVolumes = new ArrayList(); + String errorMessage = ""; - monitor.beginTask("Deleting Selected Volumes...", selectedVolumes.size()); - for (Volume volume : selectedVolumes.toArray(new Volume[0])) { + monitor.beginTask("Deleting Selected Volumes...", volumeNeedsToDelete.size()); + for (Volume volume : volumeNeedsToDelete.toArray(new Volume[0])) { try { monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume - vc.stopVolume(volume.getName(), false); + vc.stopVolume(volume.getName(), force); } vc.deleteVolume(volume.getName(), confirmDeleteDir); modelManager.deleteVolume(volume); @@ -96,7 +136,8 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { // Volume delete succeeded and post delete operation (directory cleanup, CIFS etc) may fail if (vc.volumeExists(volume.getName())) { errorMessage += CoreConstants.NEWLINE + "[" + volume.getName() + "] : [" + e.getMessage() + "]"; - failedVolumes.add(volume.getName()); + failedVolumeNames.add(volume.getName()); + failedVolumes.add(volume); } else { errorMessage += CoreConstants.NEWLINE + "Volume deleted, but following error occured: [" + e.getMessage() + "]"; @@ -107,19 +148,7 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { monitor.worked(1); } monitor.done(); - - // Display the success or failure info - if (deletedVolumeNames.size() == 0) { // No volume(s) deleted successfully - showErrorDialog(actionDesc, "volumes " + failedVolumes + " could not be delete! " + CoreConstants.NEWLINE - + "Error: [" + errorMessage + "]"); - } else { - String info = "Volumes " + deletedVolumeNames + " deleted successfully!"; - if (!errorMessage.equals("")) { - info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes - + " could not be deleted! [" + errorMessage + "]"; - } - showInfoDialog(actionDesc, info); - } + return errorMessage; } private void collectVolumeNames() { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java index 101b7982..9201aadb 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/ForceStartVolumeAction.java @@ -47,7 +47,7 @@ public class ForceStartVolumeAction extends AbstractActionDelegate { @Override public void selectionChanged(IAction action, ISelection selection) { super.selectionChanged(action, selection); - + action.setEnabled(false); volume = guiHelper.getSelectedEntity(window, Volume.class); if (volume != null) { // a volume is selected on navigation tree. Let's check if the currently open view is volume bricks view diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java index 6407b322..09b01805 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java @@ -26,13 +26,16 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.osgi.internal.signedcontent.Base64; import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.console.AlertsManager; import com.gluster.storage.management.console.GlusterDataModelManager; import com.gluster.storage.management.console.IImageKeys; import com.gluster.storage.management.console.utils.GUIHelper; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Alert.ALERT_TYPES; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; public class StartVolumeAction extends AbstractMonitoredActionDelegate { @@ -98,6 +101,11 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { try { newVolume = vc.getVolume(volume.getName()); modelManager.volumeChanged(volume, newVolume); + // Remove the offline volume alert from the AlertsManager + AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); + alertManager.removeAlert(Base64.encode( + (ALERT_TYPES.OFFLINE_VOLUME_ALERT + "-" + volume.getName()).getBytes()).toString()); + modelManager.alertsRemoved(); } catch (Exception e) { errorMessage += "Updating volume info failed on UI. [" + e.getMessage() + "]"; } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java index dad5d4ac..21bf3432 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java @@ -28,10 +28,13 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.console.AlertsManager; import com.gluster.storage.management.console.GlusterDataModelManager; import com.gluster.storage.management.console.IImageKeys; import com.gluster.storage.management.console.utils.GUIHelper; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.model.Alert; +import com.gluster.storage.management.core.model.Alert.ALERT_TYPES; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; @@ -40,6 +43,9 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { private List selectedVolumes = new ArrayList(); private List selectedVolumeNames = new ArrayList(); private List onlineVolumeNames = new ArrayList(); + private List stoppedVolumes = new ArrayList(); + private List failedVolumeNames = new ArrayList(); + private List failedVolumes = new ArrayList(); @Override protected void performAction(final IAction action, IProgressMonitor monitor) { @@ -61,10 +67,6 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { return; } - VolumesClient vc = new VolumesClient(); - List stoppedVolumes = new ArrayList(); - List failedVolumes = new ArrayList(); - String errorMessage = ""; List cifsVolumes = GlusterDataModelManager.getInstance().getCifsEnabledVolumeNames(selectedVolumes); List offlineServers = GlusterDataModelManager.getInstance().getOfflineServers(); // One or more servers are offline, Show warning if cifs is enabled @@ -80,10 +82,49 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } } + String errorMessage = performStopVolume(monitor, selectedVolumes, false); + + // Display the success or failure info + if (stoppedVolumes.size() == 0) { // No volume(s) stopped successfully + String message = "Volumes " + failedVolumeNames + " could not be stopped! " + CoreConstants.NEWLINE + + "Error: [" + errorMessage + "]"; + errorMessage = performForceStopVolume(monitor, actionDesc, message); + + } else { + String info = "Volumes " + stoppedVolumes + " stopped successfully!"; + if (!errorMessage.equals("")) { + String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames + + " failed to stop! [" + errorMessage + "]"; + errorMessage = performForceStopVolume(monitor, actionDesc, message); + } + if (errorMessage.equals("")) { + errorMessage = info; + } + } + showInfoDialog(actionDesc, errorMessage); + } + + + private String performForceStopVolume(IProgressMonitor monitor, String actionDesc, String message) { + boolean forceStop = showConfirmDialog(actionDesc, + message + CoreConstants.NEWLINE + "Do you want to stop forcefully?"); + if (!forceStop) { + return ""; + } + return performStopVolume(monitor, failedVolumes, true); + } + + private String performStopVolume(IProgressMonitor monitor, List volumesNeedsToStop, Boolean force) { + VolumesClient vc = new VolumesClient(); Volume newVolume = new Volume(); + stoppedVolumes.clear(); + failedVolumeNames.clear(); + failedVolumes.clear(); + String errorMessage = ""; + List volumeStopAlert = new ArrayList(); - monitor.beginTask("Stopping Selected Volumes...", selectedVolumes.size()); - for (Volume volume : selectedVolumes.toArray(new Volume[0])) { + monitor.beginTask("Stopping Selected Volumes...", volumesNeedsToStop.size()); + for (Volume volume : volumesNeedsToStop.toArray(new Volume[0])) { if(monitor.isCanceled()) { break; } @@ -94,11 +135,15 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } try { monitor.setTaskName("Stopping volume [" + volume.getName() + "]"); - vc.stopVolume(volume.getName(), false); + vc.stopVolume(volume.getName(), force); // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); stoppedVolumes.add(volume.getName()); + volumeStopAlert.add(new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), + Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() + + "]")); } catch (Exception e) { - failedVolumes.add(volume.getName()); + failedVolumeNames.add(volume.getName()); + failedVolumes.add(volume); // If any post volume stop activity failed, update the volume status if (vc.getVolume(volume.getName()).getStatus() == VOLUME_STATUS.OFFLINE) { modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); @@ -117,18 +162,13 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } monitor.done(); - // Display the success or failure info - if (stoppedVolumes.size() == 0) { // No volume(s) stopped successfully - showErrorDialog(actionDesc, "Volumes " + failedVolumes + " could not be stopped! " + CoreConstants.NEWLINE - + "Error: [" + errorMessage + "]"); - } else { - String info = "Volumes " + stoppedVolumes + " stopped successfully!"; - if (!errorMessage.equals("")) { - info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes - + " failed to stop! [" + errorMessage + "]"; - } - showInfoDialog(actionDesc, info); + // Add the offline volume alert in AlertsManager + if (volumeStopAlert.size() > 0) { + AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); + alertManager.addAlerts(volumeStopAlert); + modelManager.alertsGenerated(); } + return errorMessage; } private void collectVolumeNames() { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java index 376345e6..944956f7 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java @@ -103,7 +103,6 @@ public class VolumesSummaryView extends ViewPart { public void volumeChanged(Volume volume, Event event) { super.volumeChanged(volume, event); updateSummarySection(); - updateAlertSection(); } private void updateSummarySection() { @@ -119,6 +118,13 @@ public class VolumesSummaryView extends ViewPart { guiHelper.clearSection(alertsSection); populateAlertSection(); } + + @Override + public void alertsRemoved() { + super.alertsRemoved(); + guiHelper.clearSection(alertsSection); + populateAlertSection(); + } @Override public void taskAdded(TaskInfo taskInfo) { @@ -142,11 +148,6 @@ public class VolumesSummaryView extends ViewPart { guiHelper.clearSection(tasksSection); populateTasks(); } - - private void updateAlertSection() { - guiHelper.clearSection(alertsSection); - populateAlertSection(); - } }; GlusterDataModelManager.getInstance().addClusterListener(clusterListener); } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java index bff717b7..e0bb9c63 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java @@ -50,4 +50,6 @@ public interface ClusterListener { public void alertsGenerated(); public void aggregatedStatsChanged(); + + public void alertsRemoved(); } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java index f09d78bb..50a5d2ac 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java @@ -105,4 +105,9 @@ public class DefaultClusterListener implements ClusterListener { public void aggregatedStatsChanged() { modelChanged(); } + + @Override + public void alertsRemoved() { + modelChanged(); + } } -- cgit From 9d29863fecd8e21be5ff0dfc2835bc98302bc60a Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 2 Nov 2011 12:40:12 +0530 Subject: Story #70: "Force" option in volume stop --- .../console/GlusterDataModelManager.java | 47 +++++++-- .../console/actions/DeleteVolumeAction.java | 107 +++++++++++++-------- .../console/actions/StartVolumeAction.java | 8 +- .../console/actions/StopVolumeAction.java | 61 ++++++------ .../console/views/GlusterServersSummaryView.java | 6 +- .../console/views/VolumesSummaryView.java | 16 ++- .../management/core/model/ClusterListener.java | 4 +- .../core/model/DefaultClusterListener.java | 7 +- .../storage/management/core/model/Event.java | 2 + 9 files changed, 167 insertions(+), 91 deletions(-) diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java index 5fff61b9..b3f85ecf 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java @@ -408,6 +408,9 @@ public class GlusterDataModelManager { public void volumeChanged(Volume oldVolume, Volume newVolume) { oldVolume.copyFrom(newVolume); + + alertsChanged(newVolume, newVolume.getStatus()); + for (ClusterListener listener : listeners) { listener.volumeChanged(oldVolume, new Event(EVENT_TYPE.VOLUME_CHANGED, newVolume)); } @@ -746,6 +749,7 @@ public class GlusterDataModelManager { public void updateVolumeStatus(Volume volume, VOLUME_STATUS newStatus) { volume.setStatus(newStatus); + alertsChanged(volume, newStatus); if(newStatus == VOLUME_STATUS.OFFLINE) { // mark as bricks also as offline @@ -762,6 +766,43 @@ public class GlusterDataModelManager { listener.volumeChanged(volume, new Event(EVENT_TYPE.BRICKS_CHANGED, volume.getBricks())); } } + + private void alertsChanged(Volume volume, VOLUME_STATUS newStatus) { + Alert alert = null; + if (newStatus == VOLUME_STATUS.OFFLINE) { + alert = createVolumeAlert(volume); + for (ClusterListener listener : listeners) { + listener.alertsCreated(volume, new Event(EVENT_TYPE.ALERT_CREATED, alert)); + } + } else { + alert = removeVolumeAlert(volume); + for (ClusterListener listener : listeners) { + listener.alertsRemoved(volume, new Event(EVENT_TYPE.ALERT_REMOVED, alert)); + } + } + } + + private Alert createVolumeAlert(Volume volume) { + Alert alert = new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), + Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() + "]"); + getModel().getCluster().addAlert(alert); + return alert; + } + + private Alert removeVolumeAlert(Volume volume) { + List clusterAlerts = getModel().getCluster().getAlerts(); + Alert removedAlert = null; + for (int i = 0; i < clusterAlerts.size(); i++) { + if (clusterAlerts.get(i).getType().equals(ALERT_TYPES.OFFLINE_VOLUME_ALERT) + && clusterAlerts.get(i).getReference().equals(volume.getName())) { + removedAlert = clusterAlerts.get(i); + clusterAlerts.remove(i); + break; + } + } + getModel().getCluster().setAlerts(clusterAlerts); + return removedAlert; + } public void resetVolumeOptions(Volume volume) { volume.getOptions().clear(); @@ -882,12 +923,6 @@ public class GlusterDataModelManager { } } - public void alertsRemoved() { - for (ClusterListener listener : listeners) { - listener.alertsRemoved(); - } - } - public List getVolumeOptionsInfo() { if(volumeOptionsInfo == null || volumeOptionsInfo.isEmpty()) { initializeVolumeOptionsInfo(getModel().getCluster()); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java index d764dcc0..a56cf82b 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java @@ -42,7 +42,6 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { private List onlineVolumeNames = new ArrayList(); private List deletedVolumeNames = new ArrayList(); private List failedVolumes = new ArrayList(); - private List failedVolumeNames = new ArrayList(); @Override protected void performAction(final IAction action, IProgressMonitor monitor) { @@ -72,85 +71,109 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { warningMessage = "Are you sure to delete the volumes " + selectedVolumeNames + " ?"; } - final Integer directoryDeleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance() + final Integer deleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance() .getImage(IImageKeys.VOLUME_16x16), warningMessage, MessageDialog.QUESTION, new String[] { "Cancel", "Delete volume and data", "Delete volume, keep data" }, -1).open(); - if (directoryDeleteOption <= 0) { // By Cancel button(0) or Escape key(-1) + if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) return; } - String errorMessage = performDeleteVolume(monitor,selectedVolumes, directoryDeleteOption, false); + String errorMessage = deleteVolumes(selectedVolumes, deleteOption, monitor); // Display the success or failure info if (deletedVolumeNames.size() == 0) { // No volume(s) deleted successfully - String message = "volumes " + failedVolumeNames + " could not be delete! " + CoreConstants.NEWLINE - + "Error: [" + errorMessage + "]"; - errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, directoryDeleteOption, - message); + if (!errorMessage.isEmpty()) { + showErrorDialog(actionDesc, "Volume could not be deleted! " + CoreConstants.NEWLINE + errorMessage); + } } else { String info = "Volumes " + deletedVolumeNames + " deleted successfully!"; - if (!errorMessage.equals("")) { - String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames - + " could not be deleted! [" + errorMessage + "]"; - errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, - directoryDeleteOption, message); - } - if (errorMessage.equals("")) { - errorMessage = info; + if (!errorMessage.isEmpty()) { + info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes + + " could not be deleted!" + errorMessage; } + showInfoDialog(actionDesc, info); } - showInfoDialog(actionDesc, errorMessage); } - private String performForceStopAndDeleteVolume(IProgressMonitor monitor, String actionDesc, List volumesToDelete, - Integer directoryDeleteOption, String message) { - boolean forceStop = showConfirmDialog(actionDesc, message + CoreConstants.NEWLINE + CoreConstants.NEWLINE - + "Do you want to stop forcefully and delete?"); - if (!forceStop) { - return ""; - } - return performDeleteVolume(monitor, volumesToDelete, directoryDeleteOption, true); - } - - private String performDeleteVolume(IProgressMonitor monitor, List volumeNeedsToDelete, - final Integer directoryDeleteOption, Boolean force) { + private String deleteVolumes(List volumes, final Integer deleteOption, IProgressMonitor monitor) { deletedVolumeNames.clear(); - failedVolumeNames.clear(); failedVolumes.clear(); VolumesClient vc = new VolumesClient(); - boolean confirmDeleteDir = (directoryDeleteOption == 1) ? true : false; + boolean confirmDeleteDir = (deleteOption == 1) ? true : false; String errorMessage = ""; - monitor.beginTask("Deleting Selected Volumes...", volumeNeedsToDelete.size()); - for (Volume volume : volumeNeedsToDelete.toArray(new Volume[0])) { - try { - monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); - if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume - vc.stopVolume(volume.getName(), force); + // To calculate the total work we need to sum volumes size + online volumes (because we treat stop and delete as + // separate steps) + List onlineVolumes = getOnlineVolume(volumes); + monitor.beginTask("Deleting Selected Volumes...", volumes.size() + onlineVolumes.size()); + + // Deletion of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. + for (Volume volume : volumes.toArray(new Volume[0])) { + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume + monitor.setTaskName("Stopping volume [" + volume.getName() + "]"); + try { + vc.stopVolume(volume.getName(), false); + } catch (Exception e1) { + // try again with force = true + try { + vc.stopVolume(volume.getName(), true); + } catch(Exception e2) { + // force stop also failed. + // Mark as deletion failed, append error message. + errorMessage += CoreConstants.NEWLINE + "Stop volume failed on [" + volume.getName() + "] : [" + + e2.getMessage() + "]"; + failedVolumes.add(volume); + + // since we are not going to perform delete on this volume, + // mark the deletion task as worked + monitor.worked(1); + + // continue to next volume without trying to delete this one + continue; + } + } finally { + // worked for "stop" operation + monitor.worked(1); } + } + + monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); + try { vc.deleteVolume(volume.getName(), confirmDeleteDir); modelManager.deleteVolume(volume); deletedVolumeNames.add(volume.getName()); } catch (Exception e) { // Volume delete succeeded and post delete operation (directory cleanup, CIFS etc) may fail if (vc.volumeExists(volume.getName())) { - errorMessage += CoreConstants.NEWLINE + "[" + volume.getName() + "] : [" + e.getMessage() + "]"; - failedVolumeNames.add(volume.getName()); + errorMessage += CoreConstants.NEWLINE + "Error [" + volume.getName() + "] : [" + e.getMessage() + "]"; failedVolumes.add(volume); } else { - errorMessage += CoreConstants.NEWLINE + "Volume deleted, but following error occured: [" - + e.getMessage() + "]"; + errorMessage += CoreConstants.NEWLINE + "Volume [" + volume.getName() + + "] deleted, but following error occured: [" + e.getMessage() + "]"; modelManager.deleteVolume(volume); deletedVolumeNames.add(volume.getName()); } + } finally { + monitor.worked(1); } - monitor.worked(1); } monitor.done(); return errorMessage; } + private List getOnlineVolume(List volumes) { + List onlineVolumes = new ArrayList(); + for (Volume volume : volumes) { + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { + onlineVolumes.add(volume); + } + } + return onlineVolumes; + } + private void collectVolumeNames() { selectedVolumeNames.clear(); onlineVolumeNames.clear(); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java index 09b01805..78ae21c7 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java @@ -77,6 +77,9 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { } monitor.beginTask("Starting Selected Volumes...", selectedVolumes.size()); + // Starting of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. for (Volume volume : selectedVolumes.toArray(new Volume[0])) { if(monitor.isCanceled()) { break; @@ -101,11 +104,6 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { try { newVolume = vc.getVolume(volume.getName()); modelManager.volumeChanged(volume, newVolume); - // Remove the offline volume alert from the AlertsManager - AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); - alertManager.removeAlert(Base64.encode( - (ALERT_TYPES.OFFLINE_VOLUME_ALERT + "-" + volume.getName()).getBytes()).toString()); - modelManager.alertsRemoved(); } catch (Exception e) { errorMessage += "Updating volume info failed on UI. [" + e.getMessage() + "]"; } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java index 21bf3432..872213fe 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java @@ -82,49 +82,54 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } } - String errorMessage = performStopVolume(monitor, selectedVolumes, false); + String errorMessage = performStopVolume(selectedVolumes, false, monitor); // Display the success or failure info if (stoppedVolumes.size() == 0) { // No volume(s) stopped successfully String message = "Volumes " + failedVolumeNames + " could not be stopped! " + CoreConstants.NEWLINE + "Error: [" + errorMessage + "]"; - errorMessage = performForceStopVolume(monitor, actionDesc, message); - + errorMessage = performForceStopVolume(actionDesc, message, monitor); + if (errorMessage.isEmpty()) { + return; + } + showErrorDialog(actionDesc, errorMessage); } else { String info = "Volumes " + stoppedVolumes + " stopped successfully!"; if (!errorMessage.equals("")) { - String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames - + " failed to stop! [" + errorMessage + "]"; - errorMessage = performForceStopVolume(monitor, actionDesc, message); - } - if (errorMessage.equals("")) { - errorMessage = info; + if (failedVolumeNames.size() > 0) { + String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames + + " failed to stop! [" + errorMessage + "]"; + info += performForceStopVolume(actionDesc, message, monitor); + } else { // Stop volume success, but post stop volume fails, append the error message + info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + errorMessage; + } } + showInfoDialog(actionDesc, info); } - showInfoDialog(actionDesc, errorMessage); } - - private String performForceStopVolume(IProgressMonitor monitor, String actionDesc, String message) { + private String performForceStopVolume(String actionDesc, String message, IProgressMonitor monitor) { boolean forceStop = showConfirmDialog(actionDesc, message + CoreConstants.NEWLINE + "Do you want to stop forcefully?"); if (!forceStop) { return ""; } - return performStopVolume(monitor, failedVolumes, true); + return performStopVolume(failedVolumes, true, monitor); } - private String performStopVolume(IProgressMonitor monitor, List volumesNeedsToStop, Boolean force) { + private String performStopVolume(List volumes, Boolean force, IProgressMonitor monitor) { VolumesClient vc = new VolumesClient(); Volume newVolume = new Volume(); stoppedVolumes.clear(); failedVolumeNames.clear(); failedVolumes.clear(); String errorMessage = ""; - List volumeStopAlert = new ArrayList(); - monitor.beginTask("Stopping Selected Volumes...", volumesNeedsToStop.size()); - for (Volume volume : volumesNeedsToStop.toArray(new Volume[0])) { + monitor.beginTask("Stopping Selected Volumes...", volumes.size()); + // Stopping of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. + for (Volume volume : volumes.toArray(new Volume[0])) { if(monitor.isCanceled()) { break; } @@ -138,17 +143,20 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { vc.stopVolume(volume.getName(), force); // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); stoppedVolumes.add(volume.getName()); - volumeStopAlert.add(new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), - Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() - + "]")); } catch (Exception e) { - failedVolumeNames.add(volume.getName()); - failedVolumes.add(volume); // If any post volume stop activity failed, update the volume status if (vc.getVolume(volume.getName()).getStatus() == VOLUME_STATUS.OFFLINE) { + // stop volume succeed, so add it to stoppedVolumes + stoppedVolumes.add(volume.getName()); modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); + errorMessage += "Volume [" + volume.getName() + "] stopped, but following error occured: [" + + e.getMessage() + "]"; + } else { + failedVolumeNames.add(volume.getName()); + failedVolumes.add(volume); + errorMessage += "Error [" + volume.getName() + "] : " + e.getMessage() + CoreConstants.NEWLINE; } - errorMessage += e.getMessage() + CoreConstants.NEWLINE; + } // Update the model by fetching latest volume info (NOT JUST STATUS) @@ -161,13 +169,6 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { monitor.worked(1); } monitor.done(); - - // Add the offline volume alert in AlertsManager - if (volumeStopAlert.size() > 0) { - AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); - alertManager.addAlerts(volumeStopAlert); - modelManager.alertsGenerated(); - } return errorMessage; } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java index ad2f6331..5bedf4f6 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java @@ -197,7 +197,8 @@ public class GlusterServersSummaryView extends ViewPart { List alerts = GlusterDataModelManager.getInstance().getModel().getCluster().getAlerts(); for (Alert alert : alerts) { - if (alert.getType() != ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT) { + if (alert.getType() != ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT + && alert.getType() != ALERT_TYPES.OFFLINE_VOLUME_ALERT) { addAlertLabel(alertsSection, alert); } } @@ -209,9 +210,6 @@ public class GlusterServersSummaryView extends ViewPart { CLabel lblAlert = new CLabel(section, SWT.FLAT); Image alertImage = null; switch (alert.getType()) { - case OFFLINE_VOLUME_BRICKS_ALERT: - alertImage = guiHelper.getImage(IImageKeys.BRICK_OFFLINE_22x22); - break; case DISK_USAGE_ALERT: alertImage = guiHelper.getImage(IImageKeys.LOW_DISK_SPACE_22x22); break; diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java index 944956f7..9e65471c 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java @@ -105,6 +105,11 @@ public class VolumesSummaryView extends ViewPart { updateSummarySection(); } + private void updateAlertSection() { + guiHelper.clearSection(alertsSection); + populateAlertSection(); + } + private void updateSummarySection() { guiHelper.clearSection(summarySection); populateSummarySection(); @@ -120,8 +125,15 @@ public class VolumesSummaryView extends ViewPart { } @Override - public void alertsRemoved() { - super.alertsRemoved(); + public void alertsRemoved(Volume volume, Event event) { + super.alertsRemoved(volume, event); + guiHelper.clearSection(alertsSection); + populateAlertSection(); + } + + @Override + public void alertsCreated(Volume volume, Event event) { + super.alertsCreated(volume, event); guiHelper.clearSection(alertsSection); populateAlertSection(); } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java index e0bb9c63..7e32fde7 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java @@ -51,5 +51,7 @@ public interface ClusterListener { public void aggregatedStatsChanged(); - public void alertsRemoved(); + public void alertsRemoved(Volume volume, Event event); + + public void alertsCreated(Volume volume, Event event); } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java index 50a5d2ac..4745d557 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java @@ -107,7 +107,12 @@ public class DefaultClusterListener implements ClusterListener { } @Override - public void alertsRemoved() { + public void alertsRemoved(Volume volume, Event event) { + modelChanged(); + } + + @Override + public void alertsCreated(Volume volume, Event event) { modelChanged(); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java index 4ff52189..fe7b8495 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java @@ -24,6 +24,8 @@ public class Event { BRICKS_REMOVED, BRICKS_CHANGED, VOLUME_STATUS_CHANGED, + ALERT_CREATED, + ALERT_REMOVED, VOLUME_OPTIONS_RESET, VOLUME_OPTION_SET, VOLUME_CHANGED, -- cgit From 949053f0c0b14576bd291769f4f2ddd06772cdc6 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 2 Nov 2011 12:40:12 +0530 Subject: Story #70: "Force" option in volume stop --- .../console/GlusterDataModelManager.java | 48 +++++++-- .../console/actions/DeleteVolumeAction.java | 111 +++++++++++++-------- .../console/actions/StartVolumeAction.java | 14 +-- .../console/actions/StopVolumeAction.java | 68 +++++++------ .../console/views/GlusterServersSummaryView.java | 7 +- .../console/views/VolumesSummaryView.java | 18 +++- .../management/core/model/ClusterListener.java | 4 +- .../core/model/DefaultClusterListener.java | 7 +- .../storage/management/core/model/Event.java | 2 + 9 files changed, 182 insertions(+), 97 deletions(-) diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java index 5fff61b9..a6daee79 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/GlusterDataModelManager.java @@ -408,6 +408,11 @@ public class GlusterDataModelManager { public void volumeChanged(Volume oldVolume, Volume newVolume) { oldVolume.copyFrom(newVolume); + + if (oldVolume.getStatus() != newVolume.getStatus()) { + updateVolumeStatusAlert(newVolume, newVolume.getStatus()); + } + for (ClusterListener listener : listeners) { listener.volumeChanged(oldVolume, new Event(EVENT_TYPE.VOLUME_CHANGED, newVolume)); } @@ -746,6 +751,7 @@ public class GlusterDataModelManager { public void updateVolumeStatus(Volume volume, VOLUME_STATUS newStatus) { volume.setStatus(newStatus); + updateVolumeStatusAlert(volume, newStatus); if(newStatus == VOLUME_STATUS.OFFLINE) { // mark as bricks also as offline @@ -762,6 +768,42 @@ public class GlusterDataModelManager { listener.volumeChanged(volume, new Event(EVENT_TYPE.BRICKS_CHANGED, volume.getBricks())); } } + + private void updateVolumeStatusAlert(Volume volume, VOLUME_STATUS newStatus) { + Alert alert = null; + if (newStatus == VOLUME_STATUS.OFFLINE) { + alert = createOfflineVolumeAlert(volume); + for (ClusterListener listener : listeners) { + listener.alertCreated(alert); + } + } else { + alert = removeOfflineVolumeAlert(volume); + for (ClusterListener listener : listeners) { + listener.alertRemoved(alert); + } + } + } + + private Alert createOfflineVolumeAlert(Volume volume) { + Alert alert = new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), + Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() + "]"); + getModel().getCluster().addAlert(alert); + return alert; + } + + private Alert removeOfflineVolumeAlert(Volume volume) { + List clusterAlerts = getModel().getCluster().getAlerts(); + Alert removedAlert = null; + for (Alert alert : clusterAlerts) { + if (alert.getType().equals(ALERT_TYPES.OFFLINE_VOLUME_ALERT) + && alert.getReference().equals(volume.getName())) { + removedAlert = alert; + clusterAlerts.remove(alert); + break; + } + } + return removedAlert; + } public void resetVolumeOptions(Volume volume) { volume.getOptions().clear(); @@ -882,12 +924,6 @@ public class GlusterDataModelManager { } } - public void alertsRemoved() { - for (ClusterListener listener : listeners) { - listener.alertsRemoved(); - } - } - public List getVolumeOptionsInfo() { if(volumeOptionsInfo == null || volumeOptionsInfo.isEmpty()) { initializeVolumeOptionsInfo(getModel().getCluster()); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java index d764dcc0..6d784676 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java @@ -42,7 +42,6 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { private List onlineVolumeNames = new ArrayList(); private List deletedVolumeNames = new ArrayList(); private List failedVolumes = new ArrayList(); - private List failedVolumeNames = new ArrayList(); @Override protected void performAction(final IAction action, IProgressMonitor monitor) { @@ -72,85 +71,113 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { warningMessage = "Are you sure to delete the volumes " + selectedVolumeNames + " ?"; } - final Integer directoryDeleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance() + final Integer deleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance() .getImage(IImageKeys.VOLUME_16x16), warningMessage, MessageDialog.QUESTION, new String[] { "Cancel", "Delete volume and data", "Delete volume, keep data" }, -1).open(); - if (directoryDeleteOption <= 0) { // By Cancel button(0) or Escape key(-1) + if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) return; } - String errorMessage = performDeleteVolume(monitor,selectedVolumes, directoryDeleteOption, false); + String errorMessage = deleteVolumes(selectedVolumes, deleteOption, monitor); // Display the success or failure info if (deletedVolumeNames.size() == 0) { // No volume(s) deleted successfully - String message = "volumes " + failedVolumeNames + " could not be delete! " + CoreConstants.NEWLINE - + "Error: [" + errorMessage + "]"; - errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, directoryDeleteOption, - message); + if (!errorMessage.isEmpty()) { + showErrorDialog(actionDesc, "Volume(s) could not be deleted! " + CoreConstants.NEWLINE + errorMessage); + } } else { - String info = "Volumes " + deletedVolumeNames + " deleted successfully!"; - if (!errorMessage.equals("")) { - String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames - + " could not be deleted! [" + errorMessage + "]"; - errorMessage = performForceStopAndDeleteVolume(monitor, actionDesc, failedVolumes, - directoryDeleteOption, message); + String info = "Volume(s) " + deletedVolumeNames + " deleted successfully!"; + if (!errorMessage.isEmpty()) { + info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes + + " could not be deleted!" + errorMessage; } - if (errorMessage.equals("")) { - errorMessage = info; + if (selectedVolumes.size() == deletedVolumeNames.size()) { + showInfoDialog(actionDesc, info); + } else { + showWarningDialog(actionDesc, info); } } - showInfoDialog(actionDesc, errorMessage); } - private String performForceStopAndDeleteVolume(IProgressMonitor monitor, String actionDesc, List volumesToDelete, - Integer directoryDeleteOption, String message) { - boolean forceStop = showConfirmDialog(actionDesc, message + CoreConstants.NEWLINE + CoreConstants.NEWLINE - + "Do you want to stop forcefully and delete?"); - if (!forceStop) { - return ""; - } - return performDeleteVolume(monitor, volumesToDelete, directoryDeleteOption, true); - } - - private String performDeleteVolume(IProgressMonitor monitor, List volumeNeedsToDelete, - final Integer directoryDeleteOption, Boolean force) { + private String deleteVolumes(List volumes, final Integer deleteOption, IProgressMonitor monitor) { deletedVolumeNames.clear(); - failedVolumeNames.clear(); failedVolumes.clear(); VolumesClient vc = new VolumesClient(); - boolean confirmDeleteDir = (directoryDeleteOption == 1) ? true : false; + boolean confirmDeleteDir = (deleteOption == 1) ? true : false; String errorMessage = ""; - monitor.beginTask("Deleting Selected Volumes...", volumeNeedsToDelete.size()); - for (Volume volume : volumeNeedsToDelete.toArray(new Volume[0])) { - try { - monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); - if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume - vc.stopVolume(volume.getName(), force); + // To calculate the total work we need to sum volumes size + online volumes (because we treat stop and delete as + // separate steps) + List onlineVolumes = getOnlineVolumes(volumes); + monitor.beginTask("Deleting Selected Volumes...", volumes.size() + onlineVolumes.size()); + + // Deletion of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. + for (Volume volume : volumes.toArray(new Volume[0])) { + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // stop if online volume + monitor.setTaskName("Stopping volume [" + volume.getName() + "]"); + try { + vc.stopVolume(volume.getName(), false); + } catch (Exception e1) { + // try again with force = true + try { + vc.stopVolume(volume.getName(), true); + } catch(Exception e2) { + // force stop also failed. + // Mark as deletion failed, append error message. + errorMessage += CoreConstants.NEWLINE + "Stop[" + volume.getName() + "] : [" + e2.getMessage() + + "]"; + failedVolumes.add(volume); + + // since we are not going to perform delete on this volume, + // mark the deletion task as worked + monitor.worked(1); + + // continue to next volume without trying to delete this one + continue; + } + } finally { + // worked for "stop" operation + monitor.worked(1); } + } + + monitor.setTaskName("Deleting volume [" + volume.getName() + "]"); + try { vc.deleteVolume(volume.getName(), confirmDeleteDir); modelManager.deleteVolume(volume); deletedVolumeNames.add(volume.getName()); } catch (Exception e) { // Volume delete succeeded and post delete operation (directory cleanup, CIFS etc) may fail if (vc.volumeExists(volume.getName())) { - errorMessage += CoreConstants.NEWLINE + "[" + volume.getName() + "] : [" + e.getMessage() + "]"; - failedVolumeNames.add(volume.getName()); + errorMessage += CoreConstants.NEWLINE + "Delete [" + volume.getName() + "] : [" + e.getMessage() + "]"; failedVolumes.add(volume); } else { - errorMessage += CoreConstants.NEWLINE + "Volume deleted, but following error occured: [" - + e.getMessage() + "]"; + errorMessage += CoreConstants.NEWLINE + "Volume [" + volume.getName() + + "] deleted, but following error occured: [" + e.getMessage() + "]"; modelManager.deleteVolume(volume); deletedVolumeNames.add(volume.getName()); } + } finally { + monitor.worked(1); } - monitor.worked(1); } monitor.done(); return errorMessage; } + private List getOnlineVolumes(List volumes) { + List onlineVolumes = new ArrayList(); + for (Volume volume : volumes) { + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { + onlineVolumes.add(volume); + } + } + return onlineVolumes; + } + private void collectVolumeNames() { selectedVolumeNames.clear(); onlineVolumeNames.clear(); diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java index 09b01805..d7c6d2e3 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java @@ -77,6 +77,9 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { } monitor.beginTask("Starting Selected Volumes...", selectedVolumes.size()); + // Starting of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. for (Volume volume : selectedVolumes.toArray(new Volume[0])) { if(monitor.isCanceled()) { break; @@ -101,11 +104,6 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { try { newVolume = vc.getVolume(volume.getName()); modelManager.volumeChanged(volume, newVolume); - // Remove the offline volume alert from the AlertsManager - AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); - alertManager.removeAlert(Base64.encode( - (ALERT_TYPES.OFFLINE_VOLUME_ALERT + "-" + volume.getName()).getBytes()).toString()); - modelManager.alertsRemoved(); } catch (Exception e) { errorMessage += "Updating volume info failed on UI. [" + e.getMessage() + "]"; } @@ -123,7 +121,11 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes + " failed to start! [" + errorMessage + "]"; } - showInfoDialog(actionDesc, info); + if (selectedVolumes.size() == startedVolumes.size()) { + showInfoDialog(actionDesc, info); + } else { + showWarningDialog(actionDesc, info); + } } } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java index 21bf3432..3bd055f2 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java @@ -44,7 +44,6 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { private List selectedVolumeNames = new ArrayList(); private List onlineVolumeNames = new ArrayList(); private List stoppedVolumes = new ArrayList(); - private List failedVolumeNames = new ArrayList(); private List failedVolumes = new ArrayList(); @Override @@ -82,49 +81,57 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } } - String errorMessage = performStopVolume(monitor, selectedVolumes, false); + String errorMessage = stopVolume(selectedVolumes, false, monitor); // Display the success or failure info if (stoppedVolumes.size() == 0) { // No volume(s) stopped successfully - String message = "Volumes " + failedVolumeNames + " could not be stopped! " + CoreConstants.NEWLINE + String message = "Volume(s) " + failedVolumes + " could not be stopped! " + CoreConstants.NEWLINE + "Error: [" + errorMessage + "]"; - errorMessage = performForceStopVolume(monitor, actionDesc, message); - + errorMessage = forceStopVolume(actionDesc, message, monitor); + if (errorMessage.isEmpty()) { + return; + } + showErrorDialog(actionDesc, errorMessage); } else { - String info = "Volumes " + stoppedVolumes + " stopped successfully!"; + String info = "Volume(s) " + stoppedVolumes + " stopped successfully!"; if (!errorMessage.equals("")) { - String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumeNames - + " failed to stop! [" + errorMessage + "]"; - errorMessage = performForceStopVolume(monitor, actionDesc, message); + if (failedVolumes.size() > 0) { + String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volume(s) " + failedVolumes + + " failed to stop! [" + errorMessage + "]"; + info += forceStopVolume(actionDesc, message, monitor); + } else { // Stop volume success, but post stop volume fails, append the error message + info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + errorMessage; + } } - if (errorMessage.equals("")) { - errorMessage = info; + if (stoppedVolumes.size() == selectedVolumes.size()) { + showInfoDialog(actionDesc, info); + } else { + showWarningDialog(actionDesc, info); } } - showInfoDialog(actionDesc, errorMessage); } - - private String performForceStopVolume(IProgressMonitor monitor, String actionDesc, String message) { + private String forceStopVolume(String actionDesc, String message, IProgressMonitor monitor) { boolean forceStop = showConfirmDialog(actionDesc, message + CoreConstants.NEWLINE + "Do you want to stop forcefully?"); if (!forceStop) { return ""; } - return performStopVolume(monitor, failedVolumes, true); + return stopVolume(failedVolumes, true, monitor); } - private String performStopVolume(IProgressMonitor monitor, List volumesNeedsToStop, Boolean force) { + private String stopVolume(List volumes, Boolean force, IProgressMonitor monitor) { VolumesClient vc = new VolumesClient(); Volume newVolume = new Volume(); stoppedVolumes.clear(); - failedVolumeNames.clear(); failedVolumes.clear(); String errorMessage = ""; - List volumeStopAlert = new ArrayList(); - monitor.beginTask("Stopping Selected Volumes...", volumesNeedsToStop.size()); - for (Volume volume : volumesNeedsToStop.toArray(new Volume[0])) { + monitor.beginTask("Stopping Selected Volumes...", volumes.size()); + // Stopping of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, + // over which we are iterating, thus resulting in ConcurrentModificationException. To avoid this, we iterate + // over an array obtained from the list. + for (Volume volume : volumes.toArray(new Volume[0])) { if(monitor.isCanceled()) { break; } @@ -138,17 +145,19 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { vc.stopVolume(volume.getName(), force); // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); stoppedVolumes.add(volume.getName()); - volumeStopAlert.add(new Alert(ALERT_TYPES.OFFLINE_VOLUME_ALERT, volume.getName(), - Alert.ALERT_TYPE_STR[ALERT_TYPES.OFFLINE_VOLUME_ALERT.ordinal()] + " [" + volume.getName() - + "]")); } catch (Exception e) { - failedVolumeNames.add(volume.getName()); - failedVolumes.add(volume); // If any post volume stop activity failed, update the volume status if (vc.getVolume(volume.getName()).getStatus() == VOLUME_STATUS.OFFLINE) { + // stop volume succeed, so add it to stoppedVolumes + stoppedVolumes.add(volume.getName()); modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); + errorMessage += "Volume [" + volume.getName() + "] stopped, but following error occured: [" + + e.getMessage() + "]"; + } else { + failedVolumes.add(volume); + errorMessage += "[" + volume.getName() + "] : " + e.getMessage() + CoreConstants.NEWLINE; } - errorMessage += e.getMessage() + CoreConstants.NEWLINE; + } // Update the model by fetching latest volume info (NOT JUST STATUS) @@ -161,13 +170,6 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { monitor.worked(1); } monitor.done(); - - // Add the offline volume alert in AlertsManager - if (volumeStopAlert.size() > 0) { - AlertsManager alertManager = new AlertsManager(modelManager.getModel().getCluster()); - alertManager.addAlerts(volumeStopAlert); - modelManager.alertsGenerated(); - } return errorMessage; } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java index ad2f6331..afca5ad5 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/GlusterServersSummaryView.java @@ -197,7 +197,9 @@ public class GlusterServersSummaryView extends ViewPart { List alerts = GlusterDataModelManager.getInstance().getModel().getCluster().getAlerts(); for (Alert alert : alerts) { - if (alert.getType() != ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT) { + if (alert.getType() == ALERT_TYPES.DISK_USAGE_ALERT || alert.getType() != ALERT_TYPES.OFFLINE_SERVERS_ALERT + || alert.getType() == ALERT_TYPES.MEMORY_USAGE_ALERT + || alert.getType() == ALERT_TYPES.CPU_USAGE_ALERT) { addAlertLabel(alertsSection, alert); } } @@ -209,9 +211,6 @@ public class GlusterServersSummaryView extends ViewPart { CLabel lblAlert = new CLabel(section, SWT.FLAT); Image alertImage = null; switch (alert.getType()) { - case OFFLINE_VOLUME_BRICKS_ALERT: - alertImage = guiHelper.getImage(IImageKeys.BRICK_OFFLINE_22x22); - break; case DISK_USAGE_ALERT: alertImage = guiHelper.getImage(IImageKeys.LOW_DISK_SPACE_22x22); break; diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java index 944956f7..cd937215 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/VolumesSummaryView.java @@ -105,6 +105,11 @@ public class VolumesSummaryView extends ViewPart { updateSummarySection(); } + private void updateAlertSection() { + guiHelper.clearSection(alertsSection); + populateAlertSection(); + } + private void updateSummarySection() { guiHelper.clearSection(summarySection); populateSummarySection(); @@ -120,10 +125,15 @@ public class VolumesSummaryView extends ViewPart { } @Override - public void alertsRemoved() { - super.alertsRemoved(); - guiHelper.clearSection(alertsSection); - populateAlertSection(); + public void alertRemoved(Alert alert) { + super.alertRemoved(alert); + updateAlertSection(); + } + + @Override + public void alertCreated(Alert alert) { + super.alertCreated(alert); + updateAlertSection(); } @Override diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java index e0bb9c63..eb8c191e 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java @@ -51,5 +51,7 @@ public interface ClusterListener { public void aggregatedStatsChanged(); - public void alertsRemoved(); + public void alertRemoved(Alert alert); + + public void alertCreated(Alert alert); } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java index 50a5d2ac..eb98090f 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java @@ -107,7 +107,12 @@ public class DefaultClusterListener implements ClusterListener { } @Override - public void alertsRemoved() { + public void alertRemoved(Alert alert) { + modelChanged(); + } + + @Override + public void alertCreated(Alert alert) { modelChanged(); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java index 4ff52189..fe7b8495 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Event.java @@ -24,6 +24,8 @@ public class Event { BRICKS_REMOVED, BRICKS_CHANGED, VOLUME_STATUS_CHANGED, + ALERT_CREATED, + ALERT_REMOVED, VOLUME_OPTIONS_RESET, VOLUME_OPTION_SET, VOLUME_CHANGED, -- cgit From dcba1b60f258d98ab0ef654af1883cc5c295143c Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 10 Nov 2011 12:34:19 +0530 Subject: Force stop volume review comments incorporated --- .../console/actions/DeleteVolumeAction.java | 9 ++- .../console/actions/StartVolumeAction.java | 4 +- .../console/actions/StopVolumeAction.java | 66 +++++++++++++--------- 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java index b8376e4b..ba2ef5c7 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/DeleteVolumeAction.java @@ -82,15 +82,14 @@ public class DeleteVolumeAction extends AbstractMonitoredActionDelegate { // Display the success or failure info if (deletedVolumeNames.size() == 0) { // No volume(s) deleted successfully - if (!errorMessage.isEmpty()) { - showErrorDialog(actionDesc, "Volume(s) could not be deleted! " + CoreConstants.NEWLINE + errorMessage); - } + showErrorDialog(actionDesc, "Volume(s) could not be deleted! " + CoreConstants.NEWLINE + errorMessage); } else { String info = "Volume(s) " + deletedVolumeNames + " deleted successfully!"; - if (!errorMessage.isEmpty()) { + if (!failedVolumes.isEmpty()) { info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes - + " could not be deleted!" + errorMessage; + + " could not be deleted!" + CoreConstants.NEWLINE + errorMessage; } + if (selectedVolumes.size() == deletedVolumeNames.size()) { showInfoDialog(actionDesc, info); } else { diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java index d7c6d2e3..d82ab62f 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StartVolumeAction.java @@ -113,10 +113,10 @@ public class StartVolumeAction extends AbstractMonitoredActionDelegate { // Display the success or failure info if (startedVolumes.size() == 0) { // No volume(s) started successfully - showErrorDialog(actionDesc, "Following volumes " + failedVolumes + " could not be started!" + showErrorDialog(actionDesc, "Volume(s) " + failedVolumes + " could not be started!" + CoreConstants.NEWLINE + "Error: [" + errorMessage + "]"); } else { - String info = "Volumes " + startedVolumes + " started successfully!"; + String info = "Volume(s) " + startedVolumes + " started successfully!"; if (!errorMessage.equals("")) { info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volumes " + failedVolumes + " failed to start! [" + errorMessage + "]"; diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java index bbc0be47..d4ab0452 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/actions/StopVolumeAction.java @@ -42,15 +42,14 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { private List onlineVolumeNames = new ArrayList(); private List stoppedVolumes = new ArrayList(); private List failedVolumes = new ArrayList(); + private String errorMessage = null; @Override protected void performAction(final IAction action, IProgressMonitor monitor) { - final String actionDesc = action.getDescription(); - collectVolumeNames(); if (onlineVolumeNames.size() == 0) { - showWarningDialog(actionDesc, "Volumes " + selectedVolumeNames + " already stopped!"); + showWarningDialog(action.getDescription(), "Volumes " + selectedVolumeNames + " already stopped!"); return; // Volumes already stopped, Don't do anything. } @@ -78,51 +77,67 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { } } - String errorMessage = stopVolume(selectedVolumes, false, monitor); + stopVolumes(selectedVolumes, false, monitor); - // Display the success or failure info + // Check for errors, trying to force stop in case of errors + checkForErrors(action, monitor, true); + } + + private void checkForErrors(final IAction action, IProgressMonitor monitor, boolean tryForceStop) { + String message = null; if (stoppedVolumes.size() == 0) { // No volume(s) stopped successfully - String message = "Volume(s) " + failedVolumes + " could not be stopped! " + CoreConstants.NEWLINE + message = "Volume(s) " + failedVolumes + " could not be stopped! " + CoreConstants.NEWLINE + "Error: [" + errorMessage + "]"; - errorMessage = forceStopVolume(actionDesc, message, monitor); - if (errorMessage.isEmpty()) { + if(tryForceStop) { + forceStopVolumes(action.getDescription(), message + CoreConstants.NEWLINE + + "Do you want to stop forcefully?", monitor); + // check for errors without trying to force stop in case of errors + checkForErrors(action, monitor, false); + return; + } else { + showErrorDialog(action.getDescription(), message); return; } - showErrorDialog(actionDesc, errorMessage); } else { - String info = "Volume(s) " + stoppedVolumes + " stopped successfully!"; - if (!errorMessage.equals("")) { + message = "Volume(s) " + stoppedVolumes + " stopped successfully!"; + if (!errorMessage.isEmpty()) { if (failedVolumes.size() > 0) { - String message = info + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volume(s) " + failedVolumes - + " failed to stop! [" + errorMessage + "]"; - info += forceStopVolume(actionDesc, message, monitor); + message = message + CoreConstants.NEWLINE + CoreConstants.NEWLINE + "Volume(s) " + + failedVolumes + " could not be stopped! [" + errorMessage + "]"; + if(tryForceStop) { + forceStopVolumes(action.getDescription(), message + CoreConstants.NEWLINE + + "Do you want to stop forcefully?", monitor); + // check for errors without trying to force stop in case of errors + checkForErrors(action, monitor, false); + return; + } } else { // Stop volume success, but post stop volume fails, append the error message - info += CoreConstants.NEWLINE + CoreConstants.NEWLINE + errorMessage; + message += CoreConstants.NEWLINE + CoreConstants.NEWLINE + errorMessage; } } - if (stoppedVolumes.size() == selectedVolumes.size()) { - showInfoDialog(actionDesc, info); + + if (errorMessage.isEmpty()) { + showInfoDialog(action.getDescription(), message); } else { - showWarningDialog(actionDesc, info); + showWarningDialog(action.getDescription(), message); } } } - private String forceStopVolume(String actionDesc, String message, IProgressMonitor monitor) { - boolean forceStop = showConfirmDialog(actionDesc, - message + CoreConstants.NEWLINE + "Do you want to stop forcefully?"); + private void forceStopVolumes(String actionDesc, String message, IProgressMonitor monitor) { + boolean forceStop = showConfirmDialog(actionDesc, message); if (!forceStop) { - return ""; + return; } - return stopVolume(failedVolumes, true, monitor); + stopVolumes(failedVolumes, true, monitor); } - private String stopVolume(List volumes, Boolean force, IProgressMonitor monitor) { + private void stopVolumes(List volumes, Boolean force, IProgressMonitor monitor) { VolumesClient vc = new VolumesClient(); Volume newVolume = new Volume(); stoppedVolumes.clear(); failedVolumes.clear(); - String errorMessage = ""; + errorMessage = ""; monitor.beginTask("Stopping Selected Volumes...", volumes.size()); // Stopping of a volume results in changes to the model, and ultimately updates the "selectedVolumes" list, @@ -167,7 +182,6 @@ public class StopVolumeAction extends AbstractMonitoredActionDelegate { monitor.worked(1); } monitor.done(); - return errorMessage; } private void collectVolumeNames() { -- cgit