summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java49
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java14
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java1
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java27
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java6
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java19
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java33
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java54
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java34
-rw-r--r--src/com.gluster.storage.management.gui/icons/close_task.pngbin0 -> 588 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/pause_task.pngbin0 -> 427 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/start_task.gifbin0 -> 470 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/stop_task.pngbin0 -> 411 bytes
-rw-r--r--src/com.gluster.storage.management.gui/plugin.xml118
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java5
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java47
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java53
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java75
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java54
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java54
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java11
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java39
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java90
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java116
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java100
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java2
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java14
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java121
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java39
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java118
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java17
37 files changed, 1035 insertions, 287 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java
index 695fae19..c02d73b5 100644
--- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java
+++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java
@@ -35,15 +35,13 @@ import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.Server;
import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
+import com.gluster.storage.management.core.model.TaskStatus;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE;
import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS;
import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE;
import com.gluster.storage.management.core.model.VolumeOptionInfo;
-import com.gluster.storage.management.core.response.GlusterServerListResponse;
-import com.gluster.storage.management.core.response.ServerListResponse;
-import com.gluster.storage.management.core.response.VolumeListResponse;
-import com.gluster.storage.management.core.response.VolumeOptionInfoListResponse;
public class GlusterDataModelManager {
private static GlusterDataModelManager instance = new GlusterDataModelManager();
@@ -92,7 +90,6 @@ public class GlusterDataModelManager {
initializeAutoDiscoveredServers(cluster);
// initializeDisks();
-
initializeTasks(cluster);
initializeAlerts(cluster);
initializeVolumeOptionsDefaults();
@@ -118,10 +115,40 @@ public class GlusterDataModelManager {
}
public void initializeTasks(Cluster cluster) {
- List<TaskInfo> taskInfoList = new TasksClient(cluster.getName()).getAllTasks();
+ // List<TaskInfo> taskInfoList = new TasksClient(cluster.getName()).getAllTasks();
+ List<TaskInfo> taskInfoList = getDummyTasks();
cluster.setTaskInfoList(taskInfoList);
}
+ private List<TaskInfo> getDummyTasks() {
+ List<TaskInfo> taskInfoList = new ArrayList<TaskInfo>();
+
+ // Task #1
+ TaskInfo taskInfo = new TaskInfo();
+ taskInfo.setType(TASK_TYPE.BRICK_MIGRATE);
+ taskInfo.setName("Migrate Brick-music");
+ taskInfo.setCanPause(true);
+ taskInfo.setCanStop(true);
+ taskInfo.setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, "")));
+
+ taskInfo.getStatus().setMessage("Migrating file xxxxx to yyyy");
+ taskInfo.setDescription("Migrate Brick on volume [music] from /export/adb/music to /export/sdc/music.");
+ taskInfoList.add(taskInfo);
+ // Task #2
+ taskInfo = new TaskInfo();
+ taskInfo.setType(TASK_TYPE.DISK_FORMAT);
+ taskInfo.setName("Format Disk-server1:sdc");
+ taskInfo.setCanPause(false);
+ taskInfo.setCanStop(false);
+ taskInfo.setStatus( new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "")));
+ taskInfo.getStatus().setMessage("Format completes 80% ...");
+ taskInfo.setDescription("Formatting disk server1:sdc.");
+ taskInfoList.add(taskInfo);
+
+
+ return taskInfoList;
+ }
+
public void initializeAlerts(Cluster cluster) {
cluster.setAlerts(new AlertsClient(cluster.getName()).getAllAlerts());
}
@@ -334,6 +361,15 @@ public class GlusterDataModelManager {
}
}
+ public void updateTaskStatus(TaskInfo taskInfo, Status newStatus) {
+ taskInfo.getStatus().setCode(newStatus.getCode());
+ taskInfo.getStatus().setMessage(newStatus.getMessage());
+ for (ClusterListener listener : listeners) {
+ listener.taskUpdated(taskInfo);
+ }
+ }
+
+
public List<VolumeOptionInfo> getVolumeOptionsDefaults() {
return volumeOptionsDefaults;
}
@@ -414,4 +450,5 @@ public class GlusterDataModelManager {
}
return volumeNames;
}
+
}
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java
index b5ee1d1c..8e608983 100644
--- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java
+++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java
@@ -26,15 +26,17 @@ import javax.ws.rs.core.MultivaluedMap;
import com.gluster.storage.management.core.constants.RESTConstants;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
-import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.TaskInfo;
import com.gluster.storage.management.core.response.TaskListResponse;
-import com.gluster.storage.management.core.response.TaskResponse;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.util.MultivaluedMapImpl;
public class TasksClient extends AbstractClient {
+ public TasksClient() {
+ super();
+ }
+
public TasksClient(String clusterName) {
super(clusterName);
}
@@ -48,14 +50,8 @@ public class TasksClient extends AbstractClient {
return RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + RESTConstants.RESOURCE_TASKS + "/";
}
- @SuppressWarnings("unchecked")
public List<TaskInfo> getAllTasks() { // TaskListResponse get only the list of taskInfo not list of Tasks
- TaskListResponse response = (TaskListResponse) fetchResource(TaskListResponse.class);
- if (response.getStatus().isSuccess()) {
- return (List<TaskInfo>) response.getData();
- } else {
- throw new GlusterRuntimeException("Exception on fetching tasks [" + response.getStatus().getMessage() + "]");
- }
+ return ((TaskListResponse) fetchResource(TaskListResponse.class)).getTaskList();
}
// see startMigration @ VolumesClient, etc
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java
index deabbde7..c37869dc 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java
@@ -45,6 +45,7 @@ public class RESTConstants {
public static final String TASK_PAUSE = "pause";
public static final String TASK_RESUME = "resume";
public static final String TASK_STOP = "stop";
+ public static final String TASK_COMMIT = "commit";
public static final String TASK_STATUS = "status";
public static final String TASK_DELETE = "delete";
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java
new file mode 100644
index 00000000..ca5e01f8
--- /dev/null
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.core.exceptions;
+
+public class GlusterValidationException extends GlusterRuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public GlusterValidationException(String message) {
+ super(message);
+ }
+}
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 f96116ed..71de5e23 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
@@ -42,4 +42,10 @@ public interface ClusterListener {
public void volumeCreated(Volume volume);
public void volumeDeleted(Volume volume);
+
+ public void taskAdded(TaskInfo taskInfo);
+
+ public void taskRemoved(TaskInfo taskInfo);
+
+ public void taskUpdated(TaskInfo taskInfo);
}
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 e226d51b..d3b0e42e 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
@@ -74,6 +74,24 @@ public class DefaultClusterListener implements ClusterListener {
clusterChanged();
}
+
+ @Override
+ public void taskAdded(TaskInfo taskInfo) {
+ clusterChanged();
+ }
+
+
+ @Override
+ public void taskRemoved(TaskInfo taskInfo) {
+ clusterChanged();
+ }
+
+
+ @Override
+ public void taskUpdated(TaskInfo taskInfo) {
+ clusterChanged();
+ }
+
/**
* This method is called by every other event method. Thus, if a view/listener is interested in performing the same
* task on any change happening in the cluster data model, it can simply override this method and implement the
@@ -82,4 +100,5 @@ public class DefaultClusterListener implements ClusterListener {
public void clusterChanged() {
}
+
}
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java
index 45eb07ba..b7823c4b 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java
@@ -20,22 +20,23 @@
*/
package com.gluster.storage.management.core.model;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
+
public abstract class Task {
- public enum TASK_TYPE {
- DISK_FORMAT, BRICK_MIGRATE, VOLUME_REBALANCE
- }
-
public String[] TASK_TYPE_STR = { "Format Disk", "Migrate Brick", "Volume Rebalance" };
- private TaskInfo taskInfo;
+ protected TaskInfo taskInfo;
protected String serverName;
- public Task(TASK_TYPE type, String reference) {
+ public Task(TASK_TYPE type, String reference, String desc, boolean canPause, boolean canStop, boolean canCommit) {
taskInfo = new TaskInfo();
taskInfo.setType(type);
- taskInfo.setId(getTypeStr() + "-" + reference); // construct id
taskInfo.setReference(reference);
+ taskInfo.setDescription(desc);
+
+ // IMPORTANT. This call must be in the end since getId may need to use the values set in above statements
+ taskInfo.setName(getId());
}
public Task(TaskInfo taskInfo) {
@@ -68,16 +69,18 @@ public abstract class Task {
public abstract String getId();
- public abstract TaskInfo start();
+ public abstract void start();
- public abstract TaskInfo resume();
+ public abstract void resume();
- public abstract TaskInfo stop();
+ public abstract void stop();
- public abstract TaskInfo pause();
-
- public abstract TaskInfo status();
-
- public abstract void setTaskDescription();
+ public abstract void pause();
+ public abstract void commit();
+
+ /**
+ * This method should check current status of the task and update it's taskInfo accordingly
+ */
+ public abstract TaskStatus checkStatus();
}
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java
index d4549146..1ce2fa04 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java
@@ -20,24 +20,31 @@
*/
package com.gluster.storage.management.core.model;
-import com.gluster.storage.management.core.model.Task.TASK_TYPE;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.gluster.storage.management.core.utils.StringUtil;
+
+@XmlRootElement
+public class TaskInfo extends Entity {
+ public enum TASK_TYPE {
+ DISK_FORMAT, BRICK_MIGRATE, VOLUME_REBALANCE
+ }
-public class TaskInfo extends Status {
- private String id;
private TASK_TYPE type;
private String reference;
private String description;
- private Boolean canPause;
- private Boolean canStop;
+ private Boolean pauseSupported;
+ private Boolean stopSupported;
+ private Boolean commitSupported;
private TaskStatus status;
-
- public String getId() {
- return id;
+ public TaskInfo() {
}
- public void setId(String id) {
- this.id = id;
+ @XmlElement(name="id")
+ public String getName() {
+ return super.getName();
}
public TASK_TYPE getType() {
@@ -72,20 +79,35 @@ public class TaskInfo extends Status {
this.status = status;
}
- public Boolean getCanPause() {
- return canPause;
+ public Boolean canPause() {
+ return pauseSupported;
}
public void setCanPause(Boolean canPause) {
- this.canPause = canPause;
+ this.pauseSupported = canPause;
}
- public Boolean getCanStop() {
- return canStop;
+ public Boolean canStop() {
+ return stopSupported;
}
public void setCanStop(Boolean canStop) {
- this.canStop = canStop;
+ this.stopSupported = canStop;
+ }
+
+ public Boolean canCommit() {
+ return this.commitSupported;
+ }
+
+ public void setCanCommit(Boolean canCommit) {
+ this.commitSupported = canCommit;
}
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.core.model.Entity#filter(java.lang.String, boolean)
+ */
+ @Override
+ public boolean filter(String filterString, boolean caseSensitive) {
+ return StringUtil.filterString(getDescription() + getStatus().getMessage(), filterString, caseSensitive);
+ }
}
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java
index 2637b197..110f4e63 100644
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java
@@ -20,35 +20,31 @@
*/
package com.gluster.storage.management.core.response;
-import java.util.ArrayList;
import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
-import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.TaskInfo;
-@XmlRootElement
-public class TaskListResponse extends AbstractResponse {
- private List<TaskInfo> taskList = new ArrayList<TaskInfo>();
- private Status status;
-
- public Status getStatus() {
- return status;
- }
+@XmlRootElement(name = "response")
+public class TaskListResponse {
+ private List<TaskInfo> taskInfoList;
- public void setStatus(Status status) {
- this.status = status;
- }
+ public TaskListResponse() {
+ }
- public void setData(List<TaskInfo> taskList) {
- this.taskList.clear();
- this.taskList.addAll(taskList);
+ public TaskListResponse(List<TaskInfo> taskInfoList) {
+ this.taskInfoList = taskInfoList;
+ }
+
+ @XmlElement(name="TaskInfo", type=TaskInfo.class)
+ public List<TaskInfo> getTaskList() {
+ return taskInfoList;
}
- @Override
- public Object getData() {
- return this.taskList;
+ public void setTaskList(List<TaskInfo> taskInfoList) {
+ this.taskInfoList = taskInfoList;
}
}
diff --git a/src/com.gluster.storage.management.gui/icons/close_task.png b/src/com.gluster.storage.management.gui/icons/close_task.png
new file mode 100644
index 00000000..933272b4
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/close_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/pause_task.png b/src/com.gluster.storage.management.gui/icons/pause_task.png
new file mode 100644
index 00000000..af57b25d
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/pause_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/start_task.gif b/src/com.gluster.storage.management.gui/icons/start_task.gif
new file mode 100644
index 00000000..2dfaef50
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/start_task.gif
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/stop_task.png b/src/com.gluster.storage.management.gui/icons/stop_task.png
new file mode 100644
index 00000000..7c6af7f0
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/stop_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml
index af065b7d..c5c25c33 100644
--- a/src/com.gluster.storage.management.gui/plugin.xml
+++ b/src/com.gluster.storage.management.gui/plugin.xml
@@ -30,14 +30,6 @@
restorable="true">
</view>
<view
- category="org.eclipse.ui"
- class="org.eclipse.ui.ExtensionFactory:progressView"
- icon="icons/progress-bar.png"
- id="org.eclipse.ui.views.ProgressView"
- name="Tasks in Progress"
- restorable="true">
- </view>
- <view
allowMultiple="false"
category="com.gluster.storage.management.gui.category"
class="com.gluster.storage.management.gui.views.DiscoveredServersView"
@@ -175,6 +167,15 @@
name="Server Logs"
restorable="true">
</view>
+ <view
+ allowMultiple="false"
+ category="com.gluster.storage.management.gui.category"
+ class="com.gluster.storage.management.gui.views.TasksView"
+ icon="icons/progress-bar.png"
+ id="com.gluster.storage.management.gui.views.TasksView"
+ name="Tasks"
+ restorable="true">
+ </view>
</extension>
<extension
point="org.eclipse.ui.commands">
@@ -249,10 +250,35 @@
name="Remove Brick">
</command>
<command
+ categoryId="com.gluster.storage.management.gui.category"
description="Add Brick"
id="com.gluster.storage.management.gui.commands.AddDisk"
name="Add Brick">
</command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Pause Task"
+ id="com.gluster.storage.management.gui.commands.Pause"
+ name="Pause">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Resume Task"
+ id="com.gluster.storage.management.gui.commands.Resume"
+ name="Resume">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Stop Task"
+ id="com.gluster.storage.management.gui.commands.Stop"
+ name="Stop">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Delete Task"
+ id="com.gluster.storage.management.gui.commands.Delete"
+ name="Delete">
+ </command>
</extension>
<extension
point="org.eclipse.ui.bindings">
@@ -643,6 +669,70 @@
visible="false">
<action
allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.ClearTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Clear"
+ icon="icons/close_task.png"
+ id="com.gluster.storage.management.gui.actions.Clear"
+ label="&amp;Clear Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To clear selected task from task list">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.StopTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Stop"
+ icon="icons/stop_task.png"
+ id="com.gluster.storage.management.gui.actions.Stop"
+ label="&amp;Stop Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Stop the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.ResumeTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Pause"
+ icon="icons/start_task.gif"
+ id="com.gluster.storage.management.gui.actions.Resume"
+ label="&amp;Resume Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Resume the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.PauseTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Pause"
+ icon="icons/pause_task.png"
+ id="com.gluster.storage.management.gui.actions.Pause"
+ label="&amp;Pause Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Pause the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.CreateVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.CreateVolume"
icon="icons/volume-create.png"
@@ -1006,6 +1096,18 @@
standalone="false"
visible="false">
</view>
+ <view
+ closeable="false"
+ id="com.gluster.storage.management.gui.views.TasksView"
+ minimized="false"
+ moveable="false"
+ ratio="0.30f"
+ relationship="stack"
+ relative="com.gluster.storage.management.gui.views.ClusterSummaryView"
+ showTitle="true"
+ standalone="false"
+ visible="false">
+ </view>
</perspectiveExtension>
</extension>
<extension
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java
index 65124bf9..c2223729 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java
@@ -55,6 +55,11 @@ public interface IImageKeys {
public static final String LOW_DISK_SPACE = "icons/disk.png";
public static final String DISK_OFFLINE = "icons/status-offline.png";
+ public static final String PAUSE_TASK = "icons/pause_task.gif";
+ public static final String RESUME_TASK = "icons/resume_task.gif";
+ public static final String STOP_TASK = "icons/stop_task.gif";
+ public static final String CLEAR_TASK = "icons/close_task.gif";
+
public static final String OVERLAY_OFFLINE = "icons/status-offline-small.png";
public static final String OVERLAY_ONLINE = "icons/status-online-small.png";
public static final String OVERLAY_STAR = "icons/star-small.png";
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java
new file mode 100644
index 00000000..177b069e
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java
@@ -0,0 +1,47 @@
+/**
+ * TasksTableLabelProvider.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui;
+
+import org.eclipse.swt.graphics.Image;
+
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.utils.GUIHelper;
+import com.gluster.storage.management.gui.views.pages.TasksPage.TASK_TABLE_COLUMN_INDICES;
+
+
+public class TasksTableLabelProvider extends TableLabelProviderAdapter {
+ private GUIHelper guiHelper = GUIHelper.getInstance();
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ if (!(element instanceof TaskInfo)) {
+ return null;
+ }
+
+ TaskInfo taskInfo = (TaskInfo) element;
+ return (columnIndex == TASK_TABLE_COLUMN_INDICES.TASK.ordinal()) ? taskInfo.getDescription() : taskInfo.getStatus().getMessage();
+ }
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java
new file mode 100644
index 00000000..75db898d
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java
@@ -0,0 +1,53 @@
+package com.gluster.storage.management.gui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.client.TasksClient;
+import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.model.TaskInfo;
+
+public class ClearTaskAction extends AbstractActionDelegate {
+ private TaskInfo taskInfo;
+ private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
+
+ @Override
+ protected void performAction(final IAction action) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ final String actionDesc = action.getDescription();
+
+ try {
+ new TasksClient().resumeTask(taskInfo.getName());
+ // TODO Update taskInfo in the model
+ // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE);
+ modelManager.updateTaskStatus(taskInfo, new Status(Status.STATUS_CODE_PART_SUCCESS, taskInfo.getName() + " is cleared from task list"));
+ } catch (Exception e) {
+ showErrorDialog(actionDesc,
+ "Task [" + taskInfo.getName() + "] could not be cleared! Error: [" + e.getMessage() + "]");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ super.selectionChanged(action, selection);
+ action.setEnabled(false);
+ if (selectedEntity instanceof TaskInfo) {
+ taskInfo = (TaskInfo) selectedEntity;
+ action.setEnabled(taskInfo.getStatus().getCode() == Status.STATUS_CODE_SUCCESS
+ || taskInfo.getStatus().getCode() == Status.STATUS_CODE_FAILURE);
+ }
+ }
+
+ @Override
+ public void dispose() {
+
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java
new file mode 100644
index 00000000..2bb7261e
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java
@@ -0,0 +1,75 @@
+/**
+ * PauseTaskAction.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.client.TasksClient;
+import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.model.TaskInfo;
+
+
+public class PauseTaskAction extends AbstractActionDelegate {
+ private TaskInfo taskInfo;
+ private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
+
+ @Override
+ protected void performAction(final IAction action) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ final String actionDesc = action.getDescription();
+
+ try {
+ new TasksClient().pauseTask(taskInfo.getName());
+ //TODO Update taskInfo in the model
+ // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE);
+ modelManager.updateTaskStatus(taskInfo, new Status( Status.STATUS_CODE_PAUSE, "Paused"));
+ } catch (Exception e) {
+ showErrorDialog(actionDesc,
+ "Task [" + taskInfo.getName() + "] could not be Paused! Error: [" + e.getMessage() + "]");
+ }
+ }
+ });
+ }
+
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ super.selectionChanged(action, selection);
+ action.setEnabled(false);
+ if (selectedEntity instanceof TaskInfo) {
+ taskInfo = (TaskInfo) selectedEntity;
+ action.setEnabled(taskInfo.canPause() && taskInfo.getStatus().getCode() == Status.STATUS_CODE_RUNNING);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java
new file mode 100644
index 00000000..07894c80
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java
@@ -0,0 +1,54 @@
+package com.gluster.storage.management.gui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.client.TasksClient;
+import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.model.TaskInfo;
+
+public class ResumeTaskAction extends AbstractActionDelegate {
+ private TaskInfo taskInfo;
+ private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
+
+ @Override
+ protected void performAction(final IAction action) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ final String actionDesc = action.getDescription();
+
+ try {
+ new TasksClient().resumeTask(taskInfo.getName());
+ // TODO Update taskInfo in the model
+ // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE);
+ modelManager.updateTaskStatus(taskInfo, new Status(Status.STATUS_CODE_PAUSE, taskInfo.getName() + " is Resumed"));
+ } catch (Exception e) {
+ showErrorDialog(actionDesc,
+ "Task [" + taskInfo.getName() + "] could not be Resumed! Error: [" + e.getMessage() + "]");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ super.selectionChanged(action, selection);
+ action.setEnabled(false);
+ if (selectedEntity instanceof TaskInfo) {
+ taskInfo = (TaskInfo) selectedEntity;
+ action.setEnabled(taskInfo.getStatus().getCode() == Status.STATUS_CODE_PAUSE);
+ }
+ }
+
+ @Override
+ public void dispose() {
+
+
+ }
+
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java
new file mode 100644
index 00000000..144e94be
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java
@@ -0,0 +1,54 @@
+package com.gluster.storage.management.gui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.client.TasksClient;
+import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.model.TaskInfo;
+
+public class StopTaskAction extends AbstractActionDelegate {
+ private TaskInfo taskInfo;
+ private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance();
+
+ @Override
+ protected void performAction(final IAction action) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ final String actionDesc = action.getDescription();
+
+ try {
+ new TasksClient().resumeTask(taskInfo.getName());
+ // TODO Update taskInfo in the model
+ // modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE);
+ modelManager.updateTaskStatus(taskInfo, new Status(Status.STATUS_CODE_PART_SUCCESS, taskInfo.getName() + " is Stopped"));
+ } catch (Exception e) {
+ showErrorDialog(actionDesc,
+ "Task [" + taskInfo.getName() + "] could not be Stopped! Error: [" + e.getMessage() + "]");
+ }
+ }
+ });
+ }
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ super.selectionChanged(action, selection);
+ action.setEnabled(false);
+ if (selectedEntity instanceof TaskInfo) {
+ taskInfo = (TaskInfo) selectedEntity;
+ action.setEnabled(taskInfo.canStop()
+ && (taskInfo.getStatus().getCode() == Status.STATUS_CODE_PAUSE
+ || taskInfo.getStatus().getCode() == Status.STATUS_CODE_RUNNING));
+ }
+ }
+
+ @Override
+ public void dispose() {
+
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
index ac29ecf0..31d762ec 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java
@@ -84,6 +84,7 @@ import com.gluster.storage.management.core.utils.JavaUtil;
import com.gluster.storage.management.gui.Application;
import com.gluster.storage.management.gui.IImageKeys;
import com.gluster.storage.management.gui.views.NavigationView;
+import com.gluster.storage.management.gui.views.TasksView;
public class GUIHelper {
private static final GUIHelper instance = new GUIHelper();
@@ -450,6 +451,16 @@ public class GUIHelper {
}
}
+ public void showTaskView() {
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+ .showView( TasksView.ID );
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ throw new GlusterRuntimeException("Could not open the task progress view!", e);
+ }
+ }
+
public void setStatusMessage(String message) {
Application.getApplication().getStatusLineManager().setMessage(message);
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
index b4b31a0a..ab1e55ab 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
@@ -29,6 +29,7 @@ import com.gluster.storage.management.core.model.Entity;
import com.gluster.storage.management.core.model.EntityGroup;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.Server;
+import com.gluster.storage.management.core.model.TaskInfo;
import com.gluster.storage.management.core.model.Volume;
/**
@@ -80,6 +81,7 @@ public class GlusterViewsManager implements ViewsManager {
private void showViewsForCluster(Cluster cluster) throws PartInitException {
page.showView(ClusterSummaryView.ID);
+ page.showView(TasksView.ID, null, IWorkbenchPage.VIEW_CREATE);
}
private void showViewsForVolume(Volume volume) throws PartInitException {
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java
new file mode 100644
index 00000000..fb772d46
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java
@@ -0,0 +1,39 @@
+package com.gluster.storage.management.gui.views;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.views.pages.TasksPage;
+
+public class TasksView extends ViewPart {
+
+ public static final String ID = TasksView.class.getName();
+ private TasksPage page;
+
+
+ public TasksView() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ page = new TasksPage(getSite(), parent, SWT.NONE, getAllTasks());
+ page.layout(); // IMP: lays out the form properly
+ }
+
+
+ private List<TaskInfo> getAllTasks() {
+ return GlusterDataModelManager.getInstance().getModel().getCluster().getTaskInfoList();
+ }
+
+ @Override
+ public void setFocus() {
+ page.setFocus();
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
index 311014a0..a43330c4 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
@@ -35,8 +35,8 @@ import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.core.model.Alert;
import com.gluster.storage.management.core.model.Cluster;
import com.gluster.storage.management.core.model.EntityGroup;
-import com.gluster.storage.management.core.model.Task.TASK_TYPE;
import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS;
import com.gluster.storage.management.gui.IImageKeys;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
index 32a2c2f6..221e82b1 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
@@ -57,7 +57,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage<Disk> im
protected abstract int getStatusColumnIndex();
public AbstractDisksPage(final Composite parent, int style, IWorkbenchSite site, List<Disk> disks) {
- super(site, parent, style, disks);
+ super(site, parent, style, true, true, disks);
this.disks = disks;
// creates hyperlinks for "unitialized" disks
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
index dfa06f85..a37773e1 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
@@ -26,6 +26,7 @@ import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -50,15 +51,20 @@ import com.gluster.storage.management.gui.utils.GUIHelper;
public abstract class AbstractTableViewerPage<T> extends Composite {
protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
- protected CheckboxTableViewer tableViewer;
+ protected TableViewer tableViewer;
+ private boolean useCheckboxes;
+ private boolean multiSelection;
protected GUIHelper guiHelper = GUIHelper.getInstance();
protected Composite parent;
private Hyperlink linkAll, linkNone;
- public AbstractTableViewerPage(IWorkbenchSite site, final Composite parent, int style, Object model) {
+ public AbstractTableViewerPage(IWorkbenchSite site, final Composite parent, int style, boolean useChechboxes, boolean multiSelection, Object model) {
super(parent, style);
this.parent = parent;
+
+ this.useCheckboxes = useChechboxes;
+ this.multiSelection = multiSelection;
toolkit.adapt(this);
toolkit.paintBordersFor(this);
@@ -69,7 +75,7 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
Text filterText = guiHelper.createFilterText(toolkit, this);
- setupServerTableViewer(site, filterText);
+ setupTableViewer(site, filterText);
tableViewer.setInput(model);
parent.layout(); // Important - this actually paints the table
@@ -78,27 +84,35 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
}
public void createCheckboxSelectionLinks() {
- // create the "select all/none" links
- toolkit.createLabel(this, "Select");
- linkAll = toolkit.createHyperlink(this, "all", SWT.NONE);
- linkAll.addHyperlinkListener(new HyperlinkAdapter() {
- @Override
- public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
- tableViewer.setAllChecked(true);
- tableViewer.setSelection(new StructuredSelection(getAllEntities()));
- }
- });
-
- toolkit.createLabel(this, " / ");
-
- linkNone = toolkit.createHyperlink(this, "none", SWT.NONE);
- linkNone.addHyperlinkListener(new HyperlinkAdapter() {
- @Override
- public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
- tableViewer.setAllChecked(false);
- tableViewer.setSelection(null);
- }
- });
+ if (useCheckboxes) {
+ // create the "select all/none" links
+ toolkit.createLabel(this, "Select");
+ linkAll = toolkit.createHyperlink(this, "all", SWT.NONE);
+ linkAll.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ ((CheckboxTableViewer) tableViewer).setAllChecked(true);
+ tableViewer.setSelection(new StructuredSelection(getAllEntities()));
+ }
+ });
+
+ toolkit.createLabel(this, " / ");
+
+ linkNone = toolkit.createHyperlink(this, "none", SWT.NONE);
+ linkNone.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ ((CheckboxTableViewer) tableViewer).setAllChecked(false);
+ tableViewer.setSelection(null);
+ }
+ });
+ } else {
+ // create dummy labels to maintain layout
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ }
}
private void createListeners(final Composite parent) {
@@ -145,7 +159,7 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
setLayout(layout);
}
- private void setupServerTable(Composite parent, Table table) {
+ protected void setupTable(Composite parent, Table table) {
table.setHeaderVisible(true);
table.setLinesVisible(false);
@@ -155,15 +169,19 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
setColumnProperties(table);
}
- private CheckboxTableViewer createServerTableViewer(Composite parent) {
- CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
+ private void createTableViewer(Composite parent) {
+ int style = SWT.FLAT | SWT.FULL_SELECTION;
+ style |= (multiSelection ? SWT.MULTI : SWT.SINGLE);
+
+ if(useCheckboxes) {
+ tableViewer = CheckboxTableViewer.newCheckList(parent, style);
+ } else {
+ tableViewer = new TableViewer(parent, style);
+ }
tableViewer.setLabelProvider(getLabelProvider());
tableViewer.setContentProvider(getContentProvider());
-
- setupServerTable(parent, tableViewer.getTable());
-
- return tableViewer;
+ setupTable(parent, tableViewer.getTable());
}
private Composite createTableViewerComposite() {
@@ -182,13 +200,15 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
return tableViewerComposite;
}
- private void setupServerTableViewer(IWorkbenchSite site, final Text filterText) {
+ private void setupTableViewer(IWorkbenchSite site, final Text filterText) {
Composite tableViewerComposite = createTableViewerComposite();
- tableViewer = createServerTableViewer(tableViewerComposite);
+ createTableViewer(tableViewerComposite);
site.setSelectionProvider(tableViewer);
- // make sure that table selection is driven by checkbox selection
- guiHelper.configureCheckboxTableViewer(tableViewer);
+ if(useCheckboxes) {
+ // make sure that table selection is driven by checkbox selection
+ guiHelper.configureCheckboxTableViewer((CheckboxTableViewer)tableViewer);
+ }
// Create a case insensitive filter for the table viewer using the filter text field
guiHelper.createFilter(tableViewer, filterText, false);
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
index b83914eb..9805daec 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
@@ -47,7 +47,7 @@ public class BricksPage extends AbstractTableViewerPage<Brick> {
"Total Space (GB)", "Status" };
public BricksPage(Composite parent, int style, IWorkbenchSite site, final List<Brick> bricks) {
- super(site, parent, style, bricks);
+ super(site, parent, style, true, true, bricks);
this.bricks = bricks;
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
index 87644622..be4df7ad 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
@@ -49,7 +49,7 @@ public class GlusterServersPage extends AbstractTableViewerPage<GlusterServer> {
"IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Free Space (GB)", "Total \n Space (GB)", "Status" }; // Removed "Preferred\nNetwork",
public GlusterServersPage(IWorkbenchSite site, final Composite parent, int style, final EntityGroup<GlusterServer> servers) {
- super(site, parent, style, servers);
+ super(site, parent, style, true, true, servers);
this.glusterServers = servers.getEntities();
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
index 48b8892c..f285dd9f 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
@@ -55,7 +55,7 @@ public class ServersPage extends AbstractTableViewerPage<Server> {
// "Total Disk\n Space (GB)", "Disk Space\nin Use (GB)"};
public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup<Server> serversGroup) {
- super(site, parent, SWT.NONE, serversGroup);
+ super(site, parent, SWT.NONE, true, true, serversGroup);
this.servers = serversGroup.getEntities();
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java
new file mode 100644
index 00000000..03c4f7ac
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java
@@ -0,0 +1,116 @@
+/**
+ * TasksPage.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui.views.pages;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.IWorkbenchSite;
+
+import com.gluster.storage.management.core.model.ClusterListener;
+import com.gluster.storage.management.core.model.DefaultClusterListener;
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.TasksTableLabelProvider;
+
+public class TasksPage extends AbstractTableViewerPage<TaskInfo> {
+ private List<TaskInfo> taskInfoList;
+
+ public enum TASK_TABLE_COLUMN_INDICES {
+ TASK, STATUS
+ };
+
+ private static final String[] TASK_TABLE_COLUMN_NAMES = new String[] { "Task", "Status"};
+
+
+ public TasksPage(IWorkbenchSite site, Composite parent, int style, Object taskInfo) {
+ super(site, parent, style, false, false, taskInfo);
+ this.taskInfoList = (List<TaskInfo>) taskInfo;
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#createClusterListener()
+ */
+ @Override
+ protected ClusterListener createClusterListener() {
+ return new DefaultClusterListener() {
+ @Override
+ public void taskAdded(TaskInfo taskInfo) {
+ refreshViewer();
+ }
+
+ @Override
+ public void taskRemoved(TaskInfo taskInfo) {
+ refreshViewer();
+ }
+
+ private void refreshViewer() {
+ tableViewer.refresh();
+ parent.update();
+ }
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getColumnNames()
+ */
+ @Override
+ protected String[] getColumnNames() {
+ return TASK_TABLE_COLUMN_NAMES;
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#setColumnProperties(org.eclipse.swt.widgets.Table)
+ */
+ @Override
+ protected void setColumnProperties(Table table) {
+ guiHelper.setColumnProperties(table, TASK_TABLE_COLUMN_INDICES.TASK.ordinal(), SWT.LEFT, 50);
+ guiHelper.setColumnProperties(table, TASK_TABLE_COLUMN_INDICES.STATUS.ordinal(), SWT.LEFT, 50);
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getLabelProvider()
+ */
+ @Override
+ protected IBaseLabelProvider getLabelProvider() {
+ return new TasksTableLabelProvider();
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getContentProvider()
+ */
+ @Override
+ protected IContentProvider getContentProvider() {
+ return new ArrayContentProvider();
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getAllEntities()
+ */
+ @Override
+ protected List<TaskInfo> getAllEntities() {
+ return taskInfoList;
+ }
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
index bd003f3b..956fc215 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
@@ -40,6 +40,7 @@ import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
@@ -91,9 +92,9 @@ public class VolumeOptionsPage extends Composite {
toolkit.paintBordersFor(this);
setupPageLayout();
+ addTopButton = createAddButton();
filterText = guiHelper.createFilterText(toolkit, this);
- addTopButton = createAddButton();
setupOptionsTableViewer(filterText);
addBottomButton = createAddButton();
@@ -114,48 +115,7 @@ public class VolumeOptionsPage extends Composite {
}
private Button createAddButton() {
- Button button = toolkit.createButton(this, "&Add", SWT.FLAT);
- button.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- // add an empty option to be filled up by user
- volume.setOption("", "");
-
- tableViewer.refresh();
- tableViewer.setSelection(new StructuredSelection(getEntry("")));
- keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry
-
- // disable the add button AND search filter textbox till user fills up the new option
- setAddButtonsEnabled(false);
- filterText.setEnabled(false);
- }
-
- private Entry<String, String> getEntry(String key) {
- for (Entry<String, String> entry : volume.getOptions().entrySet()) {
- if (entry.getKey().equals(key)) {
- return entry;
- }
- }
- return null;
- }
- });
-
- // Make sure that add button is enabled only when search filter textbox is empty
- filterText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- if (filterText.getText().length() > 0) {
- setAddButtonsEnabled(false);
- } else {
- if (defaultVolumeOptions.size() == volume.getOptions().size()) {
- setAddButtonsEnabled(false);
- } else {
- setAddButtonsEnabled(true);
- }
- }
- }
- });
- return button;
+ return toolkit.createButton(this, "&Add", SWT.FLAT);
}
private void registerListeners(final Composite parent) {
@@ -243,11 +203,55 @@ public class VolumeOptionsPage extends Composite {
return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size() - 1]);
}
};
+
+ SelectionListener addButtonSelectionListener = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // add an empty option to be filled up by user
+ volume.setOption("", "");
+
+ tableViewer.refresh();
+ tableViewer.setSelection(new StructuredSelection(getEntry("")));
+ keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry
+
+ // disable the add button AND search filter textbox till user fills up the new option
+ setAddButtonsEnabled(false);
+ filterText.setEnabled(false);
+ }
+
+ private Entry<String, String> getEntry(String key) {
+ for (Entry<String, String> entry : volume.getOptions().entrySet()) {
+ if (entry.getKey().equals(key)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+ };
+ addTopButton.addSelectionListener(addButtonSelectionListener);
+ addBottomButton.addSelectionListener(addButtonSelectionListener);
+
+ // Make sure that add button is enabled only when search filter textbox is empty
+ filterText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ if (filterText.getText().length() > 0) {
+ setAddButtonsEnabled(false);
+ } else {
+ if (defaultVolumeOptions.size() == volume.getOptions().size()) {
+ setAddButtonsEnabled(false);
+ } else {
+ setAddButtonsEnabled(true);
+ }
+ }
+ }
+ });
+
GlusterDataModelManager.getInstance().addClusterListener(clusterListener);
}
private void setupPageLayout() {
- final GridLayout layout = new GridLayout(1, false);
+ final GridLayout layout = new GridLayout(2, false);
layout.verticalSpacing = 10;
layout.marginTop = 10;
setLayout(layout);
@@ -256,7 +260,7 @@ public class VolumeOptionsPage extends Composite {
private void setupOptionsTable(Composite parent) {
Table table = tableViewer.getTable();
table.setHeaderVisible(true);
- table.setLinesVisible(false);
+ table.setLinesVisible(true);
TableColumnLayout tableColumnLayout = createTableColumnLayout();
parent.setLayout(tableColumnLayout);
@@ -337,7 +341,11 @@ public class VolumeOptionsPage extends Composite {
private Composite createTableViewerComposite() {
Composite tableViewerComposite = new Composite(this, SWT.NO);
tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
- tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.horizontalSpan = 2;
+ tableViewerComposite.setLayoutData(layoutData);
+
return tableViewerComposite;
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
index 3a8891d4..33eb6da7 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
@@ -48,7 +48,7 @@ public class VolumesPage extends AbstractTableViewerPage<Volume> {
"Number of\nBricks", "Transport Type", "Status" };
public VolumesPage(final Composite parent, IWorkbenchSite site, EntityGroup<Volume> volumes) {
- super(site, parent, SWT.NONE, volumes);
+ super(site, parent, SWT.NONE, true, true, volumes);
}
@Override
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java
index 1999762a..e824fee7 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java
@@ -457,21 +457,15 @@ public class GlusterServersResource extends AbstractServersResource {
return badRequestResponse("Disk name must not be empty!");
}
- TaskResponse taskResponse = new TaskResponse();
InitializeDiskTask initializeTask = new InitializeDiskTask(diskName, serverName);
- String taskId = null;
try {
- TaskInfo taskInfo = initializeTask.start();
- taskId = taskInfo.getId();
- if (taskInfo.isSuccess()) {
- taskResource.addTask(initializeTask);
- }
- taskResponse.setData(taskInfo);
- taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, ""));
+ initializeTask.start();
+ taskResource.addTask(initializeTask);
+ return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS,
+ initializeTask.getId());
} catch (ConnectionException e) {
return errorResponse(e.getMessage());
}
- return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId);
}
private void setGlusterUtil(GlusterUtil glusterUtil) {
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java
index 4bf1c0cf..d86cede2 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java
@@ -20,9 +20,9 @@
*/
package com.gluster.storage.management.server.resources;
+import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION;
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_TASK_ID;
-import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS;
@@ -40,26 +40,24 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import com.gluster.storage.management.core.constants.RESTConstants;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
-import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.exceptions.GlusterValidationException;
import com.gluster.storage.management.core.model.Task;
import com.gluster.storage.management.core.model.TaskInfo;
-import com.gluster.storage.management.core.response.TaskListResponse;
-import com.gluster.storage.management.core.response.TaskResponse;
import com.sun.jersey.spi.resource.Singleton;
@Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_TASKS)
@Singleton
-public class TasksResource {
+public class TasksResource extends AbstractResource {
private Map<String, Task> tasksMap = new HashMap<String, Task>();
public TasksResource() {
}
-
- public void addTask(Task task) { // task should be one of MuigrateDiskTask, FormatDiskTask, etc
+ public void addTask(Task task) {
tasksMap.put(task.getId(), task);
}
@@ -70,18 +68,11 @@ public class TasksResource {
public List<TaskInfo> getAllTasksInfo() {
List<TaskInfo> allTasksInfo = new ArrayList<TaskInfo>();
for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
- allTasksInfo.add(entry.getValue().getTaskInfo());
+ checkTaskStatus(entry.getKey());
+ allTasksInfo.add(entry.getValue().getTaskInfo()); // TaskInfo with latest status
}
return allTasksInfo;
}
-
- public List<Task> getAllTasks() {
- List<Task> allTasks = new ArrayList<Task>();
- for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
- allTasks.add(entry.getValue());
- }
- return allTasks;
- }
public Task getTask(String taskId) {
for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
@@ -91,63 +82,95 @@ public class TasksResource {
}
return null;
}
-
+
@GET
@Produces(MediaType.APPLICATION_XML)
- public TaskListResponse getTasks() {
- TaskListResponse taskListResponse = new TaskListResponse();
+ public Response getTasks() {
+ try {
+ return okResponse(getAllTasksInfo(), MediaType.APPLICATION_XML);
+ } catch (GlusterRuntimeException e) {
+ return errorResponse(e.getMessage());
+ }
+ }
+
+ @GET
+ @Path("/{" + PATH_PARAM_TASK_ID + "}")
+ @Produces(MediaType.APPLICATION_XML)
+ public Response getTaskStatus( @PathParam(PATH_PARAM_TASK_ID) String taskId) {
try {
- taskListResponse.setData(getAllTasksInfo());
- taskListResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, ""));
+ Task task = checkTaskStatus(taskId);
+ return okResponse(task.getTaskInfo(), MediaType.APPLICATION_XML);
} catch (GlusterRuntimeException e) {
- taskListResponse.setStatus(new Status(e));
+ return errorResponse(e.getMessage());
}
- return taskListResponse;
+ }
+
+ private Task checkTaskStatus(String taskId) {
+ Task task = getTask(taskId);
+ task.getTaskInfo().setStatus(task.checkStatus());
+ return task;
}
@PUT
@Path("/{" + PATH_PARAM_TASK_ID + "}")
@Produces(MediaType.APPLICATION_XML)
- public TaskResponse performTask(@PathParam(PATH_PARAM_TASK_ID) String taskId,
- @FormParam(FORM_PARAM_OPERATION) String taskOperation) {
+ public Response performTask(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
+ @PathParam(PATH_PARAM_TASK_ID) String taskId, @FormParam(FORM_PARAM_OPERATION) String taskOperation) {
Task task = getTask(taskId);
- TaskInfo taskInfo = null;
- TaskResponse taskResponse = new TaskResponse();
-
+
try {
if (taskOperation.equals(RESTConstants.TASK_RESUME)) {
- taskInfo = task.resume();
- }
- if (taskOperation.equals(RESTConstants.TASK_PAUSE)) {
- taskInfo = task.pause();
+ task.resume();
+ } else if (taskOperation.equals(RESTConstants.TASK_PAUSE)) {
+ task.pause();
+ } else if (taskOperation.equals(RESTConstants.TASK_STOP)) {
+ task.stop();
+ } else if(taskOperation.equals(RESTConstants.TASK_COMMIT)) {
+ task.commit();
}
- if (taskOperation.equals(RESTConstants.TASK_STOP)) {
- taskInfo = task.stop();
- }
- taskResponse.setData(taskInfo);
- taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, ""));
+ // updateTask(taskId, taskOperation);
+ return (Response) acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS,
+ taskId);
+ } catch(GlusterValidationException ve) {
+ return badRequestResponse(ve.getMessage());
} catch (GlusterRuntimeException e) {
- taskResponse.setStatus(new Status(e));
+ return errorResponse(e.getMessage());
}
- return taskResponse;
}
@DELETE
@Path("/{" + PATH_PARAM_TASK_ID + "}")
@Produces(MediaType.APPLICATION_XML)
- public TaskResponse deleteTask(@PathParam(PATH_PARAM_TASK_ID) String taskId,
+ public Response deleteTask(@PathParam(PATH_PARAM_TASK_ID) String taskId,
@QueryParam(FORM_PARAM_OPERATION) String taskOperation) {
- TaskResponse taskResponse = new TaskResponse();
Task task = getTask(taskId);
if (task == null) {
- taskResponse.setStatus( new Status(Status.STATUS_CODE_FAILURE, "No such task " + taskId + "is found "));
+ return notFoundResponse("Task [" + taskId + "] not found!");
}
- if (taskOperation.equals("delete")) {
- removeTask(task);
- taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, "Task [" + taskId
- + "] removed successfully"));
- }
- return null;
- }
+
+ if(taskOperation == null || taskOperation.isEmpty()) {
+ return badRequestResponse("Parameter [" + FORM_PARAM_OPERATION + "] is missing in request!");
+ }
+
+ if(!taskOperation.equals(RESTConstants.TASK_STOP) && !taskOperation.equals(RESTConstants.TASK_DELETE)) {
+ return badRequestResponse("Invalid value [" + taskOperation + "] for parameter [" + FORM_PARAM_OPERATION
+ + "]");
+ }
+
+ try {
+ if (taskOperation.equals(RESTConstants.TASK_STOP)) {
+ task.stop();
+ // On successfully stopping the task, we can delete (forget) it as it is no more useful
+ taskOperation = RESTConstants.TASK_DELETE;
+ }
+ if (taskOperation.equals(RESTConstants.TASK_DELETE)) {
+ removeTask(task);
+ }
+
+ return noContentResponse();
+ } catch (Exception e) {
+ return errorResponse(e.getMessage());
+ }
+ }
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java
index d29d859b..018cd301 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java
@@ -23,6 +23,7 @@ package com.gluster.storage.management.server.tasks;
import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.Task;
import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
import com.gluster.storage.management.core.model.TaskStatus;
import com.gluster.storage.management.server.utils.SshUtil;
@@ -36,13 +37,10 @@ public class InitializeDiskTask extends Task {
private SshUtil sshUtil = new SshUtil();
public InitializeDiskTask( String serverName, String diskName) {
- super(TASK_TYPE.DISK_FORMAT, diskName);
+ super(TASK_TYPE.DISK_FORMAT, diskName, "Initialize disk " + serverName + ":" + diskName, false, false, false);
- getTaskInfo().setCanPause(false);
- getTaskInfo().setCanStop(false);
setServerName(serverName);
setDiskName(diskName);
- setTaskDescription();
}
public InitializeDiskTask(TaskInfo info) {
@@ -51,25 +49,27 @@ public class InitializeDiskTask extends Task {
@Override
public String getId() {
- return getTaskInfo().getId();
+ return taskInfo.getType() + "-" + serverName + ":" + diskName;
}
@Override
- public TaskInfo resume() {
+ public void resume() {
getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not resume disk initialization")));
- return getTaskInfo();
}
@Override
- public TaskInfo stop() {
+ public void stop() {
getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not stop disk initialization")));
- return getTaskInfo();
}
@Override
- public TaskInfo pause() {
+ public void pause() {
getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not suspend disk initialization")));
- return getTaskInfo();
+ }
+
+ @Override
+ public void commit() {
+ // TODO Auto-generated method stub
}
@Override
@@ -83,25 +83,16 @@ public class InitializeDiskTask extends Task {
}
@Override
- public TaskInfo start() {
+ public void start() {
getTaskInfo().setStatus(
new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), INITIALIZE_DISK_SCRIPT + " "
+ getDiskName()))));
- return getTaskInfo();
- }
-
- @Override
- public TaskInfo status() {
- getTaskInfo().setStatus(
-
- new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), INITIALIZE_DISK_STATUS_SCRIPT + " "
- + getDiskName()))));
- return getTaskInfo();
}
@Override
- public void setTaskDescription() {
- getTaskInfo().setDescription("Formating disk of " + getServerName() + ":" + getDiskName());
+ public TaskStatus checkStatus() {
+ return new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), INITIALIZE_DISK_STATUS_SCRIPT + " "
+ + getDiskName())));
}
public void setDiskName(String diskName) {
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java
index df637ab1..1f044d77 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java
@@ -20,12 +20,12 @@
*/
package com.gluster.storage.management.server.tasks;
-import org.springframework.beans.factory.annotation.Autowired;
-
import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.Task;
import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
import com.gluster.storage.management.core.model.TaskStatus;
+import com.gluster.storage.management.core.utils.ProcessResult;
import com.gluster.storage.management.server.utils.SshUtil;
public class MigrateDiskTask extends Task {
@@ -60,67 +60,111 @@ public class MigrateDiskTask extends Task {
this.autoCommit = autoCommit;
}
- public MigrateDiskTask(TASK_TYPE type, String volumeName, String fromBrick, String toBrick) {
- super(type, volumeName);
+ public MigrateDiskTask(String volumeName, String fromBrick, String toBrick) {
+ super(TASK_TYPE.BRICK_MIGRATE, volumeName, "Brick Migration on volume [" + volumeName + "] from [" + fromBrick
+ + "] to [" + toBrick + "]", true, true, true);
setFromBrick(fromBrick);
setToBrick(toBrick);
- setTaskDescription();
- getTaskInfo().setCanPause(true);
- getTaskInfo().setCanStop(true);
}
public MigrateDiskTask(TaskInfo info) {
super(info);
- setTaskDescription();
}
@Override
public String getId() {
- return getTaskInfo().getId();
+ return taskInfo.getType() + "-" + taskInfo.getReference() + "-" + fromBrick + "-" + toBrick;
}
@Override
- public TaskInfo start() {
- getTaskInfo().setStatus(
- new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume replace-brick "
- + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " start" ) )));
- return getTaskInfo();
+ public void start() {
+ String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " "
+ + getToBrick() + " start";
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().matches("*started successfully")) {
+ taskStatus.setCode(Status.STATUS_CODE_RUNNING);
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ taskStatus.setMessage(processResult.getOutput()); // Common
+ getTaskInfo().setStatus(taskStatus);
}
+
+
@Override
- public TaskInfo resume() {
- return start();
+ public void pause() {
+ String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick()
+ + " pause";
+
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().matches("*pause")) {
+ taskStatus.setCode(Status.STATUS_CODE_PAUSE);
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ taskStatus.setMessage(processResult.getOutput()); // Common
+ getTaskInfo().setStatus(taskStatus);
}
-
+
+
@Override
- public TaskInfo stop() {
- getTaskInfo().setStatus(
- new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume replace-brick "
- + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " abort" ) )));
- return getTaskInfo();
+ public void resume() {
+ start();
}
-
+
@Override
- public TaskInfo pause() {
- getTaskInfo().setStatus(
- new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume replace-brick "
- + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " pause" ) )));
- return getTaskInfo();
-
+ public void commit() {
+ // TODO Auto-generated method stub
}
-
@Override
- public void setTaskDescription() {
- TaskInfo taskInfo = getTaskInfo();
- getTaskInfo().setDescription(
- getTypeStr() + " on volume [" + taskInfo.getReference() + "] from [" + getFromBrick()
- + "] to [" + getToBrick() + "]");
+ public void stop() {
+ String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick()
+ + " abort";
+
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().matches("*abort")) {
+ taskStatus.setCode(Status.STATUS_CODE_SUCCESS);
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ taskStatus.setMessage(processResult.getOutput()); // Common
+ getTaskInfo().setStatus(taskStatus);
}
@Override
- public TaskInfo status() {
- return getTaskInfo();
+ public TaskStatus checkStatus() {
+ String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " "
+ + getToBrick() + " status";
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().matches("*Migration complete")) {
+ taskStatus.setCode(Status.STATUS_CODE_SUCCESS);
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_RUNNING);
+ }
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ taskStatus.setMessage(processResult.getOutput()); // Common
+ return taskStatus;
}
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java
index 670ffb5c..0a0892f0 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java
@@ -36,8 +36,7 @@ import com.gluster.storage.management.core.model.Brick.BRICK_STATUS;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS;
import com.gluster.storage.management.core.model.Status;
-import com.gluster.storage.management.core.model.Task.TASK_TYPE;
-import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE;
import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS;
@@ -539,17 +538,21 @@ public class GlusterUtil {
public String migrateBrickStart(String volumeName, String fromBrick, String toBrick, Boolean autoCommit,
String knownServer) {
- MigrateDiskTask migrateDiskTask = new MigrateDiskTask(TASK_TYPE.BRICK_MIGRATE, volumeName, fromBrick, toBrick);
+ MigrateDiskTask migrateDiskTask = new MigrateDiskTask(volumeName, fromBrick, toBrick);
migrateDiskTask.setOnlineServer(knownServer);
migrateDiskTask.setAutoCommit(autoCommit);
-
- TaskInfo taskInfo = migrateDiskTask.start();
- if (taskInfo.isSuccess()) {
+ migrateDiskTask.start();
+ int status = migrateDiskTask.getTaskInfo().getStatus().getCode();
+ if (status != Status.STATUS_CODE_FAILURE ) {
+ TasksResource tasksResource = new TasksResource();
taskResource.addTask(migrateDiskTask);
+ } else {
+ throw new GlusterRuntimeException( migrateDiskTask.getTaskInfo().getStatus().getMessage());
}
- return taskInfo.getId();
+ return migrateDiskTask.getId();
}
+
public Status removeBricks(String volumeName, List<String> bricks, String knownServer) {
StringBuilder command = new StringBuilder("gluster --mode=script volume remove-brick " + volumeName);