From dc9006106dd12324119d04796b5b054555ab82a8 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 22 Jun 2011 10:57:38 +0530 Subject: Story #23: Initialize Disk --- .../management/client/GlusterServersClient.java | 4 + .../management/core/constants/RESTConstants.java | 1 + .../gui/views/pages/AbstractDisksPage.java | 6 +- .../server/resources/GlusterServersResource.java | 27 +++++ .../server/tasks/InitializeDiskTask.java | 118 +++++++++++++++++++++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 20c52a41..ab2ac2ca 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -70,6 +70,10 @@ public class GlusterServersClient extends AbstractClient { postRequest(form); } + public void initializeDisk(String serverName, String diskName) { + putRequest(serverName + "/" + RESTConstants.RESOURCE_DISKS + "/" + diskName); + } + public void removeServer(String serverName) { deleteSubResource(serverName); } 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 a2d222a8..93c07a20 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 @@ -73,6 +73,7 @@ public class RESTConstants { public static final String PATH_PARAM_CLUSTER_NAME = "clusterName"; public static final String PATH_PARAM_SERVER_NAME = "serverName"; public static final String PATH_PARAM_TASK_ID = "taskId"; + public static final String PATH_PARAM_DISK_NAME = "diskName"; public static final String QUERY_PARAM_BRICK_NAME = "brickName"; public static final String QUERY_PARAM_DISKS = "disks"; 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 133aed38..32a2c2f6 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 @@ -38,6 +38,7 @@ import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.ImageHyperlink; +import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Disk; @@ -199,8 +200,11 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im @Override public void linkActivated(HyperlinkEvent e) { updateStatus(DISK_STATUS.INITIALIZING, true); + + GlusterServersClient serversClient = new GlusterServersClient(); + serversClient.initializeDisk(disk.getServerName(), disk.getName()); + guiHelper.showProgressView(); - new InitializeDiskJob(disk).schedule(); } } 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 03a927ab..81c6e53e 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 @@ -21,6 +21,7 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; @@ -32,6 +33,7 @@ import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -47,12 +49,15 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; 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.TaskInfo; import com.gluster.storage.management.core.response.GlusterServerListResponse; import com.gluster.storage.management.core.response.GlusterServerResponse; +import com.gluster.storage.management.core.response.TaskResponse; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.services.ClusterService; +import com.gluster.storage.management.server.tasks.InitializeDiskTask; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.SshUtil; import com.sun.jersey.api.core.InjectParam; @@ -69,6 +74,9 @@ public class GlusterServersResource extends AbstractServersResource { @InjectParam private DiscoveredServersResource discoveredServersResource; + @InjectParam + private TasksResource taskResource; + @Autowired private ClusterService clusterService; @@ -387,6 +395,25 @@ public class GlusterServersResource extends AbstractServersResource { return status; } + + @PUT + @Produces(MediaType.APPLICATION_XML) + @Path("{" + PATH_PARAM_SERVER_NAME + "}") + public TaskResponse initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_SERVER_NAME) String serverName, @PathParam(PATH_PARAM_DISK_NAME) String diskName) { + + TaskResponse taskResponse = new TaskResponse(); + InitializeDiskTask initializeTask = new InitializeDiskTask(diskName, serverName); + TaskInfo taskInfo = initializeTask.start(); + if (taskInfo.isSuccess()) { + taskResource.addTask(initializeTask); + } + taskResponse.setData(taskInfo); + taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, "")); + + return taskResponse; + } + private void setGlusterUtil(GlusterUtil glusterUtil) { this.glusterUtil = glusterUtil; 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 new file mode 100644 index 00000000..ef89a2a8 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java @@ -0,0 +1,118 @@ +/** + * MigrateDiskTask.java + * + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + */ +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.TaskStatus; +import com.gluster.storage.management.server.utils.SshUtil; + +public class InitializeDiskTask extends Task { + + private String serverName; + private String diskName; + private SshUtil sshUtil = new SshUtil(); + + public InitializeDiskTask( String serverName, String diskName) { + super(TASK_TYPE.DISK_FORMAT, diskName); + + getTaskInfo().setCanPause(false); + getTaskInfo().setCanStop(false); + setServerName(serverName); + setDiskName(diskName); + setTaskDescription(); + } + + public InitializeDiskTask(TaskInfo info) { + super(info); + } + + @Override + public String getId() { + return getTaskInfo().getId(); + } + + @Override + public TaskInfo resume() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not resume disk initialization"))); + return getTaskInfo(); + } + + @Override + public TaskInfo stop() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not stop disk initialization"))); + return getTaskInfo(); + } + + @Override + public TaskInfo pause() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not suspend disk initialization"))); + return getTaskInfo(); + } + + @Override + public TASK_TYPE getType() { + return TASK_TYPE.DISK_FORMAT; + } + + @Override + public TaskInfo getTaskInfo() { + return getTaskInfo(); + } + + @Override + public TaskInfo start() { + getTaskInfo().setStatus( + new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), "initialize_disk.py " + + getDiskName())))); + return getTaskInfo(); + } + + @Override + public TaskInfo status() { + getTaskInfo().setStatus( + new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), "initialize_disk_status.py " + + getDiskName())))); + return getTaskInfo(); + } + + @Override + public void setTaskDescription() { + getTaskInfo().setDescription("Formating disk of " + getServerName() + ":" + getDiskName()); + } + + public void setDiskName(String diskName) { + this.diskName = diskName; + } + + public String getDiskName() { + return diskName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public String getServerName() { + return serverName; + } +} -- cgit From 31fb6f106e6626ffd922139186cff1ed0e2adc95 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 22 Jun 2011 10:57:38 +0530 Subject: Story #23: Initialize Disk --- .../management/client/GlusterServersClient.java | 4 + .../management/core/constants/RESTConstants.java | 1 + .../gui/views/pages/AbstractDisksPage.java | 6 +- .../server/resources/GlusterServersResource.java | 27 +++++ .../server/tasks/InitializeDiskTask.java | 121 +++++++++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 20c52a41..ab2ac2ca 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -70,6 +70,10 @@ public class GlusterServersClient extends AbstractClient { postRequest(form); } + public void initializeDisk(String serverName, String diskName) { + putRequest(serverName + "/" + RESTConstants.RESOURCE_DISKS + "/" + diskName); + } + public void removeServer(String serverName) { deleteSubResource(serverName); } 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 a2d222a8..93c07a20 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 @@ -73,6 +73,7 @@ public class RESTConstants { public static final String PATH_PARAM_CLUSTER_NAME = "clusterName"; public static final String PATH_PARAM_SERVER_NAME = "serverName"; public static final String PATH_PARAM_TASK_ID = "taskId"; + public static final String PATH_PARAM_DISK_NAME = "diskName"; public static final String QUERY_PARAM_BRICK_NAME = "brickName"; public static final String QUERY_PARAM_DISKS = "disks"; 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 133aed38..32a2c2f6 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 @@ -38,6 +38,7 @@ import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.ImageHyperlink; +import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Disk; @@ -199,8 +200,11 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im @Override public void linkActivated(HyperlinkEvent e) { updateStatus(DISK_STATUS.INITIALIZING, true); + + GlusterServersClient serversClient = new GlusterServersClient(); + serversClient.initializeDisk(disk.getServerName(), disk.getName()); + guiHelper.showProgressView(); - new InitializeDiskJob(disk).schedule(); } } 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 03a927ab..81c6e53e 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 @@ -21,6 +21,7 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; @@ -32,6 +33,7 @@ import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -47,12 +49,15 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; 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.TaskInfo; import com.gluster.storage.management.core.response.GlusterServerListResponse; import com.gluster.storage.management.core.response.GlusterServerResponse; +import com.gluster.storage.management.core.response.TaskResponse; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.services.ClusterService; +import com.gluster.storage.management.server.tasks.InitializeDiskTask; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.SshUtil; import com.sun.jersey.api.core.InjectParam; @@ -69,6 +74,9 @@ public class GlusterServersResource extends AbstractServersResource { @InjectParam private DiscoveredServersResource discoveredServersResource; + @InjectParam + private TasksResource taskResource; + @Autowired private ClusterService clusterService; @@ -387,6 +395,25 @@ public class GlusterServersResource extends AbstractServersResource { return status; } + + @PUT + @Produces(MediaType.APPLICATION_XML) + @Path("{" + PATH_PARAM_SERVER_NAME + "}") + public TaskResponse initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @PathParam(PATH_PARAM_SERVER_NAME) String serverName, @PathParam(PATH_PARAM_DISK_NAME) String diskName) { + + TaskResponse taskResponse = new TaskResponse(); + InitializeDiskTask initializeTask = new InitializeDiskTask(diskName, serverName); + TaskInfo taskInfo = initializeTask.start(); + if (taskInfo.isSuccess()) { + taskResource.addTask(initializeTask); + } + taskResponse.setData(taskInfo); + taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, "")); + + return taskResponse; + } + private void setGlusterUtil(GlusterUtil glusterUtil) { this.glusterUtil = glusterUtil; 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 new file mode 100644 index 00000000..7d2ec6c3 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java @@ -0,0 +1,121 @@ +/** + * InitializeDiskTask.java + * + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + */ +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.TaskStatus; +import com.gluster.storage.management.server.utils.SshUtil; + +public class InitializeDiskTask extends Task { + + private static final String INITIALIZE_DISK_SCRIPT = "initialize_disk.py"; + private static final String INITIALIZE_DISK_STATUS_SCRIPT = "initialize_disk_status.py"; + + private String serverName; + private String diskName; + private SshUtil sshUtil = new SshUtil(); + + public InitializeDiskTask( String serverName, String diskName) { + super(TASK_TYPE.DISK_FORMAT, diskName); + + getTaskInfo().setCanPause(false); + getTaskInfo().setCanStop(false); + setServerName(serverName); + setDiskName(diskName); + setTaskDescription(); + } + + public InitializeDiskTask(TaskInfo info) { + super(info); + } + + @Override + public String getId() { + return getTaskInfo().getId(); + } + + @Override + public TaskInfo resume() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not resume disk initialization"))); + return getTaskInfo(); + } + + @Override + public TaskInfo stop() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not stop disk initialization"))); + return getTaskInfo(); + } + + @Override + public TaskInfo pause() { + getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not suspend disk initialization"))); + return getTaskInfo(); + } + + @Override + public TASK_TYPE getType() { + return TASK_TYPE.DISK_FORMAT; + } + + @Override + public TaskInfo getTaskInfo() { + return getTaskInfo(); + } + + @Override + public TaskInfo 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 void setDiskName(String diskName) { + this.diskName = diskName; + } + + public String getDiskName() { + return diskName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public String getServerName() { + return serverName; + } +} -- cgit From e6518b703800c986b90f2fe570d64edb8c32a813 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 23 Jun 2011 14:22:26 +0530 Subject: Story #23: Initialize Disk --- .../server/resources/GlusterServersResource.java | 204 +++++++++++---------- 1 file changed, 107 insertions(+), 97 deletions(-) (limited to 'src') 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 7ca1295e..ef2a862e 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 @@ -18,14 +18,13 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SOURCE; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; import java.util.ArrayList; import java.util.List; @@ -45,6 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.GlusterServer; @@ -52,7 +52,6 @@ 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.TaskInfo; import com.gluster.storage.management.core.response.GlusterServerListResponse; -import com.gluster.storage.management.core.response.GlusterServerResponse; import com.gluster.storage.management.core.response.TaskResponse; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; @@ -71,39 +70,39 @@ public class GlusterServersResource extends AbstractServersResource { public static final String HOSTNAMETAG = "hostname:"; private LRUCache clusterServerCache = new LRUCache(3); - + @InjectParam private DiscoveredServersResource discoveredServersResource; - + @InjectParam - private TasksResource taskResource; - + private TasksResource taskResource; + @Autowired private ClusterService clusterService; - + @Autowired private SshUtil sshUtil; - + protected void fetchServerDetails(GlusterServer server) { try { server.setStatus(SERVER_STATUS.ONLINE); super.fetchServerDetails(server); - } catch(ConnectionException e) { + } catch (ConnectionException e) { server.setStatus(SERVER_STATUS.OFFLINE); } } - + public GlusterServer getOnlineServer(String clusterName) { return getOnlineServer(clusterName, ""); } - + // uses cache public GlusterServer getOnlineServer(String clusterName, String exceptServerName) { GlusterServer server = clusterServerCache.get(clusterName); - if(server != null && !server.getName().equals(exceptServerName)) { + if (server != null && !server.getName().equals(exceptServerName)) { return server; } - + return getNewOnlineServer(clusterName, exceptServerName); } @@ -114,41 +113,39 @@ public class GlusterServersResource extends AbstractServersResource { // Doesn't use cache public GlusterServer getNewOnlineServer(String clusterName, String exceptServerName) { ClusterInfo cluster = clusterService.getCluster(clusterName); - if(cluster == null) { + if (cluster == null) { return null; } - - for(ServerInfo serverInfo : cluster.getServers()) { + + for (ServerInfo serverInfo : cluster.getServers()) { GlusterServer server = new GlusterServer(serverInfo.getName()); fetchServerDetails(server); - if(server.isOnline() && !server.getName().equals(exceptServerName)) { + if (server.isOnline() && !server.getName().equals(exceptServerName)) { // server is online. add it to cache and return clusterServerCache.put(clusterName, server); return server; } } - + // no online server found. return null; } - + @GET @Produces(MediaType.APPLICATION_JSON) - public Response getGlusterServersJSON( - @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { + public Response getGlusterServersJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { return getGlusterServers(clusterName, MediaType.APPLICATION_JSON); } @GET @Produces(MediaType.APPLICATION_XML) - public Response getGlusterServersXML( - @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { + public Response getGlusterServersXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { return getGlusterServers(clusterName, MediaType.APPLICATION_XML); } public Response getGlusterServers(String clusterName, String mediaType) { List glusterServers = new ArrayList(); - + if (clusterName == null || clusterName.isEmpty()) { return badRequestResponse("Cluster name must not be empty!"); } @@ -158,18 +155,18 @@ public class GlusterServersResource extends AbstractServersResource { return badRequestResponse("Cluster [" + clusterName + "] not found!"); } - if(cluster.getServers().size() == 0) { + if (cluster.getServers().size() == 0) { return okResponse(new GlusterServerListResponse(glusterServers), mediaType); } - + GlusterServer onlineServer = getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } - + try { glusterServers = getGlusterServers(clusterName, onlineServer); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = getNewOnlineServer(clusterName); if (onlineServer == null) { @@ -177,24 +174,24 @@ public class GlusterServersResource extends AbstractServersResource { } try { glusterServers = getGlusterServers(clusterName, onlineServer); - } catch(Exception e1) { + } catch (Exception e1) { return errorResponse(e1.getMessage()); } - } catch(Exception e) { + } catch (Exception e) { return errorResponse(e.getMessage()); } - + String errMsg = fetchDetailsOfServers(glusterServers, onlineServer); - if(!errMsg.isEmpty()) { + if (!errMsg.isEmpty()) { return errorResponse("Couldn't fetch details for server(s): " + errMsg); } - + return okResponse(new GlusterServerListResponse(glusterServers), mediaType); } public String fetchDetailsOfServers(List glusterServers, GlusterServer onlineServer) { String errMsg = ""; - + for (GlusterServer server : glusterServers) { if (server.getStatus() == SERVER_STATUS.ONLINE && !server.getName().equals(onlineServer.getName())) { try { @@ -211,13 +208,13 @@ public class GlusterServersResource extends AbstractServersResource { List glusterServers; try { glusterServers = glusterUtil.getGlusterServers(onlineServer); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = getNewOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } - + glusterServers = glusterUtil.getGlusterServers(onlineServer); } return glusterServers; @@ -226,8 +223,7 @@ public class GlusterServersResource extends AbstractServersResource { @GET @Path("{serverName}") @Produces(MediaType.APPLICATION_XML) - public Response getGlusterServerXML( - @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + public Response getGlusterServerXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { return getGlusterServerResponse(clusterName, serverName, MediaType.APPLICATION_XML); } @@ -235,8 +231,7 @@ public class GlusterServersResource extends AbstractServersResource { @GET @Path("{serverName}") @Produces(MediaType.APPLICATION_JSON) - public Response getGlusterServerJSON( - @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + public Response getGlusterServerJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { return getGlusterServerResponse(clusterName, serverName, MediaType.APPLICATION_JSON); } @@ -244,7 +239,7 @@ public class GlusterServersResource extends AbstractServersResource { private Response getGlusterServerResponse(String clusterName, String serverName, String mediaType) { try { return okResponse(getGlusterServer(clusterName, serverName), mediaType); - } catch(Exception e) { + } catch (Exception e) { return errorResponse(e.getMessage()); } } @@ -267,11 +262,11 @@ public class GlusterServersResource extends AbstractServersResource { if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } - + GlusterServer server = null; try { server = glusterUtil.getGlusterServer(onlineServer, serverName); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = getNewOnlineServer(clusterName); if (onlineServer == null) { @@ -279,8 +274,8 @@ public class GlusterServersResource extends AbstractServersResource { } server = glusterUtil.getGlusterServer(onlineServer, serverName); } - - if(server.isOnline()) { + + if (server.isOnline()) { fetchServerDetails(server); } return server; @@ -288,68 +283,68 @@ public class GlusterServersResource extends AbstractServersResource { private void performAddServer(String clusterName, String serverName) { GlusterServer onlineServer = getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } - + try { glusterUtil.addServer(onlineServer.getName(), serverName); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = getNewOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } - + glusterUtil.addServer(serverName, onlineServer.getName()); } } - + @POST public Response addServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @FormParam(FORM_PARAM_SERVER_NAME) String serverName) { - if(clusterName == null || clusterName.isEmpty()) { + if (clusterName == null || clusterName.isEmpty()) { return badRequestResponse("Cluster name must not be empty!"); } - - if(serverName == null || serverName.isEmpty()) { + + if (serverName == null || serverName.isEmpty()) { return badRequestResponse("Parameter [" + FORM_PARAM_SERVER_NAME + "] is missing in request!"); } - + ClusterInfo cluster = clusterService.getCluster(clusterName); if (cluster == null) { return badRequestResponse("Cluster [" + clusterName + "] not found!"); } - + boolean publicKeyInstalled = sshUtil.isPublicKeyInstalled(serverName); - if(!publicKeyInstalled && !sshUtil.hasDefaultPassword(serverName)) { + if (!publicKeyInstalled && !sshUtil.hasDefaultPassword(serverName)) { // public key not installed, default password doesn't work. return with error. return errorResponse("Gluster Management Gateway uses the default password to set up keys on the server." + CoreConstants.NEWLINE + "However it seems that the password on server [" + serverName + "] has been changed manually." + CoreConstants.NEWLINE + "Please reset it back to the standard default password and try again."); } - + List servers = cluster.getServers(); - if(servers != null && !servers.isEmpty()) { + if (servers != null && !servers.isEmpty()) { // cluster has at least one existing server, so that peer probe can be performed try { performAddServer(clusterName, serverName); - } catch(Exception e) { + } catch (Exception e) { return errorResponse(e.getMessage()); } } else { // this is the first server to be added to the cluster, which means no // gluster CLI operation required. just add it to the cluster-server mapping } - + try { // add the cluster-server mapping clusterService.mapServerToCluster(clusterName, serverName); } catch (Exception e) { return errorResponse(e.getMessage()); } - + // since the server is added to a cluster, it should not more be considered as a // discovered server available to other clusters discoveredServersResource.removeDiscoveredServer(serverName); @@ -374,37 +369,36 @@ public class GlusterServersResource extends AbstractServersResource { if (clusterName == null || clusterName.isEmpty()) { return badRequestResponse("Cluster name must not be empty!"); } - - if(serverName == null || serverName.isEmpty()) { + + if (serverName == null || serverName.isEmpty()) { return badRequestResponse("Server name must not be empty!"); } - + ClusterInfo cluster = clusterService.getCluster(clusterName); - if(cluster == null) { + if (cluster == null) { return badRequestResponse("Cluster [" + clusterName + "] not found!"); } List servers = cluster.getServers(); - if(servers == null || servers.isEmpty() || !containsServer(servers, serverName)) { - return badRequestResponse("Server [" + serverName + "] is not attached to cluster [" - + clusterName + "]!"); + if (servers == null || servers.isEmpty() || !containsServer(servers, serverName)) { + return badRequestResponse("Server [" + serverName + "] is not attached to cluster [" + clusterName + "]!"); } - - if(servers.size() == 1) { + + if (servers.size() == 1) { // Only one server mapped to the cluster, no "peer detach" required. // remove the cached online server for this cluster if present clusterServerCache.remove(clusterName); } else { try { removeServerFromCluster(clusterName, serverName); - } catch(Exception e) { + } catch (Exception e) { return errorResponse(e.getMessage()); } - } - + } + return noContentResponse(); } - + private void removeServerFromCluster(String clusterName, String serverName) { // get an online server that is not same as the server being removed GlusterServer onlineServer = getOnlineServer(clusterName, serverName); @@ -422,46 +416,62 @@ public class GlusterServersResource extends AbstractServersResource { } glusterUtil.removeServer(onlineServer.getName(), serverName); } - - if(onlineServer.getName().equals(serverName)) { + + if (onlineServer.getName().equals(serverName)) { // since the cached server has been removed from the cluster, remove it from the cache clusterServerCache.remove(clusterName); } - + clusterService.unmapServerFromCluster(clusterName, serverName); - - // since the server is removed from the cluster, it is now available to be added to other clusters. + + // since the server is removed from the cluster, it is now available to be added to other clusters. // Hence add it back to the discovered servers list. - discoveredServersResource.addDiscoveredServer(serverName); + discoveredServersResource.addDiscoveredServer(serverName); } private boolean containsServer(List servers, String serverName) { - for(ServerInfo server : servers) { - if(server.getName().toUpperCase().equals(serverName.toUpperCase())) { + for (ServerInfo server : servers) { + if (server.getName().toUpperCase().equals(serverName.toUpperCase())) { return true; } } return false; } - + @PUT @Produces(MediaType.APPLICATION_XML) @Path("{" + PATH_PARAM_SERVER_NAME + "}") - public TaskResponse initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + public Response initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName, @PathParam(PATH_PARAM_DISK_NAME) String diskName) { - + + if (clusterName == null || clusterName.isEmpty()) { + return badRequestResponse("Cluster name must not be empty!"); + } + + if (serverName == null || serverName.isEmpty()) { + return badRequestResponse("Server name must not be empty!"); + } + + if (diskName == null || diskName.isEmpty()) { + return badRequestResponse("Disk name must not be empty!"); + } + TaskResponse taskResponse = new TaskResponse(); InitializeDiskTask initializeTask = new InitializeDiskTask(diskName, serverName); - TaskInfo taskInfo = initializeTask.start(); - if (taskInfo.isSuccess()) { - taskResource.addTask(initializeTask); - } - taskResponse.setData(taskInfo); - taskResponse.setStatus(new Status(Status.STATUS_CODE_SUCCESS, "")); - - return taskResponse; + 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, "")); + } catch (ConnectionException e) { + return errorResponse(e.getMessage()); + } + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); } - private void setGlusterUtil(GlusterUtil glusterUtil) { this.glusterUtil = glusterUtil; -- cgit From e804392391cededbed09208e00eb0ab9312c4b6d Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Thu, 23 Jun 2011 19:50:06 +0530 Subject: REST API Enhancements --- .../management/client/DiscoveredServersClient.java | 37 ++++---- .../management/client/GlusterDataModelManager.java | 9 +- .../management/core/constants/RESTConstants.java | 2 +- .../core/response/ServerListResponse.java | 26 +----- .../core/response/ServerNameListResponse.java | 46 ++++++++++ .../resources/DiscoveredServersResource.java | 100 ++++++++++++--------- 6 files changed, 128 insertions(+), 92 deletions(-) create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerNameListResponse.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java index e055a2dd..f35c3e36 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java @@ -18,13 +18,17 @@ *******************************************************************************/ package com.gluster.storage.management.client; +import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DETAILS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_DISCOVERED_SERVERS; + +import java.util.List; + import javax.ws.rs.core.MultivaluedMap; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.ServerListResponse; -import com.gluster.storage.management.core.response.StringListResponse; -import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_DISCOVERED_SERVERS; +import com.gluster.storage.management.core.response.ServerNameListResponse; import com.sun.jersey.core.util.MultivaluedMapImpl; public class DiscoveredServersClient extends AbstractClient { @@ -43,38 +47,33 @@ public class DiscoveredServersClient extends AbstractClient { } @SuppressWarnings("rawtypes") - private Object getDiscoveredServers(Boolean getDetails, Class responseClass) { + private Object getDiscoveredServers(Boolean details, Class responseClass) { MultivaluedMap queryParams = new MultivaluedMapImpl(); - queryParams.putSingle("details", getDetails.toString()); + queryParams.putSingle(QUERY_PARAM_DETAILS, details.toString()); return fetchResource(queryParams, responseClass); } - public StringListResponse getDiscoveredServerNames() { - - return (StringListResponse) getDiscoveredServers(Boolean.FALSE, StringListResponse.class); + public List getDiscoveredServerNames() { + return ((ServerNameListResponse) getDiscoveredServers(Boolean.FALSE, ServerNameListResponse.class)) + .getServerNames(); } - public ServerListResponse getDiscoveredServerDetails() { - return (ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class); + public List getDiscoveredServerDetails() { + return ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)).getServers(); } - @SuppressWarnings("unchecked") public Server getServer(String serverName) { - GenericResponse response = (GenericResponse) fetchSubResource(serverName, GenericResponse.class); - return response.getData(); + return (Server) fetchSubResource(serverName, Server.class); } public static void main(String[] args) { UsersClient usersClient = new UsersClient(); if (usersClient.authenticate("gluster", "gluster").isSuccess()) { DiscoveredServersClient serverResource = new DiscoveredServersClient(usersClient.getSecurityToken()); - StringListResponse discoveredServerNames = serverResource.getDiscoveredServerNames(); - System.out.println(discoveredServerNames.getData()); - ServerListResponse discoveredServers = serverResource.getDiscoveredServerDetails(); - System.out.println(discoveredServers.getData()); - - // Server serverDetails = ServerResource.getServer("localhost"); - // System.out.println(serverDetails.getName()); + List discoveredServerNames = serverResource.getDiscoveredServerNames(); + System.out.println(discoveredServerNames); + List discoveredServers = serverResource.getDiscoveredServerDetails(); + System.out.println(discoveredServers); } } } 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 3c5aedf5..695fae19 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 @@ -105,14 +105,7 @@ public class GlusterDataModelManager { } private void initializeAutoDiscoveredServers(Cluster cluster) { - ServerListResponse discoveredServerListResponse = new DiscoveredServersClient(securityToken) - .getDiscoveredServerDetails(); - Status status = discoveredServerListResponse.getStatus(); - if (!status.isSuccess() && !status.isPartSuccess()) { - // TODO: Find a way to show warning in case of part success - throw new GlusterRuntimeException(discoveredServerListResponse.getStatus().getMessage()); - } - cluster.setAutoDiscoveredServers(discoveredServerListResponse.getData()); + cluster.setAutoDiscoveredServers(new DiscoveredServersClient(securityToken).getDiscoveredServerDetails()); } private void initializeVolumes(Cluster cluster) { 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 a2d222a8..b3dc30c2 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 @@ -56,7 +56,6 @@ public class RESTConstants { public static final String FORM_PARAM_ACCESS_PROTOCOLS = "accessProtocols"; public static final String FORM_PARAM_VOLUME_OPTIONS = "options"; - public static final String FORM_PARAM_CLUSTER_NAME = "clusterName"; public static final String FORM_PARAM_SERVER_NAME = "serverName"; public static final String FORM_PARAM_DISKS = "disks"; @@ -85,6 +84,7 @@ public class RESTConstants { public static final String QUERY_PARAM_TO_TIMESTAMP = "toTimestamp"; public static final String QUERY_PARAM_DOWNLOAD = "download"; public static final String QUERY_PARAM_SERVER_NAME = "serverName"; + public static final String QUERY_PARAM_DETAILS = "details"; public static final String FORMAT_XML = "xml"; public static final String FORMAT_JSON = "json"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerListResponse.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerListResponse.java index 16059b15..05627ab1 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerListResponse.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerListResponse.java @@ -22,47 +22,27 @@ import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; import com.gluster.storage.management.core.model.Server; -import com.gluster.storage.management.core.model.Status; -@XmlRootElement(name = "response") -public class ServerListResponse extends AbstractResponse { +@XmlRootElement(name = "servers") +public class ServerListResponse { private List servers = new ArrayList(); public ServerListResponse() { } - public ServerListResponse(Status status, List servers) { - setStatus(status); + public ServerListResponse(List servers) { setServers(servers); } - @XmlElementWrapper(name = "servers") @XmlElement(name = "server", type=Server.class) public List getServers() { return servers; } - /** - * @param servers - * the servers to set - */ public void setServers(List servers) { this.servers = servers; } - - /* - * (non-Javadoc) - * - * @see com.gluster.storage.management.core.model.Response#getData() - */ - @Override - @XmlTransient - public List getData() { - return getServers(); - } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerNameListResponse.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerNameListResponse.java new file mode 100644 index 00000000..2211f29f --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerNameListResponse.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + *******************************************************************************/ +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; + +/** + * Response object for transferring cluster names during REST communication. This is just a wrapper over a list of + * Strings, and is required because the jersey rest framework can't transfer lists directly. + */ +@XmlRootElement(name="servers") +public class ServerNameListResponse { +private List serverNames = new ArrayList(); + + public ServerNameListResponse() { + } + + public ServerNameListResponse(List serverNames) { + this.serverNames = serverNames; + } + + @XmlElement(name = "server", type = String.class) + public List getServerNames() { + return serverNames; + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java index aba88d82..ee9d3600 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java @@ -18,6 +18,8 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DETAILS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_DISCOVERED_SERVERS; import java.util.ArrayList; @@ -29,16 +31,13 @@ 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 org.springframework.stereotype.Component; -import com.gluster.storage.management.core.constants.CoreConstants; -import com.gluster.storage.management.core.model.Response; import com.gluster.storage.management.core.model.Server; -import com.gluster.storage.management.core.model.Status; -import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.ServerListResponse; -import com.gluster.storage.management.core.response.StringListResponse; +import com.gluster.storage.management.core.response.ServerNameListResponse; import com.sun.jersey.spi.resource.Singleton; @Component @@ -67,57 +66,76 @@ public class DiscoveredServersResource extends AbstractServersResource { @GET @Produces(MediaType.APPLICATION_XML) - @SuppressWarnings("rawtypes") - public Response getDiscoveredServers(@QueryParam("details") Boolean getDetails) { - if(getDetails != null && getDetails == true) { - return getDiscoveredServerDetails(); + public Response getDiscoveredServersXML(@QueryParam(QUERY_PARAM_DETAILS) Boolean details) { + return getDiscoveredServersResponse(details, MediaType.APPLICATION_XML); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getDiscoveredServersJSON(@QueryParam(QUERY_PARAM_DETAILS) Boolean details) { + return getDiscoveredServersResponse(details, MediaType.APPLICATION_JSON); + } + + private Response getDiscoveredServersResponse(Boolean details, String mediaType) { + if(details != null && details == true) { + try { + List discoveredServers = getDiscoveredServerDetails(); + return okResponse(new ServerListResponse(discoveredServers), mediaType); + } catch(Exception e) { + return errorResponse(e.getMessage()); + } + } else { + return okResponse(new ServerNameListResponse(getDiscoveredServerNames()), mediaType); } - return new StringListResponse(getDiscoveredServerNames()); } - private ServerListResponse getDiscoveredServerDetails() { + private List getDiscoveredServerDetails() { List discoveredServers = new ArrayList(); - List serverNames = getDiscoveredServerNames(); - GenericResponse discoveredServerResponse; - int errCount = 0; - StringBuilder errMsg = new StringBuilder("Couldn't fetch details for server(s): "); - for (String serverName : serverNames) { - discoveredServerResponse = getDiscoveredServer(serverName); - if (!discoveredServerResponse.getStatus().isSuccess()) { - errMsg.append(CoreConstants.NEWLINE + serverName + " : " + discoveredServerResponse.getStatus()); - errCount++; - } else { - discoveredServers.add(discoveredServerResponse.getData()); + for (String serverName : getDiscoveredServerNames()) { + try { + discoveredServers.add(getDiscoveredServer(serverName)); + } catch(Exception e) { + // TODO: Log the exception + // continue with next discovered server } } - Status status = null; - if(errCount == 0) { - status = new Status(Status.STATUS_CODE_SUCCESS, "Success"); - } else if(errCount == serverNames.size()) { - status = new Status(Status.STATUS_CODE_FAILURE, errMsg.toString()); - } else { - status = new Status(Status.STATUS_CODE_PART_SUCCESS, errMsg.toString()); - } - return new ServerListResponse(status, discoveredServers); + return discoveredServers; } - @Path("/{serverName}") + @Path("{" + PATH_PARAM_SERVER_NAME + "}") @GET @Produces(MediaType.APPLICATION_XML) - public GenericResponse getDiscoveredServer(@PathParam("serverName") String serverName) { - Server server = new Server(serverName); + public Response getDiscoveredServerXML(@PathParam(PATH_PARAM_SERVER_NAME) String serverName) { + return getDiscoveredServerResponse(serverName, MediaType.APPLICATION_XML); + } + + @Path("{" + PATH_PARAM_SERVER_NAME + "}") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getDiscoveredServerJSON(@PathParam(PATH_PARAM_SERVER_NAME) String serverName) { + return getDiscoveredServerResponse(serverName, MediaType.APPLICATION_JSON); + } + + private Response getDiscoveredServerResponse(String serverName, String mediaType) { + if(serverName == null || serverName.isEmpty()) { + return badRequestResponse("Server name must not be empty!"); + } try { - fetchServerDetails(server); + return okResponse(getDiscoveredServer(serverName), mediaType); } catch (Exception e) { - return new GenericResponse(new Status(e), null); + // TODO: Log the exception + return errorResponse(e.getMessage()); } - return new GenericResponse(Status.STATUS_SUCCESS, server); + } + + private Server getDiscoveredServer(String serverName) { + Server server = new Server(serverName); + fetchServerDetails(server); + return server; } public static void main(String[] args) { - StringListResponse listResponse = (StringListResponse)new DiscoveredServersResource().getDiscoveredServers(false); - for (String server : listResponse.getData()) { - System.out.println(server); - } + Response response = (Response)new DiscoveredServersResource().getDiscoveredServersXML(false); + System.out.println(response.getEntity()); } } -- cgit From 83e384323d8c9ac3ad78084663c477eb6729eeaa Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Thu, 23 Jun 2011 21:47:16 +0530 Subject: REST API Enhancements --- .../storage/management/client/AbstractClient.java | 2 +- .../storage/management/client/ClustersClient.java | 44 +++++----- .../management/client/DiscoveredServersClient.java | 5 +- .../management/client/GlusterServersClient.java | 5 +- .../storage/management/client/UsersClient.java | 58 +++++++------ .../storage/management/client/VolumesClient.java | 5 +- .../management/core/constants/RESTConstants.java | 2 + .../management/gui/dialogs/LoginDialog.java | 98 +++++++++++----------- .../server/resources/AbstractResource.java | 20 +++++ .../management/server/resources/UsersResource.java | 61 +++++++------- 10 files changed, 166 insertions(+), 134 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java index 9eaaca93..3d13a8de 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java @@ -126,7 +126,7 @@ public abstract class AbstractClient { return res.queryParams(queryParams) .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).get(responseClass); } catch(UniformInterfaceException e) { - throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); + throw new GlusterRuntimeException(e.getResponse().getEntity(String.class), e); } } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java index dadeadf8..31809c75 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java @@ -74,27 +74,29 @@ public class ClustersClient extends AbstractClient { public static void main(String args[]) { UsersClient usersClient = new UsersClient(); - Status authStatus = usersClient.authenticate("gluster", "gluster"); - if (authStatus.isSuccess()) { - ClustersClient client = new ClustersClient(); - client.setSecurityToken(usersClient.getSecurityToken()); - System.out.println(client.getClusterNames()); - try { - client.createCluster("test1"); - } catch(GlusterRuntimeException e) { - System.out.println(e.getMessage()); - } - - System.out.println(client.getClusterNames()); - - try { - client.deleteCluster("test1"); - } catch (GlusterRuntimeException e) { - System.out.println(e.getMessage()); - } - System.out.println(client.getClusterNames()); - } else { - System.out.println("authentication failed: " + authStatus); + + try { + usersClient.authenticate("gluster", "gluster"); + } catch(Exception e) { + e.printStackTrace(); } + + ClustersClient client = new ClustersClient(); + client.setSecurityToken(usersClient.getSecurityToken()); + System.out.println(client.getClusterNames()); + try { + client.createCluster("test1"); + } catch (GlusterRuntimeException e) { + System.out.println(e.getMessage()); + } + + System.out.println(client.getClusterNames()); + + try { + client.deleteCluster("test1"); + } catch (GlusterRuntimeException e) { + System.out.println(e.getMessage()); + } + System.out.println(client.getClusterNames()); } } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java index f35c3e36..3704e2ff 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java @@ -68,12 +68,15 @@ public class DiscoveredServersClient extends AbstractClient { public static void main(String[] args) { UsersClient usersClient = new UsersClient(); - if (usersClient.authenticate("gluster", "gluster").isSuccess()) { + try { + usersClient.authenticate("gluster", "gluster"); DiscoveredServersClient serverResource = new DiscoveredServersClient(usersClient.getSecurityToken()); List discoveredServerNames = serverResource.getDiscoveredServerNames(); System.out.println(discoveredServerNames); List discoveredServers = serverResource.getDiscoveredServerDetails(); System.out.println(discoveredServers); + } catch(Exception e) { + e.printStackTrace(); } } } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index b525da01..b780e1c0 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -68,7 +68,8 @@ public class GlusterServersClient extends AbstractClient { public static void main(String[] args) { UsersClient usersClient = new UsersClient(); - if (usersClient.authenticate("gluster", "gluster").isSuccess()) { + try { + usersClient.authenticate("gluster", "gluster"); GlusterServersClient glusterServersClient = new GlusterServersClient(usersClient.getSecurityToken(), "cluster1"); List glusterServers = glusterServersClient.getServers(); for (GlusterServer server : glusterServers) { @@ -79,6 +80,8 @@ public class GlusterServersClient extends AbstractClient { Server srv = new Server(); srv.setName("server3"); glusterServersClient.addServer(srv); + } catch(Exception e) { + e.printStackTrace(); } } } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java index 84ed4e4c..522b87c1 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java @@ -22,6 +22,7 @@ import java.net.ConnectException; import javax.ws.rs.core.Response; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Status; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.representation.Form; @@ -40,60 +41,57 @@ public class UsersClient extends AbstractClient { super(); } - public Status authenticate(String user, String password) { + public void authenticate(String user, String password) { setSecurityToken(generateSecurityToken(user, password)); try { - Status authStatus = (Status) fetchSubResource(user, Status.class); - if (!authStatus.isSuccess()) { - // authentication failed. clear security token. - setSecurityToken(null); - } - return authStatus; - } catch (UniformInterfaceException e) { - if ((e.getResponse().getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) { - // authentication failed. clear security token. - setSecurityToken(null); - return new Status(Status.STATUS_CODE_FAILURE, "Invalid user id or password!"); - } else { + fetchSubResource(user, String.class); + } catch (RuntimeException e) { + Throwable cause = e.getCause(); + if(cause == null) { throw e; } - } catch (Exception e) { - // authentication failed. clear security token. - setSecurityToken(null); - Throwable cause = e.getCause(); - if(cause != null && cause instanceof ConnectException) { - return new Status(Status.STATUS_CODE_FAILURE, "Couldn't connect to Gluster Management Gateway!"); + if (cause instanceof UniformInterfaceException) { + UniformInterfaceException e1 = (UniformInterfaceException) cause; + if ((e1.getResponse().getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) { + // authentication failed. clear security token. + setSecurityToken(null); + throw new GlusterRuntimeException("Invalid user id or password!"); + } else { + // TODO: Log the exception + throw new GlusterRuntimeException("Exception during authentication: [" + + e1.getResponse().getStatus() + "]"); + } + } else if(cause instanceof ConnectException) { + throw new GlusterRuntimeException("Couldn't connect to Gluster Management Gateway!"); + } else { + throw new GlusterRuntimeException("Exception during authentication: [" + e.getMessage() + "]"); } - return new Status(Status.STATUS_CODE_FAILURE, "Exception during authentication: [" + e.getMessage() + "]"); } } - public boolean changePassword(String user, String oldPassword, String newPassword) { + public void changePassword(String user, String oldPassword, String newPassword) { setSecurityToken(generateSecurityToken(user, oldPassword)); Form form = new Form(); form.add(FORM_PARAM_OLD_PASSWORD, oldPassword); form.add(FORM_PARAM_NEW_PASSWORD, newPassword); - try { - putRequest(user, form); - return true; - } catch (Exception e) { - return false; - } + putRequest(user, form); } public static void main(String[] args) { UsersClient authClient = new UsersClient(); // authenticate user - System.out.println(authClient.authenticate("gluster", "gluster")); + authClient.authenticate("gluster", "gluster"); // change password to gluster1 - System.out.println(authClient.changePassword("gluster", "gluster", "gluster1")); + authClient.changePassword("gluster", "gluster", "gluster1"); // change it back to gluster - System.out.println(authClient.changePassword("gluster", "gluster1", "gluster")); + authClient.changePassword("gluster", "gluster1", "gluster"); + + System.out.println("success"); } /* diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index d237f010..c04389d1 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -232,10 +232,13 @@ public class VolumesClient extends AbstractClient { public static void main(String[] args) { UsersClient usersClient = new UsersClient(); - if (usersClient.authenticate("gluster", "gluster").isSuccess()) { + try { + usersClient.authenticate("gluster", "gluster"); VolumesClient client = new VolumesClient(usersClient.getSecurityToken()); System.out.println(client.getAllVolumes()); // client.downloadLogs("vol1", "/tmp/temp1.tar.gz"); + } catch(Exception e) { + e.printStackTrace(); } } } 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 b3dc30c2..fa266b50 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 @@ -25,6 +25,7 @@ package com.gluster.storage.management.core.constants; */ public class RESTConstants { // REST Resource paths + public static final String RESOURCE_PATH_USERS = "/users"; public static final String RESOURCE_PATH_CLUSTERS = "/clusters"; public static final String RESOURCE_PATH_DISCOVERED_SERVERS = "/discoveredservers"; @@ -72,6 +73,7 @@ public class RESTConstants { public static final String PATH_PARAM_CLUSTER_NAME = "clusterName"; public static final String PATH_PARAM_SERVER_NAME = "serverName"; public static final String PATH_PARAM_TASK_ID = "taskId"; + public static final String PATH_PARAM_USER = "user"; public static final String QUERY_PARAM_BRICK_NAME = "brickName"; public static final String QUERY_PARAM_DISKS = "disks"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 563e6416..5cdb2648 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -199,56 +199,60 @@ public class LoginDialog extends Dialog { String password = connectionDetails.getPassword(); UsersClient usersClient = new UsersClient(); - Status loginStatus = usersClient.authenticate(user, password); - if (loginStatus.isSuccess()) { - // authentication successful. close the login dialog and open the next one. - close(); - - ClustersClient clustersClient = new ClustersClient(usersClient.getSecurityToken()); - - IEclipsePreferences preferences = new ConfigurationScope().getNode(Application.PLUGIN_ID); - boolean showClusterSelectionDialog = preferences.getBoolean(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); - - String clusterName = null; - if(!showClusterSelectionDialog) { - clusterName = preferences.get(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, null); - if(clusterName == null || clusterName.isEmpty()) { - // Cluster name not available in preferences. Hence we must show the cluster selection dialog. - showClusterSelectionDialog = true; - } - } - - CLUSTER_MODE mode; - String serverName = null; - - if (showClusterSelectionDialog) { - ClusterSelectionDialog clusterDialog = new ClusterSelectionDialog(getParentShell(), - clustersClient.getClusterNames()); - int userAction = clusterDialog.open(); - if (userAction == Window.CANCEL) { - MessageDialog.openError(getShell(), "Login Cancelled", - "User cancelled login at cluster selection. Application will close!"); - cancelPressed(); - return; - } - mode = clusterDialog.getClusterMode(); - clusterName = clusterDialog.getClusterName(); - serverName = clusterDialog.getServerName(); - } else { - mode = CLUSTER_MODE.SELECT; + try { + usersClient.authenticate(user, password); + } catch(Exception e) { + MessageDialog.openError(getShell(), "Authentication Failed", e.getMessage()); + setReturnCode(RETURN_CODE_ERROR); + return; + } + + // authentication successful. close the login dialog and open the next one. + close(); + + ClustersClient clustersClient = new ClustersClient(usersClient.getSecurityToken()); + + IEclipsePreferences preferences = new ConfigurationScope().getNode(Application.PLUGIN_ID); + boolean showClusterSelectionDialog = preferences.getBoolean( + PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); + + String clusterName = null; + if (!showClusterSelectionDialog) { + clusterName = preferences.get(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, null); + if (clusterName == null || clusterName.isEmpty()) { + // Cluster name not available in preferences. Hence we must show the cluster selection dialog. + showClusterSelectionDialog = true; } - - try { - createOrRegisterCluster(clustersClient, clusterName, serverName, mode); - GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken(), clusterName); - super.okPressed(); - } catch (Exception e) { - setReturnCode(RETURN_CODE_ERROR); - MessageDialog.openError(getShell(), "Initialization Error", e.getMessage()); - close(); + } + + CLUSTER_MODE mode; + String serverName = null; + + if (showClusterSelectionDialog) { + ClusterSelectionDialog clusterDialog = new ClusterSelectionDialog(getParentShell(), + clustersClient.getClusterNames()); + int userAction = clusterDialog.open(); + if (userAction == Window.CANCEL) { + MessageDialog.openError(getShell(), "Login Cancelled", + "User cancelled login at cluster selection. Application will close!"); + cancelPressed(); + return; } + mode = clusterDialog.getClusterMode(); + clusterName = clusterDialog.getClusterName(); + serverName = clusterDialog.getServerName(); } else { - MessageDialog.openError(getShell(), "Authentication Failed", loginStatus.getMessage()); + mode = CLUSTER_MODE.SELECT; + } + + try { + createOrRegisterCluster(clustersClient, clusterName, serverName, mode); + GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken(), clusterName); + super.okPressed(); + } catch (Exception e) { + setReturnCode(RETURN_CODE_ERROR); + MessageDialog.openError(getShell(), "Initialization Error", e.getMessage()); + close(); } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java index ee65add0..4523ff75 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java @@ -123,6 +123,15 @@ public class AbstractResource { protected Response badRequestResponse(String errMessage) { return Response.status(Status.BAD_REQUEST).type(MediaType.TEXT_HTML).entity(errMessage).build(); } + + /** + * Creates a response with HTTP status code of 401 (unauthorized) + * + * @return the {@link Response} object + */ + protected Response unauthorizedResponse() { + return Response.status(Status.UNAUTHORIZED).build(); + } /** * Creates an OK response and sets the entity in the response body. @@ -137,6 +146,17 @@ public class AbstractResource { return Response.ok(entity).type(mediaType).build(); } + /** + * Creates an OK response without any entity in the response body. + * + * @param mediaType + * Media type to be set on the response + * @return the {@link Response} object + */ + protected Response okResponse(String mediaType) { + return Response.ok().type(mediaType).build(); + } + /** * Creates a streaming output response and sets the given streaming output in the response. Typically used for * "download" requests diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java index 0326793b..1b1f0d72 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java @@ -18,6 +18,9 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources; +import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_USER; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_USERS; + import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.PUT; @@ -25,6 +28,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.encoding.PasswordEncoder; @@ -38,55 +42,48 @@ import com.sun.jersey.spi.resource.Singleton; @Singleton @Component -@Path("/users") -public class UsersResource { +@Path(RESOURCE_PATH_USERS) +public class UsersResource extends AbstractResource { @Autowired private JdbcUserDetailsManager jdbcUserService; @Autowired private PasswordEncoder passwordEncoder; - /** - * Authenticates given user with given password for login on current system - * - * @param user - * @param password - * @return true is user can be successfully authenticated using given password, else false - */ - /* - * NOTE: This method is no more required as user authentication is performed on every request by the spring security - * framework. Can be removed after testing. - */ - /* - * private boolean authenticate(String user, String password) { String tmpFileName = "tmp"; File saltFile = new - * File(tmpFileName); ProcessResult result = new ProcessUtil().executeCommand("get-user-password.py", user, - * tmpFileName); if (result.isSuccess()) { String salt = new FileUtil().readFileAsString(saltFile); String - * encryptedPassword = MD5Crypt.crypt(password, salt); return encryptedPassword.equals(salt); } - * - * return false; } - */ - - @Path("{user}") + @Path("{" + PATH_PARAM_USER + "}") @GET @Produces(MediaType.APPLICATION_XML) - public Status authenticate(@PathParam("user") String user) { + public Response authenticateXML(@PathParam("user") String user) { + // success only if the user passed in query is same as the one passed in security header + // spring security would have already authenticated the user credentials + return getAuthenticationResponse(user, MediaType.APPLICATION_XML); + } + + @Path("{" + PATH_PARAM_USER + "}") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response authenticateJSON(@PathParam("user") String user) { // success only if the user passed in query is same as the one passed in security header // spring security would have already authenticated the user credentials - return (SecurityContextHolder.getContext().getAuthentication().getName().equals(user) ? Status.STATUS_SUCCESS - : Status.STATUS_FAILURE); + return getAuthenticationResponse(user, MediaType.APPLICATION_JSON); } - @Path("{user}") + public Response getAuthenticationResponse(String user, String mediaType) { + return (SecurityContextHolder.getContext().getAuthentication().getName().equals(user) ? okResponse(mediaType) + : unauthorizedResponse()); + } + + @Path("{" + PATH_PARAM_USER + "}") @PUT - @Produces(MediaType.APPLICATION_XML) - public Status changePassword(@FormParam("oldpassword") String oldPassword, + public Response changePassword(@FormParam("oldpassword") String oldPassword, @FormParam("newpassword") String newPassword) { try { jdbcUserService.changePassword(oldPassword, passwordEncoder.encodePassword(newPassword, null)); - } catch (AuthenticationException ex) { + } catch (Exception ex) { + // TODO: Log the exception ex.printStackTrace(); - return new Status(Status.STATUS_CODE_FAILURE, "Could not change password: [" + ex.getMessage() + "]"); + return errorResponse("Could not change password. Error: [" + ex.getMessage() + "]"); } - return Status.STATUS_SUCCESS; + return noContentResponse(); } } -- cgit From 7b0de6dc33bcd979058ebeb7e3d04b477edc338e Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 23 Jun 2011 14:22:26 +0530 Subject: Story #23: Initialize Disk --- .../storage/management/server/resources/GlusterServersResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') 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 ef2a862e..1999762a 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 @@ -25,6 +25,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.PATH_P import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; import java.util.ArrayList; import java.util.List; @@ -440,7 +441,7 @@ public class GlusterServersResource extends AbstractServersResource { @PUT @Produces(MediaType.APPLICATION_XML) - @Path("{" + PATH_PARAM_SERVER_NAME + "}") + @Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_DISKS + "/{" + PATH_PARAM_DISK_NAME + "}") public Response initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName, @PathParam(PATH_PARAM_DISK_NAME) String diskName) { -- cgit From df849286f545647b50f9afcc4bba731848df3b0a Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 24 Jun 2011 19:49:55 +0530 Subject: Introduced preference store --- .../gui/dialogs/ClusterSelectionDialog.java | 50 ++++++++++++++++++++++ .../management/gui/dialogs/LoginDialog.java | 13 +++--- .../gui/preferences/GlusterPreferencePage.java | 43 +++++++++++-------- .../gui/preferences/PreferenceConstants.java | 1 + .../gui/preferences/PreferenceInitializer.java | 7 +-- .../management/server/resources/UsersResource.java | 2 - .../server/resources/VolumesResource.java | 9 ++-- .../storage/management/server/utils/SshUtil.java | 4 +- 8 files changed, 92 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java index 342c72e6..82df0c46 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java @@ -20,9 +20,12 @@ package com.gluster.storage.management.gui.dialogs; import java.util.List; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.ModifyEvent; @@ -40,8 +43,14 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.osgi.service.prefs.BackingStoreException; +import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.gui.Activator; +import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.preferences.PreferenceConstants; import com.gluster.storage.management.gui.utils.GUIHelper; /** @@ -73,10 +82,13 @@ public class ClusterSelectionDialog extends Dialog { private String clusterName; private CLUSTER_MODE clusterMode; private String serverName; + private Button dontAskAgainButton; + IPreferenceStore preferenceStore; public ClusterSelectionDialog(Shell parentShell, List clusters) { super(parentShell); this.clusters = clusters; + preferenceStore = Activator.getDefault().getPreferenceStore(); } @Override @@ -109,6 +121,20 @@ public class ClusterSelectionDialog extends Dialog { clusterNameCombo = new Combo(composite, SWT.READ_ONLY); clusterNameCombo.setItems(clusters.toArray(new String[0])); clusterNameCombo.select(0); + + String clusterName = preferenceStore.getString(PreferenceConstants.P_DEFAULT_CLUSTER_NAME); + if(clusterName != null && !clusterName.isEmpty()) { + selectCluster(clusterName); + } + } + + public void selectCluster(String clusterName) { + for(int i = 0; i < clusters.size(); i++) { + if(clusterNameCombo.getItem(i).equals(clusterName)) { + clusterNameCombo.select(i); + break; + } + } } private void configureDialogLayout(Composite composite) { @@ -231,9 +257,26 @@ public class ClusterSelectionDialog extends Dialog { clusterSelectionComposite.setLayout(layout); createClusterNameLabel(clusterSelectionComposite); createClusterNameCombo(clusterSelectionComposite); + + createPreferenceCheckboxes(clusterSelectionComposite); + stackLayout.topControl = clusterSelectionComposite; } + private void createPreferenceCheckboxes(Composite composite) { + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + layoutData.verticalIndent = 5; + layoutData.horizontalSpan = 2; + + dontAskAgainButton = new Button(composite, SWT.CHECK); + dontAskAgainButton.setLayoutData(layoutData); + dontAskAgainButton.setText("&Don't ask again"); + dontAskAgainButton.setEnabled(true); + dontAskAgainButton.setSelection(false); + dontAskAgainButton.setToolTipText("Always manage the selected cluster without showing this dialog box." + + "This preference can later be changed from the \"Settings\" menu."); + } + private void createRadioButtons() { { if (clusters.size() > 0) { @@ -371,6 +414,13 @@ public class ClusterSelectionDialog extends Dialog { if(selectButton != null && selectButton.getSelection()) { clusterMode = CLUSTER_MODE.SELECT; clusterName = clusterNameCombo.getText(); + + if(dontAskAgainButton.getSelection()) { + preferenceStore.setValue(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, false); + preferenceStore.setValue(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, clusterName); + } else { + preferenceStore.setValue(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); + } } else if(createButton.getSelection()) { clusterMode = CLUSTER_MODE.CREATE; clusterName = newClusterNameText.getText().trim(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 5cdb2648..c23a96c5 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -28,6 +28,7 @@ import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.TraverseEvent; @@ -47,6 +48,7 @@ import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.UsersClient; import com.gluster.storage.management.core.model.ConnectionDetails; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.gui.Activator; import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.dialogs.ClusterSelectionDialog.CLUSTER_MODE; @@ -212,20 +214,21 @@ public class LoginDialog extends Dialog { ClustersClient clustersClient = new ClustersClient(usersClient.getSecurityToken()); - IEclipsePreferences preferences = new ConfigurationScope().getNode(Application.PLUGIN_ID); - boolean showClusterSelectionDialog = preferences.getBoolean( - PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + boolean showClusterSelectionDialog = preferenceStore.getBoolean(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG); + CLUSTER_MODE mode; String clusterName = null; if (!showClusterSelectionDialog) { - clusterName = preferences.get(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, null); + clusterName = preferenceStore.getString(PreferenceConstants.P_DEFAULT_CLUSTER_NAME); if (clusterName == null || clusterName.isEmpty()) { // Cluster name not available in preferences. Hence we must show the cluster selection dialog. showClusterSelectionDialog = true; + } else { + mode = CLUSTER_MODE.SELECT; } } - CLUSTER_MODE mode; String serverName = null; if (showClusterSelectionDialog) { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java index 23b2cff2..3090b278 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java @@ -18,10 +18,16 @@ *******************************************************************************/ package com.gluster.storage.management.gui.preferences; -import org.eclipse.jface.preference.*; -import org.eclipse.ui.IWorkbenchPreferencePage; +import java.util.List; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import com.gluster.storage.management.client.ClustersClient; import com.gluster.storage.management.gui.Activator; /** @@ -37,15 +43,16 @@ import com.gluster.storage.management.gui.Activator; * the main plug-in class. That way, preferences can * be accessed directly via the preference store. */ - public class GlusterPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private List clusterNames; public GlusterPreferencePage() { super(GRID); setPreferenceStore(Activator.getDefault().getPreferenceStore()); - setDescription("A demonstration of a preference page implementation"); + setDescription("Gluster Management Console"); } /** @@ -55,29 +62,29 @@ public class GlusterPreferencePage * restore itself. */ public void createFieldEditors() { - addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, - "&Directory preference:", getFieldEditorParent())); addField( new BooleanFieldEditor( - PreferenceConstants.P_BOOLEAN, - "&An example of a boolean preference", + PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, + "&Show Cluster Selection Dialog on Login:", getFieldEditorParent())); + + String[][] clusterNamesArr = new String[clusterNames.size()][clusterNames.size()]; + for(int i = 0; i < clusterNames.size(); i++) { + String clusterName = clusterNames.get(i);; + clusterNamesArr[i][0] = clusterName; + clusterNamesArr[i][1] = clusterName; + } - addField(new RadioGroupFieldEditor( - PreferenceConstants.P_CHOICE, - "An example of a multiple-choice preference", - 1, - new String[][] { { "&Choice 1", "choice1" }, { - "C&hoice 2", "choice2" } - }, getFieldEditorParent())); - addField( - new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); + addField(new ComboFieldEditor(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, "Default &Cluster to manage:", + clusterNamesArr, getFieldEditorParent())); + addField(new IntegerFieldEditor(PreferenceConstants.P_DATA_REFRESH_INTERVAL, "&Data Refresh Interval:", + getFieldEditorParent())); } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) */ public void init(IWorkbench workbench) { + clusterNames = new ClustersClient().getClusterNames(); } - } \ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java index 8b5a8cfd..260aadb6 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java @@ -25,6 +25,7 @@ public class PreferenceConstants { public static final String P_SHOW_CLUSTER_SELECTION_DIALOG = "show.cluster.selection.dialog"; public static final String P_DEFAULT_CLUSTER_NAME = "default.cluster.name"; + public static final String P_DATA_REFRESH_INTERVAL = "data.refresh.interval"; // TODO: Remove after proper preferences are added public static final String P_PATH = "pathPreference"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java index 74ace130..1a4104ac 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java @@ -35,10 +35,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { */ public void initializeDefaultPreferences() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); - store.setDefault(PreferenceConstants.P_BOOLEAN, true); - store.setDefault(PreferenceConstants.P_CHOICE, "choice2"); - store.setDefault(PreferenceConstants.P_STRING, - "Default value"); + + store.setDefault(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); } - } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java index 1b1f0d72..0ccb4263 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java @@ -32,12 +32,10 @@ import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.encoding.PasswordEncoder; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.stereotype.Component; -import com.gluster.storage.management.core.model.Status; import com.sun.jersey.spi.resource.Singleton; @Singleton diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 5d1f38e9..c7e18aaa 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -23,8 +23,9 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_ACCESS_PROTOCOLS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_AUTO_COMMIT; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_KEY; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_VALUE; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_REPLICA_COUNT; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SOURCE; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_STRIPE_COUNT; @@ -33,7 +34,6 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_TYPE; -import static com.gluster.storage.management.core.constants.RESTConstants.*; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS; @@ -44,13 +44,13 @@ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_LINE_COUNT; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_LOG_SEVERITY; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TO_TIMESTAMP; -import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_BRICKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DEFAULT_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DOWNLOAD; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_LOGS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP; @@ -91,15 +91,12 @@ import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.LogMessageListResponse; -import com.gluster.storage.management.core.response.TaskResponse; import com.gluster.storage.management.core.response.VolumeListResponse; import com.gluster.storage.management.core.response.VolumeOptionInfoListResponse; import com.gluster.storage.management.core.utils.DateUtil; import com.gluster.storage.management.core.utils.FileUtil; -import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; -import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.ServerUtil; diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index 5f8b88f6..d15142e6 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -259,7 +259,9 @@ public class SshUtil { // Wait for program to come out either // a) gracefully with an exit status, OR // b) because of a termination signal - int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS, 5000); + // c) command takes to long to exit (timeout) + int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS + | ChannelCondition.TIMEOUT, 5000); StringBuilder output = new StringBuilder(); try { -- cgit From 724d32f78992490e107af147c82cba616d9ddf15 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 24 Jun 2011 19:49:55 +0530 Subject: Introduced preference store --- .../gui/dialogs/ClusterSelectionDialog.java | 50 ++++++++++++++++++++++ .../management/gui/dialogs/LoginDialog.java | 13 +++--- .../gui/preferences/GlusterPreferencePage.java | 43 +++++++++++-------- .../gui/preferences/PreferenceConstants.java | 1 + .../gui/preferences/PreferenceInitializer.java | 7 +-- .../management/server/resources/UsersResource.java | 2 - .../server/resources/VolumesResource.java | 9 ++-- .../storage/management/server/utils/SshUtil.java | 4 +- 8 files changed, 92 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java index 342c72e6..82df0c46 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java @@ -20,9 +20,12 @@ package com.gluster.storage.management.gui.dialogs; import java.util.List; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.ModifyEvent; @@ -40,8 +43,14 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import org.osgi.service.prefs.BackingStoreException; +import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.gui.Activator; +import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.preferences.PreferenceConstants; import com.gluster.storage.management.gui.utils.GUIHelper; /** @@ -73,10 +82,13 @@ public class ClusterSelectionDialog extends Dialog { private String clusterName; private CLUSTER_MODE clusterMode; private String serverName; + private Button dontAskAgainButton; + IPreferenceStore preferenceStore; public ClusterSelectionDialog(Shell parentShell, List clusters) { super(parentShell); this.clusters = clusters; + preferenceStore = Activator.getDefault().getPreferenceStore(); } @Override @@ -109,6 +121,20 @@ public class ClusterSelectionDialog extends Dialog { clusterNameCombo = new Combo(composite, SWT.READ_ONLY); clusterNameCombo.setItems(clusters.toArray(new String[0])); clusterNameCombo.select(0); + + String clusterName = preferenceStore.getString(PreferenceConstants.P_DEFAULT_CLUSTER_NAME); + if(clusterName != null && !clusterName.isEmpty()) { + selectCluster(clusterName); + } + } + + public void selectCluster(String clusterName) { + for(int i = 0; i < clusters.size(); i++) { + if(clusterNameCombo.getItem(i).equals(clusterName)) { + clusterNameCombo.select(i); + break; + } + } } private void configureDialogLayout(Composite composite) { @@ -231,9 +257,26 @@ public class ClusterSelectionDialog extends Dialog { clusterSelectionComposite.setLayout(layout); createClusterNameLabel(clusterSelectionComposite); createClusterNameCombo(clusterSelectionComposite); + + createPreferenceCheckboxes(clusterSelectionComposite); + stackLayout.topControl = clusterSelectionComposite; } + private void createPreferenceCheckboxes(Composite composite) { + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + layoutData.verticalIndent = 5; + layoutData.horizontalSpan = 2; + + dontAskAgainButton = new Button(composite, SWT.CHECK); + dontAskAgainButton.setLayoutData(layoutData); + dontAskAgainButton.setText("&Don't ask again"); + dontAskAgainButton.setEnabled(true); + dontAskAgainButton.setSelection(false); + dontAskAgainButton.setToolTipText("Always manage the selected cluster without showing this dialog box." + + "This preference can later be changed from the \"Settings\" menu."); + } + private void createRadioButtons() { { if (clusters.size() > 0) { @@ -371,6 +414,13 @@ public class ClusterSelectionDialog extends Dialog { if(selectButton != null && selectButton.getSelection()) { clusterMode = CLUSTER_MODE.SELECT; clusterName = clusterNameCombo.getText(); + + if(dontAskAgainButton.getSelection()) { + preferenceStore.setValue(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, false); + preferenceStore.setValue(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, clusterName); + } else { + preferenceStore.setValue(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); + } } else if(createButton.getSelection()) { clusterMode = CLUSTER_MODE.CREATE; clusterName = newClusterNameText.getText().trim(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 5cdb2648..c23a96c5 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -28,6 +28,7 @@ import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.TraverseEvent; @@ -47,6 +48,7 @@ import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.UsersClient; import com.gluster.storage.management.core.model.ConnectionDetails; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.gui.Activator; import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.dialogs.ClusterSelectionDialog.CLUSTER_MODE; @@ -212,20 +214,21 @@ public class LoginDialog extends Dialog { ClustersClient clustersClient = new ClustersClient(usersClient.getSecurityToken()); - IEclipsePreferences preferences = new ConfigurationScope().getNode(Application.PLUGIN_ID); - boolean showClusterSelectionDialog = preferences.getBoolean( - PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + boolean showClusterSelectionDialog = preferenceStore.getBoolean(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG); + CLUSTER_MODE mode; String clusterName = null; if (!showClusterSelectionDialog) { - clusterName = preferences.get(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, null); + clusterName = preferenceStore.getString(PreferenceConstants.P_DEFAULT_CLUSTER_NAME); if (clusterName == null || clusterName.isEmpty()) { // Cluster name not available in preferences. Hence we must show the cluster selection dialog. showClusterSelectionDialog = true; + } else { + mode = CLUSTER_MODE.SELECT; } } - CLUSTER_MODE mode; String serverName = null; if (showClusterSelectionDialog) { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java index 23b2cff2..c88d6e98 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java @@ -18,10 +18,16 @@ *******************************************************************************/ package com.gluster.storage.management.gui.preferences; -import org.eclipse.jface.preference.*; -import org.eclipse.ui.IWorkbenchPreferencePage; +import java.util.List; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import com.gluster.storage.management.client.ClustersClient; import com.gluster.storage.management.gui.Activator; /** @@ -37,15 +43,16 @@ import com.gluster.storage.management.gui.Activator; * the main plug-in class. That way, preferences can * be accessed directly via the preference store. */ - public class GlusterPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private List clusterNames; public GlusterPreferencePage() { super(GRID); setPreferenceStore(Activator.getDefault().getPreferenceStore()); - setDescription("A demonstration of a preference page implementation"); + setDescription("Gluster Management Console"); } /** @@ -55,29 +62,29 @@ public class GlusterPreferencePage * restore itself. */ public void createFieldEditors() { - addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, - "&Directory preference:", getFieldEditorParent())); addField( new BooleanFieldEditor( - PreferenceConstants.P_BOOLEAN, - "&An example of a boolean preference", + PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, + "&Show Cluster Selection Dialog on Login:", getFieldEditorParent())); + + String[][] clusterNamesArr = new String[clusterNames.size()][2]; + for(int i = 0; i < clusterNames.size(); i++) { + String clusterName = clusterNames.get(i);; + clusterNamesArr[i][0] = clusterName; + clusterNamesArr[i][1] = clusterName; + } - addField(new RadioGroupFieldEditor( - PreferenceConstants.P_CHOICE, - "An example of a multiple-choice preference", - 1, - new String[][] { { "&Choice 1", "choice1" }, { - "C&hoice 2", "choice2" } - }, getFieldEditorParent())); - addField( - new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); + addField(new ComboFieldEditor(PreferenceConstants.P_DEFAULT_CLUSTER_NAME, "Default &Cluster to manage:", + clusterNamesArr, getFieldEditorParent())); + addField(new IntegerFieldEditor(PreferenceConstants.P_DATA_REFRESH_INTERVAL, "&Data Refresh Interval:", + getFieldEditorParent())); } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) */ public void init(IWorkbench workbench) { + clusterNames = new ClustersClient().getClusterNames(); } - } \ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java index 8b5a8cfd..260aadb6 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java @@ -25,6 +25,7 @@ public class PreferenceConstants { public static final String P_SHOW_CLUSTER_SELECTION_DIALOG = "show.cluster.selection.dialog"; public static final String P_DEFAULT_CLUSTER_NAME = "default.cluster.name"; + public static final String P_DATA_REFRESH_INTERVAL = "data.refresh.interval"; // TODO: Remove after proper preferences are added public static final String P_PATH = "pathPreference"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java index 74ace130..1a4104ac 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java @@ -35,10 +35,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { */ public void initializeDefaultPreferences() { IPreferenceStore store = Activator.getDefault().getPreferenceStore(); - store.setDefault(PreferenceConstants.P_BOOLEAN, true); - store.setDefault(PreferenceConstants.P_CHOICE, "choice2"); - store.setDefault(PreferenceConstants.P_STRING, - "Default value"); + + store.setDefault(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG, true); } - } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java index 1b1f0d72..0ccb4263 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java @@ -32,12 +32,10 @@ import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.encoding.PasswordEncoder; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.provisioning.JdbcUserDetailsManager; import org.springframework.stereotype.Component; -import com.gluster.storage.management.core.model.Status; import com.sun.jersey.spi.resource.Singleton; @Singleton diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 5d1f38e9..c7e18aaa 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -23,8 +23,9 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_ACCESS_PROTOCOLS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_AUTO_COMMIT; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_KEY; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_VALUE; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_REPLICA_COUNT; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SOURCE; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_STRIPE_COUNT; @@ -33,7 +34,6 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_VOLUME_TYPE; -import static com.gluster.storage.management.core.constants.RESTConstants.*; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS; @@ -44,13 +44,13 @@ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_LINE_COUNT; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_LOG_SEVERITY; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TO_TIMESTAMP; -import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_BRICKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DEFAULT_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DOWNLOAD; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_LOGS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_OPTIONS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP; @@ -91,15 +91,12 @@ import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.response.LogMessageListResponse; -import com.gluster.storage.management.core.response.TaskResponse; import com.gluster.storage.management.core.response.VolumeListResponse; import com.gluster.storage.management.core.response.VolumeOptionInfoListResponse; import com.gluster.storage.management.core.utils.DateUtil; import com.gluster.storage.management.core.utils.FileUtil; -import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; -import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.ServerUtil; diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index 5f8b88f6..d15142e6 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -259,7 +259,9 @@ public class SshUtil { // Wait for program to come out either // a) gracefully with an exit status, OR // b) because of a termination signal - int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS, 5000); + // c) command takes to long to exit (timeout) + int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS + | ChannelCondition.TIMEOUT, 5000); StringBuilder output = new StringBuilder(); try { -- cgit From dbfc04a1dc1bbd998302b7cec914008c3e9d1bd8 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 27 Jun 2011 15:58:57 +0530 Subject: Introduced method notFoundResponse to create 404 response from a resource. --- .../storage/management/server/resources/AbstractResource.java | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java index 4523ff75..6bc394c3 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java @@ -73,6 +73,17 @@ public class AbstractResource { return Response.status(Status.ACCEPTED).location(createAbsoluteURI(uriElements)).build(); } + /** + * Creates a response with HTTP status code of 404 (not found), also setting the given message in the response body + * + * @param message + * Message to be set in the response body + * @return the {@link Response} object + */ + protected Response notFoundResponse(String message) { + return Response.status(Status.NOT_FOUND).type(MediaType.TEXT_HTML).entity(message).build(); + } + /** * Creates a new URI that is relative to the base URI of the application * @param uriElements URI Elements to be appended to the base URI -- cgit From b51fce37009145f91f0345b428eb297ad4691563 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Mon, 27 Jun 2011 16:21:16 +0530 Subject: Story #1: Rebalance Volume --- .../storage/management/client/VolumesClient.java | 9 ++ .../management/core/constants/RESTConstants.java | 4 + .../gui/actions/RebalanceVolumeAction.java | 37 +++++- .../server/resources/VolumesResource.java | 132 ++++++++++++++------- .../server/tasks/RebalanceVolumeTask.java | 103 ++++++++++++++++ .../management/server/utils/GlusterUtil.java | 15 +++ 6 files changed, 255 insertions(+), 45 deletions(-) create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index c04389d1..338caf89 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -229,6 +229,15 @@ public class VolumesClient extends AbstractClient { putRequest(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); } + + public void rebalanceVolume(String volumeName, boolean fixLayout, boolean migrateData, boolean forcedDataMigrate) { + Form form = new Form(); + form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_REBALANCE_START); + form.add(RESTConstants.FORM_PARAM_FIX_LAYOUT, fixLayout); + form.add(RESTConstants.FORM_PARAM_MIGRATE_DATA, migrateData); + form.add(RESTConstants.FORM_PARAM_FORCED_DATA_MIGRATE, forcedDataMigrate); + putRequest(volumeName, form); + } public static void main(String[] args) { UsersClient usersClient = new UsersClient(); 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..16f5d7b5 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 @@ -47,6 +47,7 @@ public class RESTConstants { public static final String TASK_STOP = "stop"; public static final String TASK_STATUS = "status"; public static final String TASK_DELETE = "delete"; + public static final String TASK_REBALANCE_START = "rebalanceStart"; public static final String FORM_PARAM_VOLUME_NAME = "name"; public static final String FORM_PARAM_VOLUME_TYPE = "volumeType"; @@ -67,6 +68,9 @@ public class RESTConstants { public static final String FORM_PARAM_SOURCE = "source"; public static final String FORM_PARAM_TARGET = "target"; public static final String FORM_PARAM_AUTO_COMMIT = "autoCommit"; + public static final String FORM_PARAM_FIX_LAYOUT = "fix-layout"; + public static final String FORM_PARAM_MIGRATE_DATA = "migrate-data"; + public static final String FORM_PARAM_FORCED_DATA_MIGRATE = "forced-data-migrate"; public static final String PATH_PARAM_FORMAT = "format"; public static final String PATH_PARAM_VOLUME_NAME = "volumeName"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java index 5339beb0..9b55e70a 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java @@ -19,11 +19,44 @@ 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.VolumesClient; +import com.gluster.storage.management.core.model.Volume; public class RebalanceVolumeAction extends AbstractActionDelegate { + private Volume volume; + + @Override + protected void performAction(final IAction action) { + + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + final String actionDesc = action.getDescription(); + try { + new VolumesClient().rebalanceVolume(volume.getName(), false, false, false); + showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] rebalance started successfully!"); + } catch (Exception e) { + showErrorDialog(actionDesc, + "Volume rebalance cannot started on [" + volume.getName() + "]! Error: [" + e.getMessage() + "]"); + } + + } + }); + } + @Override - protected void performAction(IAction action) { - System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + action.setEnabled(false); + if (selectedEntity instanceof Volume) { + volume = (Volume) selectedEntity; + action.setEnabled(true); + } } @Override diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index c7e18aaa..d85cb006 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -54,6 +54,9 @@ import static com.gluster.storage.management.core.constants.RESTConstants.RESOUR import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FIX_LAYOUT; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_MIGRATE_DATA; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FORCED_DATA_MIGRATE; import java.io.File; import java.io.IOException; @@ -139,11 +142,11 @@ public class VolumesResource extends AbstractResource { public Response getVolumes(String clusterName, String mediaType) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } return okResponse(getVolumes(clusterName), mediaType); @@ -176,24 +179,24 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_BRICKS) String bricks, @FormParam(FORM_PARAM_ACCESS_PROTOCOLS) String accessProtocols, @FormParam(FORM_PARAM_VOLUME_OPTIONS) String options) { if(clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } String missingParam = checkMissingParamsForCreateVolume(volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options); if(missingParam != null) { - return badRequestResponse("Parameter [" + missingParam + "] is missing in request!"); + return notFoundResponse("Parameter [" + missingParam + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_MIRROR) && replicaCount <= 0) { - return badRequestResponse("Replica count must be a positive integer"); + return notFoundResponse("Replica count must be a positive integer"); } if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_STRIPE) && stripeCount <= 0) { - return badRequestResponse("Stripe count must be a positive integer"); + return notFoundResponse("Stripe count must be a positive integer"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -267,11 +270,11 @@ public class VolumesResource extends AbstractResource { Volume volume = null; if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } try { @@ -306,23 +309,30 @@ public class VolumesResource extends AbstractResource { @PUT @Path("{" + PATH_PARAM_VOLUME_NAME + "}") public Response performOperation(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, - @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_OPERATION) String operation) { + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_OPERATION) String operation, + @FormParam(FORM_PARAM_FIX_LAYOUT) Boolean isFixLayout, + @FormParam(FORM_PARAM_MIGRATE_DATA) Boolean isMigrateData, + @FormParam(FORM_PARAM_FORCED_DATA_MIGRATE) Boolean isForcedDataMigrate) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } + + if (operation.equals(RESTConstants.TASK_REBALANCE_START)) { + return rebalanceVolume(clusterName, volumeName, isFixLayout, isMigrateData, isForcedDataMigrate); + } try { performOperation(volumeName, operation, onlineServer); @@ -359,15 +369,15 @@ public class VolumesResource extends AbstractResource { @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_DELETE_OPTION) Boolean deleteFlag) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty"); + return notFoundResponse("Cluster name must not be empty"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty"); + return notFoundResponse("Volume name must not be empty"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } if (deleteFlag == null) { @@ -408,19 +418,19 @@ public class VolumesResource extends AbstractResource { List brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query // parameter) if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (bricks == null || bricks.isEmpty()) { - return badRequestResponse("Parameter [" + QUERY_PARAM_BRICKS + "] is missing in request!"); + return notFoundResponse("Parameter [" + QUERY_PARAM_BRICKS + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } if(deleteFlag == null) { @@ -511,23 +521,23 @@ public class VolumesResource extends AbstractResource { @FormParam(RESTConstants.FORM_PARAM_OPTION_KEY) String key, @FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if(volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if(key == null || key.isEmpty()) { - return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_KEY + "] is missing in request!"); + return notFoundResponse("Parameter [" + FORM_PARAM_OPTION_KEY + "] is missing in request!"); } if(value == null || value.isEmpty()) { - return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_VALUE + "] is missing in request!"); + return notFoundResponse("Parameter [" + FORM_PARAM_OPTION_VALUE + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -561,15 +571,15 @@ public class VolumesResource extends AbstractResource { public Response resetOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if(volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -654,15 +664,15 @@ public class VolumesResource extends AbstractResource { public Response downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } try { @@ -746,15 +756,15 @@ public class VolumesResource extends AbstractResource { public Response getLogs(String clusterName, String volumeName, String brickName, String severity, String fromTimestamp, String toTimestamp, Integer lineCount, String mediaType) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } List logMessages = null; @@ -847,19 +857,19 @@ public class VolumesResource extends AbstractResource { public Response addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_BRICKS) String bricks) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (bricks == null || bricks.isEmpty()) { - return badRequestResponse("Parameter [" + FORM_PARAM_BRICKS + "] is missing in request!"); + return notFoundResponse("Parameter [" + FORM_PARAM_BRICKS + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -896,23 +906,23 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_TARGET) String toBrick, @FormParam(FORM_PARAM_AUTO_COMMIT) Boolean autoCommit) { if (clusterName == null || clusterName.isEmpty()) { - return badRequestResponse("Cluster name must not be empty!"); + return notFoundResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return badRequestResponse("Volume name must not be empty!"); + return notFoundResponse("Volume name must not be empty!"); } if (fromBrick == null || fromBrick.isEmpty()) { - return badRequestResponse("Parameter [" + FORM_PARAM_SOURCE + "] is missing in request!"); + return notFoundResponse("Parameter [" + FORM_PARAM_SOURCE + "] is missing in request!"); } if (toBrick == null || toBrick.isEmpty()) { - return badRequestResponse("Parameter [" + FORM_PARAM_TARGET + "] is missing in request!"); + return notFoundResponse("Parameter [" + FORM_PARAM_TARGET + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -942,6 +952,42 @@ public class VolumesResource extends AbstractResource { return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); } + + private Response rebalanceVolume(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, + boolean isForcedDataMigrate) { + + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if (onlineServer == null) { + return errorResponse("No online servers found in cluster [" + clusterName + "]"); + } + + String layout = ""; + String taskId = null; + if (isForcedDataMigrate) { + layout = "forced-data-migrate = true"; + } else if (isMigrateData) { + layout = "migrate-data = true"; + } else if (isFixLayout) { + layout = "fix-layout = true"; + } + + try { + taskId = glusterUtil.rebalanceVolumeStart(volumeName, layout, onlineServer.getName()); + } catch (ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + + try { + taskId = glusterUtil.rebalanceVolumeStart(volumeName, layout, onlineServer.getName()); + } catch(Exception e1) { + return errorResponse(e1.getMessage()); + } + } catch(Exception e1) { + return errorResponse(e1.getMessage()); + } + + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + } public static void main(String[] args) throws ClassNotFoundException { VolumesResource vr = new VolumesResource(); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java new file mode 100644 index 00000000..697a40be --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java @@ -0,0 +1,103 @@ +/** + * RebalanceVolumeTask.java + * + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + */ +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.TaskStatus; +import com.gluster.storage.management.server.utils.SshUtil; + +public class RebalanceVolumeTask extends Task { + + private String layout; + private SshUtil sshUtil = new SshUtil(); + + public RebalanceVolumeTask(TaskInfo taskInfo) { + super(taskInfo); + } + + public RebalanceVolumeTask(String volumeName) { + super(TASK_TYPE.VOLUME_REBALANCE, volumeName); + setTaskDescription(); + getTaskInfo().setCanPause(false); + getTaskInfo().setCanStop(true); + } + + @Override + public String getId() { + return getTaskInfo().getId(); + } + + @Override + public TaskInfo start() { + getTaskInfo().setStatus( + new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " + + getTaskInfo().getReference() + " " + getLayout() + " start")))); + return getTaskInfo(); + } + + @Override + public TaskInfo resume() { + getTaskInfo().setStatus( + new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Can not suspend volume rebalance"))); + return getTaskInfo(); + } + + @Override + public TaskInfo stop() { + getTaskInfo().setStatus( + new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " + + getTaskInfo().getReference() + " stop")))); + return getTaskInfo(); + } + + @Override + public TaskInfo pause() { + getTaskInfo().setStatus( + new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Can not pause volume rebalance"))); + return getTaskInfo(); + } + + @Override + public TaskInfo status() { + getTaskInfo().setStatus( + new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " + + getTaskInfo().getReference() + " status")))); + return getTaskInfo(); + } + + @Override + public void setTaskDescription() { + TaskInfo taskInfo = getTaskInfo(); + getTaskInfo().setDescription("Volume rebalance running on " + taskInfo.getReference()); + + } + + public void setLayout(String layout) { + this.layout = layout; + } + + public String getLayout() { + return layout; + } + +} 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..970e1c65 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 @@ -47,6 +47,7 @@ import com.gluster.storage.management.core.utils.ProcessResult; import com.gluster.storage.management.core.utils.StringUtil; import com.gluster.storage.management.server.resources.TasksResource; import com.gluster.storage.management.server.tasks.MigrateDiskTask; +import com.gluster.storage.management.server.tasks.RebalanceVolumeTask; import com.sun.jersey.api.core.InjectParam; @Component @@ -550,6 +551,20 @@ public class GlusterUtil { return taskInfo.getId(); } + + public String rebalanceVolumeStart(String volumeName, String layout, String knownServer) { + + RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); + rebalanceTask.setOnlineServer(knownServer); + rebalanceTask.setLayout(layout); + + TaskInfo taskInfo = rebalanceTask.start(); + if(taskInfo.isSuccess()) { + taskResource.addTask(rebalanceTask); + } + + return taskInfo.getId(); + } public Status removeBricks(String volumeName, List bricks, String knownServer) { StringBuilder command = new StringBuilder("gluster --mode=script volume remove-brick " + volumeName); -- cgit From 8c59a588c903cc1a70ea769e78e0414c69006b35 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 27 Jun 2011 19:17:00 +0530 Subject: REST API enhancements --- .../core/response/LogMessageListResponse.java | 13 +------- .../src/get_volume_brick_log.py | 38 ++++++++-------------- .../server/resources/VolumesResource.java | 23 +++++-------- 3 files changed, 23 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java index c1f879bb..8c362fa9 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java @@ -9,11 +9,10 @@ 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.VolumeLogMessage; @XmlRootElement(name = "logMessages") -public class LogMessageListResponse extends AbstractResponse { +public class LogMessageListResponse { private List logMessages = new ArrayList(); public LogMessageListResponse() { @@ -23,11 +22,6 @@ public class LogMessageListResponse extends AbstractResponse { setLogMessages(logMessages); } - public LogMessageListResponse(Status status, List logMessages) { - setStatus(status); - setLogMessages(logMessages); - } - @XmlElement(name = "logMessage", type = VolumeLogMessage.class) public List getLogMessages() { return logMessages; @@ -36,9 +30,4 @@ public class LogMessageListResponse extends AbstractResponse { public void setLogMessages(List logMessages) { this.logMessages = logMessages; } - - @Override - public Object getData() { - return getLogMessages(); - } } diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py index 7c912412..64a40df3 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py @@ -19,7 +19,7 @@ import re import os import sys -from XmlHandler import ResponseXml +from XmlHandler import XDOM def enumLogType(logCode): if "M" == logCode.upper(): @@ -44,12 +44,10 @@ def enumLogType(logCode): return "UNKNOWN" ##--end of enumLogType() -def addLog(responseDom, logMessageTag, loginfo): - logTag = responseDom.createTag("logMessage", None) - logTag.appendChild(responseDom.createTag("timestamp", loginfo[0] + " " + loginfo[1])) - logTag.appendChild(responseDom.createTag("severity", enumLogType(loginfo[2]))) - logTag.appendChild(responseDom.createTag("message", loginfo[3])) - logMessageTag.appendChild(logTag) +def addLog(responseDom, loginfo): + responseDom.appendTagRoute("logMessages.logMessage.timestamp", loginfo[0] + " " + loginfo[1]) + responseDom.appendTagRoute("logMessages.logMessage.severity", enumLogType(loginfo[2])) + responseDom.appendTagRoute("logMessages.logMessage.message", loginfo[3]) return True ##--end of addLog() @@ -61,26 +59,21 @@ def logSplit(log): ##--end of logSplit() def getVolumeLog(logFilePath, tailCount): - rs = ResponseXml() + rs = XDOM() if not logFilePath: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No log file path given") - return rs.toprettyxml() + print >> sys.stderr, "No log file path given" + sys.exit(-1); if not tailCount: - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "No tail count given") - return rs.toprettyxml() + print >> sys.stderr, "No tail count given" + sys.exit(-1); pattern = '\[\d{4}-\d{2}-\d{2}\s{1}\d{2}:\d{2}:\d{2}.\d+\]\s{1}([MACEWNIDT]){1}\s+' - logMessagesTag = rs.createTag("logMessages") if not os.path.exists(logFilePath): - rs.appendTagRoute("status.code", "-1") - rs.appendTagRoute("status.message", "volume log file [%s] not found!" % logFilePath) - return rs.toprettyxml + print >> sys.stderr, "volume log file [%s] not found!" % logFilePath + sys.exit(-1); fp = open(logFilePath) - #lines = [line for line in fp] lines = [line for line in fp if re.match(pattern, line)] fp.close() i = len(lines) - int(tailCount) @@ -88,11 +81,8 @@ def getVolumeLog(logFilePath, tailCount): i = 0 for log in lines[i:]: loginfo = logSplit(log) - addLog(rs, logMessagesTag, loginfo) - rs.appendTagRoute("status.code", "0") - rs.appendTagRoute("status.message", "Success") - rs.appendTag(logMessagesTag) - return rs.toprettyxml() + addLog(rs, loginfo) + return rs.toxml() ##--end of getVolumeLog() def main(): diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index c7e18aaa..7b506e67 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -625,27 +625,20 @@ public class VolumesResource extends AbstractResource { // Usage: get_volume_disk_log.py Object responseObj = serverUtil.executeOnServer(true, brick.getServerName(), VOLUME_BRICK_LOG_SCRIPT + " " + logFilePath + " " + lineCount, LogMessageListResponse.class); - Status status = null; + LogMessageListResponse response = null; if (responseObj instanceof LogMessageListResponse) { response = (LogMessageListResponse) responseObj; - status = response.getStatus(); + // populate disk and trim other fields + List logMessages = response.getLogMessages(); + for (VolumeLogMessage logMessage : logMessages) { + logMessage.setBrickDirectory(brick.getBrickDirectory()); + } + return logMessages; } else { - status = (Status) responseObj; - } - - if (!status.isSuccess()) { + Status status = (Status) responseObj; throw new GlusterRuntimeException(status.toString()); } - - // populate disk and trim other fields - List logMessages = response.getLogMessages(); - for (VolumeLogMessage logMessage : logMessages) { - logMessage.setBrickDirectory(brick.getBrickDirectory()); - logMessage.setMessage(logMessage.getMessage().trim()); - logMessage.setSeverity(logMessage.getSeverity().trim()); - } - return logMessages; } @GET -- cgit From 4ef7f5b73e733528d818d2bb6987a56cc3b097ce Mon Sep 17 00:00:00 2001 From: Selvasundaram Date: Wed, 22 Jun 2011 18:36:51 +0530 Subject: Task progress view UI --- .../management/client/GlusterDataModelManager.java | 49 ++++++++- .../storage/management/client/TasksClient.java | 14 +-- .../management/core/constants/RESTConstants.java | 1 + .../exceptions/GlusterValidationException.java | 27 +++++ .../management/core/model/ClusterListener.java | 6 + .../core/model/DefaultClusterListener.java | 19 ++++ .../storage/management/core/model/Task.java | 33 +++--- .../storage/management/core/model/TaskInfo.java | 54 ++++++--- .../management/core/response/TaskListResponse.java | 34 +++--- .../icons/close_task.png | Bin 0 -> 588 bytes .../icons/pause_task.png | Bin 0 -> 427 bytes .../icons/start_task.gif | Bin 0 -> 470 bytes .../icons/stop_task.png | Bin 0 -> 411 bytes src/com.gluster.storage.management.gui/plugin.xml | 118 ++++++++++++++++++-- .../gluster/storage/management/gui/IImageKeys.java | 5 + .../management/gui/TasksTableLabelProvider.java | 47 ++++++++ .../management/gui/actions/ClearTaskAction.java | 53 +++++++++ .../management/gui/actions/PauseTaskAction.java | 75 +++++++++++++ .../management/gui/actions/ResumeTaskAction.java | 54 +++++++++ .../management/gui/actions/StopTaskAction.java | 54 +++++++++ .../storage/management/gui/utils/GUIHelper.java | 11 ++ .../management/gui/views/GlusterViewsManager.java | 2 + .../storage/management/gui/views/TasksView.java | 39 +++++++ .../management/gui/views/VolumesSummaryView.java | 2 +- .../gui/views/pages/AbstractDisksPage.java | 2 +- .../gui/views/pages/AbstractTableViewerPage.java | 90 +++++++++------ .../management/gui/views/pages/BricksPage.java | 2 +- .../gui/views/pages/GlusterServersPage.java | 2 +- .../management/gui/views/pages/ServersPage.java | 2 +- .../management/gui/views/pages/TasksPage.java | 116 ++++++++++++++++++++ .../gui/views/pages/VolumeOptionsPage.java | 100 +++++++++-------- .../management/gui/views/pages/VolumesPage.java | 2 +- .../server/resources/GlusterServersResource.java | 14 +-- .../management/server/resources/TasksResource.java | 121 ++++++++++++--------- .../server/tasks/InitializeDiskTask.java | 39 +++---- .../management/server/tasks/MigrateDiskTask.java | 118 +++++++++++++------- .../management/server/utils/GlusterUtil.java | 17 +-- 37 files changed, 1035 insertions(+), 287 deletions(-) create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java create mode 100644 src/com.gluster.storage.management.gui/icons/close_task.png create mode 100644 src/com.gluster.storage.management.gui/icons/pause_task.png create mode 100644 src/com.gluster.storage.management.gui/icons/start_task.gif create mode 100644 src/com.gluster.storage.management.gui/icons/stop_task.png create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java (limited to 'src') 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 taskInfoList = new TasksClient(cluster.getName()).getAllTasks(); + // List taskInfoList = new TasksClient(cluster.getName()).getAllTasks(); + List taskInfoList = getDummyTasks(); cluster.setTaskInfoList(taskInfoList); } + private List getDummyTasks() { + List taskInfoList = new ArrayList(); + + // 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 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 getAllTasks() { // TaskListResponse get only the list of taskInfo not list of Tasks - TaskListResponse response = (TaskListResponse) fetchResource(TaskListResponse.class); - if (response.getStatus().isSuccess()) { - return (List) 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. + * 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 + * . + *******************************************************************************/ +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 taskList = new ArrayList(); - private Status status; - - public Status getStatus() { - return status; - } +@XmlRootElement(name = "response") +public class TaskListResponse { + private List taskInfoList; - public void setStatus(Status status) { - this.status = status; - } + public TaskListResponse() { + } - public void setData(List taskList) { - this.taskList.clear(); - this.taskList.addAll(taskList); + public TaskListResponse(List taskInfoList) { + this.taskInfoList = taskInfoList; + } + + @XmlElement(name="TaskInfo", type=TaskInfo.class) + public List getTaskList() { + return taskInfoList; } - @Override - public Object getData() { - return this.taskList; + public void setTaskList(List 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 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/close_task.png 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 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/pause_task.png 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 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/start_task.gif 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 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/stop_task.png 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 @@ -29,14 +29,6 @@ name="Cluster Navigation Tree" restorable="true"> - - + + @@ -249,10 +250,35 @@ name="Remove Brick"> + + + + + + + + @@ -641,6 +667,70 @@ id="com.gluster.storage.management.gui.actionsets.gluster" label="Cluster Action Set" visible="false"> + + + + + + + + + + + * 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 + * . + */ +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. + * 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 + * . + */ +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 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 im protected abstract int getStatusColumnIndex(); public AbstractDisksPage(final Composite parent, int style, IWorkbenchSite site, List 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 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 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 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 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 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 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 { "Total Space (GB)", "Status" }; public BricksPage(Composite parent, int style, IWorkbenchSite site, final List 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 { "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 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 { // "Total Disk\n Space (GB)", "Disk Space\nin Use (GB)"}; public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup 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. + * 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 + * . + */ +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 { + private List 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; + } + + /* (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 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 getEntry(String key) { - for (Entry 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 getEntry(String key) { + for (Entry 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 { "Number of\nBricks", "Transport Type", "Status" }; public VolumesPage(final Composite parent, IWorkbenchSite site, EntityGroup 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 tasksMap = new HashMap(); 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 getAllTasksInfo() { List allTasksInfo = new ArrayList(); for (Map.Entry entry : tasksMap.entrySet()) { - allTasksInfo.add(entry.getValue().getTaskInfo()); + checkTaskStatus(entry.getKey()); + allTasksInfo.add(entry.getValue().getTaskInfo()); // TaskInfo with latest status } return allTasksInfo; } - - public List getAllTasks() { - List allTasks = new ArrayList(); - for (Map.Entry entry : tasksMap.entrySet()) { - allTasks.add(entry.getValue()); - } - return allTasks; - } public Task getTask(String taskId) { for (Map.Entry 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 bricks, String knownServer) { StringBuilder command = new StringBuilder("gluster --mode=script volume remove-brick " + volumeName); -- cgit From 8c9fc77039b09f22004c728c1a7640c354a8345d Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 28 Jun 2011 11:09:33 +0530 Subject: Modified to ignore case while checking if a cluster/server already exists. --- .../management/gui/dialogs/LoginDialog.java | 30 ++++++++-------------- .../server/resources/ClustersResource.java | 1 - .../management/server/services/ClusterService.java | 4 +-- 3 files changed, 12 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index c23a96c5..487a03c4 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -254,31 +254,21 @@ public class LoginDialog extends Dialog { super.okPressed(); } catch (Exception e) { setReturnCode(RETURN_CODE_ERROR); - MessageDialog.openError(getShell(), "Initialization Error", e.getMessage()); - close(); + MessageDialog.openError(getShell(), "Gluster Management Console", e.getMessage()); } } public void createOrRegisterCluster(ClustersClient clustersClient, String clusterName, String serverName, CLUSTER_MODE mode) { - String errTitle = null; - - try { - switch (mode) { - case SELECT: - return; - case CREATE: - errTitle = "Cluster Creation Failed!"; - clustersClient.createCluster(clusterName); - break; - case REGISTER: - errTitle = "Cluster Registration Failed!"; - clustersClient.registerCluster(clusterName, serverName); - break; - } - } catch (Exception e) { - MessageDialog.openError(getShell(), errTitle, e.getMessage()); - setReturnCode(RETURN_CODE_ERROR); + switch (mode) { + case SELECT: + return; + case CREATE: + clustersClient.createCluster(clusterName); + break; + case REGISTER: + clustersClient.registerCluster(clusterName, serverName); + break; } } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java index 2ce23a4e..4c834973 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java @@ -106,7 +106,6 @@ public class ClustersResource extends AbstractResource { return badRequestResponse("Server [" + knownServer + "] is already present in cluster [" + mappedCluster.getName() + "]!"); } - try { clusterService.registerCluster(clusterName, knownServer); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java index 0aabb714..bb379de6 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java @@ -65,7 +65,7 @@ public class ClusterService { } public ClusterInfo getCluster(String clusterName) { - List clusters = clusterDao.findBy("name = ?1", clusterName); + List clusters = clusterDao.findBy("UPPER(name) = ?1", clusterName.toUpperCase()); if(clusters.size() == 0) { return null; } @@ -74,7 +74,7 @@ public class ClusterService { } public ClusterInfo getClusterForServer(String serverName) { - List servers = serverDao.findBy("name = ?1", serverName); + List servers = serverDao.findBy("UPPER(name) = ?1", serverName.toUpperCase()); if(servers.size() == 0) { return null; } -- cgit From eb58d91bb775a897c39ac7303993b361b48f35a9 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Mon, 27 Jun 2011 16:21:16 +0530 Subject: Story #1: Rebalance Volume --- .../storage/management/client/VolumesClient.java | 14 +++- .../management/core/constants/RESTConstants.java | 2 + .../gui/actions/RebalanceVolumeAction.java | 4 +- .../server/resources/VolumesResource.java | 66 ++++++++++++++-- .../server/tasks/RebalanceVolumeTask.java | 90 ++++++++++++++-------- .../management/server/utils/GlusterUtil.java | 41 ++++++++-- 6 files changed, 169 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index 338caf89..4ec3ff13 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -230,7 +230,7 @@ public class VolumesClient extends AbstractClient { putRequest(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); } - public void rebalanceVolume(String volumeName, boolean fixLayout, boolean migrateData, boolean forcedDataMigrate) { + public void rebalanceStart(String volumeName, Boolean fixLayout, Boolean migrateData, Boolean forcedDataMigrate) { Form form = new Form(); form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_REBALANCE_START); form.add(RESTConstants.FORM_PARAM_FIX_LAYOUT, fixLayout); @@ -238,6 +238,18 @@ public class VolumesClient extends AbstractClient { form.add(RESTConstants.FORM_PARAM_FORCED_DATA_MIGRATE, forcedDataMigrate); putRequest(volumeName, form); } + + public void rebalanceStatus(String volumeName) { + Form form = new Form(); + form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_REBALANCE_STATUS); + putRequest(volumeName, form); + } + + public void rebalanceStop(String volumeName) { + Form form = new Form(); + form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_REBALANCE_STOP); + putRequest(volumeName, form); + } public static void main(String[] args) { UsersClient usersClient = new UsersClient(); 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 abc2d852..527ae2a1 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 @@ -49,6 +49,8 @@ public class RESTConstants { public static final String TASK_STATUS = "status"; public static final String TASK_DELETE = "delete"; public static final String TASK_REBALANCE_START = "rebalanceStart"; + public static final String TASK_REBALANCE_STATUS = "rebalanceStatus"; + public static final String TASK_REBALANCE_STOP = "rebalanceStop"; public static final String FORM_PARAM_VOLUME_NAME = "name"; public static final String FORM_PARAM_VOLUME_TYPE = "volumeType"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java index 9b55e70a..33ca0e5b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java @@ -37,11 +37,11 @@ public class RebalanceVolumeAction extends AbstractActionDelegate { public void run() { final String actionDesc = action.getDescription(); try { - new VolumesClient().rebalanceVolume(volume.getName(), false, false, false); + new VolumesClient().rebalanceStart(volume.getName(), false, false, false); showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] rebalance started successfully!"); } catch (Exception e) { showErrorDialog(actionDesc, - "Volume rebalance cannot started on [" + volume.getName() + "]! Error: [" + e.getMessage() + "]"); + "Volume rebalance could not be started on [" + volume.getName() + "]! Error: [" + e.getMessage() + "]"); } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 73d3ccc8..0bb61245 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -331,7 +331,11 @@ public class VolumesResource extends AbstractResource { } if (operation.equals(RESTConstants.TASK_REBALANCE_START)) { - return rebalanceVolume(clusterName, volumeName, isFixLayout, isMigrateData, isForcedDataMigrate); + return rebalanceStart(clusterName, volumeName, isFixLayout, isMigrateData, isForcedDataMigrate); + } else if (operation.equals(RESTConstants.TASK_REBALANCE_STATUS)) { + return rebalanceStatus(clusterName, volumeName); + } else if (operation.equals(RESTConstants.TASK_REBALANCE_STOP)) { + return rebalanceStop(clusterName, volumeName); } try { @@ -946,12 +950,12 @@ public class VolumesResource extends AbstractResource { return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); } - private Response rebalanceVolume(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, - boolean isForcedDataMigrate) { + private Response rebalanceStart(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, + Boolean isForcedDataMigrate) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); + return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); } String layout = ""; @@ -965,13 +969,13 @@ public class VolumesResource extends AbstractResource { } try { - taskId = glusterUtil.rebalanceVolumeStart(volumeName, layout, onlineServer.getName()); + taskId = glusterUtil.rebalanceStart(volumeName, layout, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); try { - taskId = glusterUtil.rebalanceVolumeStart(volumeName, layout, onlineServer.getName()); + taskId = glusterUtil.rebalanceStart(volumeName, layout, onlineServer.getName()); } catch(Exception e1) { return errorResponse(e1.getMessage()); } @@ -981,6 +985,56 @@ public class VolumesResource extends AbstractResource { return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); } + + private Response rebalanceStatus(String clusterName, String volumeName) { + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if (onlineServer == null) { + return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); + } + + String taskId = null; + try { + taskId = glusterUtil.rebalanceStatus(volumeName, onlineServer.getName()); + } catch (ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + + try { + taskId = glusterUtil.rebalanceStatus(volumeName, onlineServer.getName()); + } catch (Exception e1) { + return errorResponse(e1.getMessage()); + } + } catch(Exception e1) { + return errorResponse(e1.getMessage()); + } + + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + } + + private Response rebalanceStop(String clusterName, String volumeName) { + GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + if (onlineServer == null) { + return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); + } + + String taskId = null; + try { + taskId = glusterUtil.rebalanceStop(volumeName, onlineServer.getName()); + } catch (ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + + try { + taskId = glusterUtil.rebalanceStop(volumeName, onlineServer.getName()); + } catch (Exception e1) { + return errorResponse(e1.getMessage()); + } + } catch(Exception e1) { + return errorResponse(e1.getMessage()); + } + + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + } public static void main(String[] args) throws ClassNotFoundException { VolumesResource vr = new VolumesResource(); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java index 697a40be..720c050e 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java @@ -23,7 +23,9 @@ 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.core.utils.ProcessResult; import com.gluster.storage.management.server.utils.SshUtil; public class RebalanceVolumeTask extends Task { @@ -36,60 +38,78 @@ public class RebalanceVolumeTask extends Task { } public RebalanceVolumeTask(String volumeName) { - super(TASK_TYPE.VOLUME_REBALANCE, volumeName); - setTaskDescription(); - getTaskInfo().setCanPause(false); - getTaskInfo().setCanStop(true); + super(TASK_TYPE.VOLUME_REBALANCE, volumeName, "Volume rebalance running on " + volumeName, false, true, false); } @Override public String getId() { - return getTaskInfo().getId(); + return taskInfo.getType() + "-" + taskInfo.getReference(); } @Override - public TaskInfo start() { - getTaskInfo().setStatus( - new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " - + getTaskInfo().getReference() + " " + getLayout() + " start")))); - return getTaskInfo(); + public void start() { + String command = "gluster volume rebalance " + getTaskInfo().getReference() + " " + getLayout() + " start"; + ProcessResult processResult = sshUtil.executeRemote(serverName, command); + TaskStatus taskStatus = new TaskStatus(); + if (processResult.isSuccess()) { + if (processResult.getOutput().trim().matches("*has been successful$")) { + 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() { + public void resume() { getTaskInfo().setStatus( - new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Can not suspend volume rebalance"))); - return getTaskInfo(); + new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Pause/Resume is not supported in Volume Rebalance"))); } @Override - public TaskInfo stop() { - getTaskInfo().setStatus( - new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " - + getTaskInfo().getReference() + " stop")))); - return getTaskInfo(); + public void stop() { + String command = "gluster volume rebalance " + getTaskInfo().getReference() + " stop"; + ProcessResult processResult = sshUtil.executeRemote(serverName, command); + TaskStatus taskStatus = new TaskStatus(); + if (processResult.isSuccess()) { + if (processResult.getOutput().trim().matches("*has been successful$")) { + 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 pause() { + public void pause() { getTaskInfo().setStatus( - new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Can not pause volume rebalance"))); - return getTaskInfo(); + new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Pause/Resume is not supported in Volume Rebalance"))); } @Override - public TaskInfo status() { - getTaskInfo().setStatus( - new TaskStatus(new Status(sshUtil.executeRemote(getOnlineServer(), "gluster volume rebalance " - + getTaskInfo().getReference() + " status")))); - return getTaskInfo(); - } - - @Override - public void setTaskDescription() { - TaskInfo taskInfo = getTaskInfo(); - getTaskInfo().setDescription("Volume rebalance running on " + taskInfo.getReference()); - + public TaskStatus checkStatus() { + String command = "gluster volume rebalance " + getTaskInfo().getReference() + " status"; + ProcessResult processResult = sshUtil.executeRemote(serverName, command); + TaskStatus taskStatus = new TaskStatus(); + if (processResult.isSuccess()) { + if (processResult.getOutput().matches("Rebalance completed!")) { + 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; } public void setLayout(String layout) { @@ -100,4 +120,8 @@ public class RebalanceVolumeTask extends Task { return layout; } + @Override + public void commit() { + // TODO Auto-generated method stub + } } 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 f75810df..767b15c3 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,7 +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.TaskInfo.TASK_TYPE; +import com.gluster.storage.management.core.model.TaskInfo; 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; @@ -554,18 +554,47 @@ public class GlusterUtil { return migrateDiskTask.getId(); } - public String rebalanceVolumeStart(String volumeName, String layout, String knownServer) { + public String rebalanceStart(String volumeName, String layout, String knownServer) { RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); rebalanceTask.setOnlineServer(knownServer); rebalanceTask.setLayout(layout); + rebalanceTask.start(); + int status = rebalanceTask.getTaskInfo().getStatus().getCode(); - TaskInfo taskInfo = rebalanceTask.start(); - if(taskInfo.isSuccess()) { + if(status != Status.STATUS_CODE_FAILURE) { + TasksResource taskResource = new TasksResource(); taskResource.addTask(rebalanceTask); + } else { + throw new GlusterRuntimeException( rebalanceTask.getTaskInfo().getStatus().getMessage()); } - - return taskInfo.getId(); + return rebalanceTask.getId(); + } + + public String rebalanceStatus(String volumeName, String knownServer) { + RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); + rebalanceTask.setOnlineServer(knownServer); + + rebalanceTask.checkStatus(); + int status = rebalanceTask.getTaskInfo().getStatus().getCode(); + + if (status == Status.STATUS_CODE_FAILURE) { + throw new GlusterRuntimeException(rebalanceTask.getTaskInfo().getStatus().getMessage()); + } + return rebalanceTask.getId(); + } + + public String rebalanceStop(String volumeName, String knownServer) { + RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); + rebalanceTask.setOnlineServer(knownServer); + + rebalanceTask.stop(); + int status = rebalanceTask.getTaskInfo().getStatus().getCode(); + + if (status == Status.STATUS_CODE_FAILURE) { + throw new GlusterRuntimeException(rebalanceTask.getTaskInfo().getStatus().getMessage()); + } + return rebalanceTask.getId(); } public Status removeBricks(String volumeName, List bricks, String knownServer) { -- cgit From 0aa85e9e8b67492fbf26e761f54ca282539116e8 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 28 Jun 2011 14:27:07 +0530 Subject: Fixed XML format of the log messages response --- .../src/get_volume_brick_log.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py index 64a40df3..fd7361da 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py @@ -44,10 +44,12 @@ def enumLogType(logCode): return "UNKNOWN" ##--end of enumLogType() -def addLog(responseDom, loginfo): - responseDom.appendTagRoute("logMessages.logMessage.timestamp", loginfo[0] + " " + loginfo[1]) - responseDom.appendTagRoute("logMessages.logMessage.severity", enumLogType(loginfo[2])) - responseDom.appendTagRoute("logMessages.logMessage.message", loginfo[3]) +def addLog(responseDom, logMessagesTag, loginfo): + logMessageTag = responseDom.createTag("logMessage") + logMessageTag.appendChild(responseDom.createTag("timestamp", loginfo[0] + " " + loginfo[1])) + logMessageTag.appendChild(responseDom.createTag("severity", enumLogType(loginfo[2]))) + logMessageTag.appendChild(responseDom.createTag("message", loginfo[3])) + logMessagesTag.appendChild(logMessageTag); return True ##--end of addLog() @@ -79,9 +81,11 @@ def getVolumeLog(logFilePath, tailCount): i = len(lines) - int(tailCount) if i < 0: i = 0 + logMessagesTag = rs.createTag("logMessages") + rs.addTag(logMessagesTag) for log in lines[i:]: loginfo = logSplit(log) - addLog(rs, loginfo) + addLog(rs, logMessagesTag, loginfo) return rs.toxml() ##--end of getVolumeLog() -- cgit From 91a5b783b596a16aa6e557f8fac687fb656d447d Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Tue, 28 Jun 2011 15:27:00 +0530 Subject: Bug 3089 - Total memory for auto discovered servers is showing upto 16 digits after decimal point --- .../com/gluster/storage/management/gui/views/DiscoveredServerView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java index fdb4c53c..8516d1db 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java @@ -62,7 +62,7 @@ public class DiscoveredServerView extends ViewPart { toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); toolkit.createLabel(section, "Total Memory (GB): ", SWT.NONE); - toolkit.createLabel(section, "" + (server.getTotalMemory() / 1024), SWT.NONE); + toolkit.createLabel(section, "" + NumberUtil.formatNumber((server.getTotalMemory() / 1024)), SWT.NONE); toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); toolkit.createLabel(section, "" + NumberUtil.formatNumber((server.getTotalDiskSpace() / 1024)), SWT.NONE); -- cgit From d2e858aa61e7087a3b4f16019d677d93b0a38d51 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 28 Jun 2011 16:20:07 +0530 Subject: Bug 3060 - If the brick log file size is greater than 1MB then tar ball downloaded will be corrupt --- .../gluster/storage/management/client/AbstractClient.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java index 3d13a8de..514217ad 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java @@ -139,13 +139,14 @@ public abstract class AbstractClient { } InputStream inputStream = response.getEntityInputStream(); - byte[] data = new byte[inputStream.available()]; - inputStream.read(data); + FileOutputStream outputStream = new FileOutputStream(filePath); + + int c; + while((c = inputStream.read()) != -1) { + outputStream.write(c); + } inputStream.close(); - - FileOutputStream os = new FileOutputStream(filePath); - os.write(data); - os.close(); + outputStream.close(); } catch (IOException e) { throw new GlusterRuntimeException("Error while downloading resource [" + res.getURI().getPath() + "]", e); } -- cgit From 0643561ef89b12982d0835264146dcee97365476 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Tue, 28 Jun 2011 18:17:37 +0530 Subject: Bug 3100 - "Remove Brick" gets activated even with out checking the check box of any brick --- .../management/client/GlusterDataModelManager.java | 3 ++- .../storage/management/client/VolumesClient.java | 3 ++- .../management/core/utils/GlusterCoreUtil.java | 3 ++- .../management/gui/actions/RemoveDiskAction.java | 23 +++++----------------- .../server/tasks/RebalanceVolumeTask.java | 6 +++--- 5 files changed, 14 insertions(+), 24 deletions(-) (limited to 'src') 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 c02d73b5..02a387e0 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 @@ -21,6 +21,7 @@ package com.gluster.storage.management.client; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; @@ -339,7 +340,7 @@ public class GlusterDataModelManager { } } - public void removeBricks(Volume volume, List bricks) { + public void removeBricks(Volume volume, Set bricks) { for (ClusterListener listener : listeners) { listener.volumeChanged(volume, new Event(EVENT_TYPE.BRICKS_REMOVED, bricks)); } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index 4ec3ff13..be9b82b0 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -31,6 +31,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import java.util.Date; import java.util.List; +import java.util.Set; import javax.ws.rs.core.MultivaluedMap; @@ -175,7 +176,7 @@ public class VolumesClient extends AbstractClient { downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); } - public void removeBricks(String volumeName, List BrickList, boolean deleteOption) { + public void removeBricks(String volumeName, Set BrickList, boolean deleteOption) { String bricks = StringUtil.collectionToString(GlusterCoreUtil.getQualifiedBrickList(BrickList), ","); MultivaluedMap queryParams = prepareRemoveBrickQueryParams(volumeName, bricks, deleteOption); deleteSubResource(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, queryParams); diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java index c238cad7..4194a642 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java @@ -22,6 +22,7 @@ package com.gluster.storage.management.core.utils; import java.util.ArrayList; import java.util.List; +import java.util.Set; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Disk; @@ -37,7 +38,7 @@ public class GlusterCoreUtil { return qualifiedDiskNames; } - public static final List getQualifiedBrickList(List bricks) { + public static final List getQualifiedBrickList(Set bricks) { List qualifiedBricks = new ArrayList(); for (Brick brick : bricks) { qualifiedBricks.add(brick.getQualifiedName()); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java index 9df40457..b79a4ee4 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java @@ -3,6 +3,7 @@ package com.gluster.storage.management.gui.actions; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; @@ -15,6 +16,7 @@ import org.eclipse.ui.IWorkbenchPart; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.utils.StringUtil; @@ -25,7 +27,7 @@ import com.gluster.storage.management.gui.views.VolumeBricksView; public class RemoveDiskAction extends AbstractActionDelegate { private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); private GUIHelper guiHelper = GUIHelper.getInstance(); - private List bricks; + private Set bricks; private Volume volume; boolean confirmDelete = false; @@ -90,28 +92,13 @@ public class RemoveDiskAction extends AbstractActionDelegate { IWorkbenchPart view = guiHelper.getActiveView(); if (view instanceof VolumeBricksView) { // volume disks view is open. check if any brick is selected - bricks = getSelectedBricks(selection); + bricks = GUIHelper.getInstance().getSelectedEntities(getWindow(), Brick.class); action.setEnabled(bricks.size() > 0); } } } - private List getSelectedBricks(ISelection selection) { - List selectedBricks = new ArrayList(); - - if (selection instanceof IStructuredSelection) { - Iterator iter = ((IStructuredSelection) selection).iterator(); - while (iter.hasNext()) { - Object selectedObj = iter.next(); - if (selectedObj instanceof Brick) { - selectedBricks.add((Brick) selectedObj); - } - } - } - return selectedBricks; - } - - private List getBrickList(List bricks) { + private List getBrickList(Set bricks) { List brickList = new ArrayList(); for (Brick brick : bricks) { brickList.add(brick.getServerName() + ":" + brick.getBrickDirectory()); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java index 720c050e..5b70d7a8 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java @@ -52,7 +52,7 @@ public class RebalanceVolumeTask extends Task { ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { - if (processResult.getOutput().trim().matches("*has been successful$")) { + if (processResult.getOutput().trim().matches(".*has been successful$")) { taskStatus.setCode(Status.STATUS_CODE_RUNNING); } else { taskStatus.setCode(Status.STATUS_CODE_FAILURE); @@ -76,7 +76,7 @@ public class RebalanceVolumeTask extends Task { ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { - if (processResult.getOutput().trim().matches("*has been successful$")) { + if (processResult.getOutput().trim().matches(".*has been successful$")) { taskStatus.setCode(Status.STATUS_CODE_SUCCESS); } else { taskStatus.setCode(Status.STATUS_CODE_FAILURE); @@ -100,7 +100,7 @@ public class RebalanceVolumeTask extends Task { ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { - if (processResult.getOutput().matches("Rebalance completed!")) { + if (processResult.getOutput().trim().matches("Rebalance completed!")) { taskStatus.setCode(Status.STATUS_CODE_SUCCESS); } else { taskStatus.setCode(Status.STATUS_CODE_RUNNING); -- cgit From 6f3735d5e745c8f2ec26c3dcc106777541cb02b7 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Tue, 28 Jun 2011 18:51:48 +0530 Subject: Bug 3049 - "Scan last" field in logs allows alphabets --- .../management/gui/views/pages/ServerLogsPage.java | 23 ++++++++++++++++++++++ .../management/gui/views/pages/VolumeLogsPage.java | 22 +++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java index 7cde38bb..0ff22e31 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java @@ -26,6 +26,8 @@ import org.eclipse.jface.viewers.ListViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -84,6 +86,27 @@ public class ServerLogsPage extends Composite { text = toolkit.createText(composite, "100", SWT.NONE); text.setBounds(85, 15, 60, 20); + text.setTextLimit(4); + text.addVerifyListener(new VerifyListener() { + + @Override + public void verifyText(VerifyEvent event) { + // Assume we allow it + event.doit = true; + + String text = event.text; + char[] chars = text.toCharArray(); + + // Don't allow if text contains non-digit characters + for (int i = 0; i < chars.length; i++) { + if (!Character.isDigit(chars[i])) { + event.doit = false; + break; + } + } + + } + }); Label lblMessagesAndFilter = toolkit.createLabel(composite, " messages from ", SWT.CENTER); lblMessagesAndFilter.setBounds(160, 15, 110, 20); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java index 6ba9c0d1..82836621 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java @@ -32,6 +32,8 @@ import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -334,6 +336,26 @@ public class VolumeLogsPage extends Composite { private void createLineCountText(Composite composite) { lineCountText = toolkit.createText(composite, "100", SWT.NONE); lineCountText.setBounds(85, 15, 60, 20); + lineCountText.setTextLimit(4); + lineCountText.addVerifyListener(new VerifyListener() { + + @Override + public void verifyText(VerifyEvent event) { + // Assume we allow it + event.doit = true; + + String text = event.text; + char[] chars = text.toCharArray(); + + // Don't allow if text contains non-digit characters + for (int i = 0; i < chars.length; i++) { + if (!Character.isDigit(chars[i])) { + event.doit = false; + break; + } + } + } + }); } private void createLineCountLabel(Composite composite) { -- cgit From f5c680106bf3abdd3e795637d3fe4baf956cbfe0 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Wed, 29 Jun 2011 15:17:05 +0530 Subject: tango icon set --- .../icons/star.png | Bin 0 -> 244 bytes .../icons/tango/16x16/disk.png | Bin 0 -> 603 bytes .../icons/tango/16x16/help.png | Bin 0 -> 932 bytes .../icons/tango/16x16/logs.png | Bin 0 -> 611 bytes .../icons/tango/16x16/server.png | Bin 0 -> 725 bytes .../icons/tango/16x16/servers.png | Bin 0 -> 393 bytes .../icons/tango/16x16/settings.png | Bin 0 -> 588 bytes .../icons/tango/16x16/volume-create.png | Bin 0 -> 635 bytes .../icons/tango/16x16/volume.png | Bin 0 -> 697 bytes .../icons/tango/32x32/disk.png | Bin 0 -> 1155 bytes .../icons/tango/32x32/help.png | Bin 0 -> 2231 bytes .../icons/tango/32x32/logs.png | Bin 0 -> 1886 bytes .../icons/tango/32x32/server.png | Bin 0 -> 1591 bytes .../icons/tango/32x32/servers.png | Bin 0 -> 1264 bytes .../icons/tango/32x32/settings.png | Bin 0 -> 2544 bytes .../icons/tango/32x32/volume-create.png | Bin 0 -> 1399 bytes .../icons/tango/32x32/volume.png | Bin 0 -> 1446 bytes .../icons/tango/48x48/server.png | Bin 0 -> 3295 bytes .../icons/tango/48x48/volume-create.png | Bin 0 -> 2853 bytes .../icons/tango/48x48/volume.png | Bin 0 -> 2965 bytes src/com.gluster.storage.management.gui/plugin.xml | 22 ++++++++++----------- .../gluster/storage/management/gui/IImageKeys.java | 18 ++++++++--------- 22 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 src/com.gluster.storage.management.gui/icons/star.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/help.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/logs.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/server.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/servers.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/settings.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/volume.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/disk.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/help.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/logs.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/server.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/servers.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/settings.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/volume.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/48x48/server.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/48x48/volume.png (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/icons/star.png b/src/com.gluster.storage.management.gui/icons/star.png new file mode 100644 index 00000000..5f8fc748 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/star.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png new file mode 100644 index 00000000..5c3b8587 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/help.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/help.png new file mode 100644 index 00000000..f25fc3fb Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/help.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/logs.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/logs.png new file mode 100644 index 00000000..8734e777 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/logs.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/server.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/server.png new file mode 100644 index 00000000..d0b397be Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/server.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/servers.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/servers.png new file mode 100644 index 00000000..0efee57e Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/servers.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/settings.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/settings.png new file mode 100644 index 00000000..d90ab661 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/settings.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.png new file mode 100644 index 00000000..628f4d50 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/volume.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume.png new file mode 100644 index 00000000..5234eab4 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/disk.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/disk.png new file mode 100644 index 00000000..b34d8b77 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/disk.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/help.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/help.png new file mode 100644 index 00000000..d60425f7 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/help.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/logs.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/logs.png new file mode 100644 index 00000000..b62959e4 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/logs.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/server.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/server.png new file mode 100644 index 00000000..e34eb4e4 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/server.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/servers.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/servers.png new file mode 100644 index 00000000..dca03af4 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/servers.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/settings.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/settings.png new file mode 100644 index 00000000..565f406d Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/settings.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.png new file mode 100644 index 00000000..fcd15c01 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/volume.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume.png new file mode 100644 index 00000000..3e0d9add Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/48x48/server.png b/src/com.gluster.storage.management.gui/icons/tango/48x48/server.png new file mode 100644 index 00000000..a568c0b8 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/48x48/server.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.png b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.png new file mode 100644 index 00000000..967d1844 Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/48x48/volume.png b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume.png new file mode 100644 index 00000000..4bd1a2aa Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume.png differ diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index c5c25c33..e86618bb 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -54,7 +54,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.VolumesView" - icon="icons/volumes.png" + icon="icons/tango/16x16/volume.png" id="com.gluster.storage.management.gui.views.VolumesView" name="Volumes" restorable="true"> @@ -99,7 +99,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.VolumeOptionsView" - icon="icons/preferences.png" + icon="icons/tango/16x16/settings.png" id="com.gluster.storage.management.gui.views.VolumeOptionsView" name="Volume Options" restorable="true"> @@ -108,7 +108,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.VolumeLogsView" - icon="icons/logs.png" + icon="icons/tango/16x16/logs.png" id="com.gluster.storage.management.gui.views.VolumeLogsView" name="Volume Logs" restorable="true"> @@ -126,7 +126,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.GlusterServersView" - icon="icons/servers.png" + icon="icons/tango/16x16/servers.png" id="com.gluster.storage.management.gui.views.GlusterServersView" name="Servers" restorable="true"> @@ -135,7 +135,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.DisksView" - icon="icons/disks.png" + icon="icons/tango/16x16/disk.png" id="com.gluster.storage.management.gui.views.DisksView" name="Disks" restorable="true"> @@ -153,7 +153,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.GlusterServerDisksView" - icon="icons/disks.png" + icon="icons/tango/16x16/disk.png" id="com.gluster.storage.management.gui.views.GlusterServerDisksView" name="Server Disks" restorable="true"> @@ -162,7 +162,7 @@ allowMultiple="false" category="com.gluster.storage.management.gui.category" class="com.gluster.storage.management.gui.views.GlusterServerLogsView" - icon="icons/logs.png" + icon="icons/tango/16x16/logs.png" id="com.gluster.storage.management.gui.views.GlusterServerLogsView" name="Server Logs" restorable="true"> @@ -400,7 +400,7 @@ allowLabelUpdate="false" class="com.gluster.storage.management.gui.actions.PreferencesAction" definitionId="org.eclipse.ui.window.preferences" - icon="icons/preferences.png" + icon="icons/tango/32x32/settings.png" id="com.gluster.storage.management.gui.actions.AddServerAction" label="&Settings" menubarPath="com.gluster.storage.management.gui.menu.edit/edit" @@ -545,7 +545,7 @@ allowLabelUpdate="false" class="com.gluster.storage.management.gui.actions.DownloadVolumeLogsAction" definitionId="com.gluster.storage.management.gui.commands.DownloadVolumeLogs" - icon="icons/logs.png" + icon="icons/tango/16x16/logs.png" id="com.gluster.storage.management.gui.actions.DownloadVolumeLogsAction" label="Download &Logs" menubarPath="com.gluster.storage.management.gui.menu.volume/volume" @@ -561,7 +561,7 @@ allowLabelUpdate="false" class="com.gluster.storage.management.gui.actions.ResetVolumeOptionsAction" definitionId="com.gluster.storage.management.gui.commands.ResetVolumeOptions" - icon="icons/reset-options.png" + icon="icons/tango/16x16/settings.png" id="com.gluster.storage.management.gui.actions.ResetVolumeOptionsAction" label="Reset &Options" menubarPath="com.gluster.storage.management.gui.menu.volume/volume" @@ -735,7 +735,7 @@ allowLabelUpdate="false" class="com.gluster.storage.management.gui.actions.CreateVolumeAction" definitionId="com.gluster.storage.management.gui.commands.CreateVolume" - icon="icons/volume-create.png" + icon="icons/tango/32x32/volume-create.png" id="com.gluster.storage.management.gui.actions.CreateVolumeAction" label="Create &Volume" menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster" 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 c2223729..5836f6f9 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 @@ -20,10 +20,10 @@ package com.gluster.storage.management.gui; public interface IImageKeys { public static final String CLUSTER = "icons/cluster.png"; - public static final String VOLUMES = "icons/volumes.png"; - public static final String SERVERS = "icons/servers.png"; - public static final String VOLUME = "icons/volume.png"; - public static final String SERVER = "icons/server.png"; + public static final String VOLUMES = "icons/tango/16x16/volume.png"; + public static final String SERVERS = "icons/tango/16x16/servers.png"; + public static final String VOLUME = "icons/tango/16x16/volume.png"; + public static final String SERVER = "icons/tango/16x16/server.png"; public static final String SERVER_WARNING = "icons/server-warning.png"; public static final String MEMORY = "icons/memory.png"; public static final String GSN = "icons/gsn.png"; @@ -31,10 +31,10 @@ public interface IImageKeys { public static final String ADD = "icons/plus-white.png"; public static final String REMOVE = "icons/minus-white.png"; public static final String CREATE_VOLUME = "icons/volume-create.png"; - public static final String CREATE_VOLUME_BIG = "icons/volume-create-big.png"; + public static final String CREATE_VOLUME_BIG = "icons/tango/48x48/volume-create.png"; public static final String REMOVE_VOLUME = "icons/volume-delete.png"; public static final String ADD_SERVER = "icons/server-add.png"; - public static final String ADD_SERVER_BIG = "icons/server-add-big.png"; + public static final String ADD_SERVER_BIG = "icons/tango/48x48/server.png"; public static final String REMOVE_SERVER = "icons/server-remove.png"; public static final String HELP = "icons/question.png"; public static final String STATUS_OFFLINE = "icons/status-offline.png"; @@ -44,8 +44,8 @@ public interface IImageKeys { public static final String WORK_IN_PROGRESS = "icons/progress-bar.png"; public static final String CHECKBOX_UNCHECKED = "icons/ui-check-box-uncheck.png"; public static final String CHECKBOX_CHECKED = "icons/ui-check-box.png"; - public static final String DISK = "icons/disk.png"; - public static final String DISKS = "icons/disks.png"; + public static final String DISK = "icons/tango/16x16/disk.png"; + public static final String DISKS = "icons/tango/16x16/disk.png"; public static final String DISK_UNINITIALIZED = "icons/disk-uninitialized.png"; public static final String SEARCH = "icons/search.png"; public static final String ARROW_UP = "icons/arrow-up.png"; @@ -62,7 +62,7 @@ public interface IImageKeys { 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"; + public static final String OVERLAY_STAR = "icons/star.png"; public static final String SPLASH_IMAGE = "splash.bmp"; public static final String DIALOG_SPLASH_IMAGE = "splash/splash-dialog.bmp"; -- cgit From d13ec8851ef77ba8a60fa659faf88e9924210180 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 29 Jun 2011 15:19:38 +0530 Subject: Resources response issue fix --- .../server/resources/GlusterServersResource.java | 6 +-- .../server/resources/VolumesResource.java | 60 +++++++++++----------- .../server/tasks/RebalanceVolumeTask.java | 2 +- .../management/server/utils/GlusterUtil.java | 1 - 4 files changed, 34 insertions(+), 35 deletions(-) (limited to 'src') 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 e824fee7..0a77a8ab 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 @@ -153,7 +153,7 @@ public class GlusterServersResource extends AbstractServersResource { ClusterInfo cluster = clusterService.getCluster(clusterName); if (cluster == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } if (cluster.getServers().size() == 0) { @@ -314,7 +314,7 @@ public class GlusterServersResource extends AbstractServersResource { ClusterInfo cluster = clusterService.getCluster(clusterName); if (cluster == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } boolean publicKeyInstalled = sshUtil.isPublicKeyInstalled(serverName); @@ -377,7 +377,7 @@ public class GlusterServersResource extends AbstractServersResource { ClusterInfo cluster = clusterService.getCluster(clusterName); if (cluster == null) { - return badRequestResponse("Cluster [" + clusterName + "] not found!"); + return notFoundResponse("Cluster [" + clusterName + "] not found!"); } List servers = cluster.getServers(); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 0bb61245..0f3fbb95 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -142,7 +142,7 @@ public class VolumesResource extends AbstractResource { public Response getVolumes(String clusterName, String mediaType) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -179,12 +179,12 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_BRICKS) String bricks, @FormParam(FORM_PARAM_ACCESS_PROTOCOLS) String accessProtocols, @FormParam(FORM_PARAM_VOLUME_OPTIONS) String options) { if(clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } String missingParam = checkMissingParamsForCreateVolume(volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options); if(missingParam != null) { - return notFoundResponse("Parameter [" + missingParam + "] is missing in request!"); + return badRequestResponse("Parameter [" + missingParam + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { @@ -192,11 +192,11 @@ public class VolumesResource extends AbstractResource { } if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_MIRROR) && replicaCount <= 0) { - return notFoundResponse("Replica count must be a positive integer"); + return badRequestResponse("Replica count must be a positive integer"); } if (volumeType.equals(VOLUME_TYPE.DISTRIBUTED_STRIPE) && stripeCount <= 0) { - return notFoundResponse("Stripe count must be a positive integer"); + return badRequestResponse("Stripe count must be a positive integer"); } GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); @@ -270,7 +270,7 @@ public class VolumesResource extends AbstractResource { Volume volume = null; if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -314,11 +314,11 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_MIGRATE_DATA) Boolean isMigrateData, @FormParam(FORM_PARAM_FORCED_DATA_MIGRATE) Boolean isForcedDataMigrate) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -373,11 +373,11 @@ public class VolumesResource extends AbstractResource { @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_DELETE_OPTION) Boolean deleteFlag) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty"); + return badRequestResponse("Cluster name must not be empty"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty"); + return badRequestResponse("Volume name must not be empty"); } if (clusterService.getCluster(clusterName) == null) { @@ -422,15 +422,15 @@ public class VolumesResource extends AbstractResource { List brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query // parameter) if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (bricks == null || bricks.isEmpty()) { - return notFoundResponse("Parameter [" + QUERY_PARAM_BRICKS + "] is missing in request!"); + return badRequestResponse("Parameter [" + QUERY_PARAM_BRICKS + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { @@ -525,19 +525,19 @@ public class VolumesResource extends AbstractResource { @FormParam(RESTConstants.FORM_PARAM_OPTION_KEY) String key, @FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if(volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if(key == null || key.isEmpty()) { - return notFoundResponse("Parameter [" + FORM_PARAM_OPTION_KEY + "] is missing in request!"); + return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_KEY + "] is missing in request!"); } if(value == null || value.isEmpty()) { - return notFoundResponse("Parameter [" + FORM_PARAM_OPTION_VALUE + "] is missing in request!"); + return badRequestResponse("Parameter [" + FORM_PARAM_OPTION_VALUE + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { @@ -575,11 +575,11 @@ public class VolumesResource extends AbstractResource { public Response resetOptions(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if(volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -661,11 +661,11 @@ public class VolumesResource extends AbstractResource { public Response downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -753,11 +753,11 @@ public class VolumesResource extends AbstractResource { public Response getLogs(String clusterName, String volumeName, String brickName, String severity, String fromTimestamp, String toTimestamp, Integer lineCount, String mediaType) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (clusterService.getCluster(clusterName) == null) { @@ -854,15 +854,15 @@ public class VolumesResource extends AbstractResource { public Response addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_BRICKS) String bricks) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (bricks == null || bricks.isEmpty()) { - return notFoundResponse("Parameter [" + FORM_PARAM_BRICKS + "] is missing in request!"); + return badRequestResponse("Parameter [" + FORM_PARAM_BRICKS + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { @@ -903,19 +903,19 @@ public class VolumesResource extends AbstractResource { @FormParam(FORM_PARAM_TARGET) String toBrick, @FormParam(FORM_PARAM_AUTO_COMMIT) Boolean autoCommit) { if (clusterName == null || clusterName.isEmpty()) { - return notFoundResponse("Cluster name must not be empty!"); + return badRequestResponse("Cluster name must not be empty!"); } if (volumeName == null || volumeName.isEmpty()) { - return notFoundResponse("Volume name must not be empty!"); + return badRequestResponse("Volume name must not be empty!"); } if (fromBrick == null || fromBrick.isEmpty()) { - return notFoundResponse("Parameter [" + FORM_PARAM_SOURCE + "] is missing in request!"); + return badRequestResponse("Parameter [" + FORM_PARAM_SOURCE + "] is missing in request!"); } if (toBrick == null || toBrick.isEmpty()) { - return notFoundResponse("Parameter [" + FORM_PARAM_TARGET + "] is missing in request!"); + return badRequestResponse("Parameter [" + FORM_PARAM_TARGET + "] is missing in request!"); } if (clusterService.getCluster(clusterName) == null) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java index 5b70d7a8..f696a823 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java @@ -100,7 +100,7 @@ public class RebalanceVolumeTask extends Task { ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { - if (processResult.getOutput().trim().matches("Rebalance completed!")) { + if (processResult.getOutput().trim().matches(".*rebalance completed$")) { taskStatus.setCode(Status.STATUS_CODE_SUCCESS); } else { taskStatus.setCode(Status.STATUS_CODE_RUNNING); 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 aa44b016..c2da8d6c 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 @@ -562,7 +562,6 @@ public class GlusterUtil { int status = rebalanceTask.getTaskInfo().getStatus().getCode(); if(status != Status.STATUS_CODE_FAILURE) { - TasksResource taskResource = new TasksResource(); taskResource.addTask(rebalanceTask); } else { throw new GlusterRuntimeException( rebalanceTask.getTaskInfo().getStatus().getMessage()); -- cgit From 9ff4f7270ba883d0f7f6be466e522c09beab44ed Mon Sep 17 00:00:00 2001 From: Selvasundaram Date: Wed, 29 Jun 2011 21:51:41 +0530 Subject: Task frame work code changes --- .../.classpath | 4 +- .../storage/management/client/AbstractClient.java | 33 +++- .../storage/management/client/TasksClient.java | 9 +- .../storage/management/client/UsersClient.java | 26 +-- .../storage/management/client/VolumesClient.java | 8 +- .../storage/management/core/model/Task.java | 86 --------- .../management/gui/dialogs/MigrateDiskWizard.java | 19 +- .../server/resources/AbstractResource.java | 14 +- .../server/resources/AbstractServersResource.java | 19 +- .../resources/DiscoveredServersResource.java | 2 +- .../server/resources/GlusterServersResource.java | 75 ++------ .../management/server/resources/TasksResource.java | 6 +- .../server/resources/VolumesResource.java | 214 ++++++++------------- .../management/server/services/ClusterService.java | 56 +++++- .../server/tasks/InitializeDiskTask.java | 11 +- .../management/server/tasks/MigrateDiskTask.java | 73 +++++-- .../server/tasks/RebalanceVolumeTask.java | 52 +++-- .../storage/management/server/tasks/Task.java | 110 +++++++++++ .../management/server/utils/GlusterUtil.java | 59 ------ .../management/server/utils/ServerUtil.java | 17 ++ 20 files changed, 456 insertions(+), 437 deletions(-) delete mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/.classpath b/src/com.gluster.storage.management.client/.classpath index d216a8fe..218503d5 100644 --- a/src/com.gluster.storage.management.client/.classpath +++ b/src/com.gluster.storage.management.client/.classpath @@ -1,8 +1,8 @@ - - + + diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java index 14539b87..6f4ba050 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java @@ -22,6 +22,7 @@ import javax.ws.rs.core.MultivaluedMap; import com.gluster.storage.management.client.utils.ClientUtil; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.TaskInfo; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.UniformInterfaceException; @@ -41,6 +42,7 @@ public abstract class AbstractClient { protected WebResource resource; private String securityToken; private String authHeader; + private Client client; /** * This constructor will work only after the data model manager has been initialized. @@ -61,11 +63,16 @@ public abstract class AbstractClient { this.clusterName = clusterName; setSecurityToken(securityToken); - SSLContext context = initializeSSLContext(); - DefaultClientConfig config = createClientConfig(context); + createClient(); // this must be after setting clusterName as sub-classes may refer to cluster name in the getResourcePath method - resource = Client.create(config).resource(ClientUtil.getServerBaseURI()).path(getResourcePath()); + resource = client.resource(ClientUtil.getServerBaseURI()).path(getResourcePath()); + } + + private void createClient() { + SSLContext context = initializeSSLContext(); + DefaultClientConfig config = createClientConfig(context); + client = Client.create(config); } private DefaultClientConfig createClientConfig(SSLContext context) { @@ -123,7 +130,7 @@ public abstract class AbstractClient { * @return Object of responseClass received as a result of the GET request */ @SuppressWarnings({ "unchecked", "rawtypes" }) - private Object fetchResource(WebResource res, MultivaluedMap queryParams, Class responseClass) { + private T fetchResource(WebResource res, MultivaluedMap queryParams, Class responseClass) { try { return res.queryParams(queryParams) .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML).get(responseClass); @@ -267,7 +274,11 @@ public abstract class AbstractClient { private ClientResponse putRequest(WebResource resource, Form form) { try { - return prepareFormRequestBuilder(resource).put(ClientResponse.class, form); + ClientResponse response = prepareFormRequestBuilder(resource).put(ClientResponse.class, form); + if(response.getStatus() >= 300) { + throw new GlusterRuntimeException(response.getEntity(String.class)); + } + return response; } catch (UniformInterfaceException e) { throw new GlusterRuntimeException(e.getResponse().getEntity(String.class)); } @@ -292,7 +303,8 @@ public abstract class AbstractClient { protected URI putRequestURI(String subResourceName, Form form) { - return putRequest(resource.path(subResourceName), form).getLocation(); + ClientResponse response = putRequest(resource.path(subResourceName), form); + return response.getLocation(); } /** @@ -361,4 +373,13 @@ public abstract class AbstractClient { this.securityToken = securityToken; authHeader = "Basic " + securityToken; } + + /** + * @param uri The URI to be fetched using GET API + * @param responseClass Expected type of response object + * @return Object of the given class + */ + protected T fetchResource(URI uri, Class responseClass) { + return fetchResource(client.resource(uri), NO_PARAMS, responseClass); + } } 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 aff4f5d2..deaeee64 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 @@ -20,12 +20,13 @@ */ package com.gluster.storage.management.client; +import java.net.URI; import java.util.List; import javax.ws.rs.core.MultivaluedMap; +import com.gluster.storage.management.client.utils.ClientUtil; import com.gluster.storage.management.core.constants.RESTConstants; -import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.response.TaskInfoListResponse; import com.sun.jersey.api.representation.Form; @@ -86,7 +87,11 @@ public class TasksClient extends AbstractClient { public void deleteTask(String taskId) { MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_DELETE); - + deleteSubResource(taskId, queryParams); } + + public TaskInfo getTaskInfo(URI uri) { + return ((TaskInfo) fetchResource(uri, TaskInfo.class)); + } } diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java index 522b87c1..c839a15a 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java @@ -80,18 +80,20 @@ public class UsersClient extends AbstractClient { } public static void main(String[] args) { - UsersClient authClient = new UsersClient(); - - // authenticate user - authClient.authenticate("gluster", "gluster"); - - // change password to gluster1 - authClient.changePassword("gluster", "gluster", "gluster1"); - - // change it back to gluster - authClient.changePassword("gluster", "gluster1", "gluster"); - - System.out.println("success"); +// UsersClient authClient = new UsersClient(); +// +// // authenticate user +// authClient.authenticate("gluster", "gluster"); +// +// // change password to gluster1 +// authClient.changePassword("gluster", "gluster", "gluster1"); +// +// // change it back to gluster +// authClient.changePassword("gluster", "gluster1", "gluster"); +// +// System.out.println("success"); + System.out.println(new String(Base64.encode("abcdefghijklmnopqrstuvwxyz"))); + System.out.println(new String(Base64.decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="))); } /* diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index 6be67e65..b5d2711a 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -40,6 +40,7 @@ import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.GlusterConstants; import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.model.VolumeOptionInfo; @@ -222,16 +223,13 @@ public class VolumesClient extends AbstractClient { return queryParams; } - public void startMigration(String volumeName, String brickFrom, String brickTo, Boolean autoCommit) { + public URI startMigration(String volumeName, String brickFrom, String brickTo, Boolean autoCommit) { Form form = new Form(); form.add(RESTConstants.FORM_PARAM_SOURCE, brickFrom); form.add(RESTConstants.FORM_PARAM_TARGET, brickTo); form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_START); form.add(RESTConstants.FORM_PARAM_AUTO_COMMIT, autoCommit); - - // putRequest(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); - URI uri = putRequestURI(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); - System.out.println(uri.getRawPath()); + return putRequestURI(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form); } public void rebalanceStart(String volumeName, Boolean fixLayout, Boolean migrateData, Boolean forcedDataMigrate) { 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 deleted file mode 100644 index b7823c4b..00000000 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Task.java - * - * Copyright (c) 2011 Gluster, Inc. - * 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 - * . - */ -package com.gluster.storage.management.core.model; - -import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE; - -public abstract class Task { - public String[] TASK_TYPE_STR = { "Format Disk", "Migrate Brick", "Volume Rebalance" }; - - protected TaskInfo taskInfo; - - protected String serverName; - - public Task(TASK_TYPE type, String reference, String desc, boolean canPause, boolean canStop, boolean canCommit) { - taskInfo = new TaskInfo(); - taskInfo.setType(type); - 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) { - setTaskInfo(taskInfo); - } - - public String getTypeStr() { - return TASK_TYPE_STR[taskInfo.getType().ordinal()]; - } - - public TASK_TYPE getType() { - return getTaskInfo().getType(); - } - - public String getOnlineServer() { - return serverName; - } - - public void setOnlineServer(String serverName) { - this.serverName = serverName; - } - - public TaskInfo getTaskInfo() { - return taskInfo; - } - - public void setTaskInfo(TaskInfo info) { - this.taskInfo = info; - } - - public abstract String getId(); - - public abstract void start(); - - public abstract void resume(); - - public abstract void stop(); - - 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.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java index 514f805e..2d65a869 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java @@ -18,12 +18,16 @@ *******************************************************************************/ package com.gluster.storage.management.gui.dialogs; +import java.net.URI; + import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.wizard.Wizard; +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.TasksClient; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Brick; -import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.model.Volume; public class MigrateDiskWizard extends Wizard { @@ -53,10 +57,15 @@ public class MigrateDiskWizard extends Wizard { VolumesClient volumesClient = new VolumesClient(); try { - volumesClient.startMigration(volume.getName(), sourceDir, targetDir, autoCommit); - MessageDialog.openInformation(getShell(), "Brick migration", - "Brick migration is initiated, Please check the status..."); - //TODO Add the task to model + URI uri = volumesClient.startMigration(volume.getName(), sourceDir, targetDir, autoCommit); + + // To get the object + TasksClient taskClient = new TasksClient(); + TaskInfo taskInfo = taskClient.getTaskInfo(uri); + if (taskInfo != null && taskInfo instanceof TaskInfo) { + GlusterDataModelManager.getInstance().getModel().getCluster().addTaskInfo(taskInfo); + } + MessageDialog.openInformation(getShell(), "Brick migration", "Brick migration started successfully"); } catch (Exception e) { MessageDialog.openError(getShell(), "Error: Migrate brick", e.getMessage()); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java index 6bc394c3..feef8b3e 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java @@ -65,12 +65,12 @@ public class AbstractResource { * Creates a response with HTTP status code of 202 (accepted), also setting the location header to given location. * This is typically done while triggering long running tasks * - * @param uriElements - * URI Elements to be appended to the base URI + * @param locationURI + * URI to be appended to the base URI * @return the {@link Response} object */ - protected Response acceptedResponse(Object...uriElements) { - return Response.status(Status.ACCEPTED).location(createAbsoluteURI(uriElements)).build(); + protected Response acceptedResponse(String locationURI) { + return Response.status(Status.ACCEPTED).location(createAbsoluteURI(locationURI)).build(); } /** @@ -86,11 +86,11 @@ public class AbstractResource { /** * Creates a new URI that is relative to the base URI of the application - * @param uriElements URI Elements to be appended to the base URI + * @param uriString URI String to be appended to the base URI * @return newly created URI */ - private URI createAbsoluteURI(Object[] uriElements) { - return uriInfo.getBaseUriBuilder().build(uriElements); + private URI createAbsoluteURI(String uriString) { + return uriInfo.getBaseUriBuilder().path(uriString).build(); } /** diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java index 0bc0f061..dd6e2804 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java @@ -20,9 +20,6 @@ */ package com.gluster.storage.management.server.resources; -import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; -import com.gluster.storage.management.core.model.Server; -import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.ServerUtil; import com.sun.jersey.api.core.InjectParam; @@ -37,19 +34,5 @@ public class AbstractServersResource extends AbstractResource { @InjectParam protected GlusterUtil glusterUtil; - /** - * Fetch details of the given server. The server name must be populated in the object before calling this method. - * - * @param server - * Server whose details are to be fetched - */ - protected void fetchServerDetails(Server server) { - // fetch standard server details like cpu, disk, memory details - Object response = serverUtil.executeOnServer(true, server.getName(), "get_server_details.py --only-data-disks", Server.class); - if (response instanceof Status) { - // TODO: check if this happened because the server is not reachable, and if yes, set it's status as offline - throw new GlusterRuntimeException(((Status)response).getMessage()); - } - server.copyFrom((Server) response); // Update the details in object - } + // TODO: Remove this class! } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java index ee9d3600..283ab147 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java @@ -130,7 +130,7 @@ public class DiscoveredServersResource extends AbstractServersResource { private Server getDiscoveredServer(String serverName) { Server server = new Server(serverName); - fetchServerDetails(server); + serverUtil.fetchServerDetails(server); return server; } 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 0a77a8ab..a9ef7fbb 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 @@ -22,10 +22,10 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; -import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; import java.util.ArrayList; import java.util.List; @@ -50,11 +50,7 @@ import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; 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.TaskInfo; import com.gluster.storage.management.core.response.GlusterServerListResponse; -import com.gluster.storage.management.core.response.TaskResponse; -import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.services.ClusterService; @@ -70,7 +66,6 @@ import com.sun.jersey.spi.resource.Singleton; public class GlusterServersResource extends AbstractServersResource { public static final String HOSTNAMETAG = "hostname:"; - private LRUCache clusterServerCache = new LRUCache(3); @InjectParam private DiscoveredServersResource discoveredServersResource; @@ -87,50 +82,12 @@ public class GlusterServersResource extends AbstractServersResource { protected void fetchServerDetails(GlusterServer server) { try { server.setStatus(SERVER_STATUS.ONLINE); - super.fetchServerDetails(server); + serverUtil.fetchServerDetails(server); } catch (ConnectionException e) { server.setStatus(SERVER_STATUS.OFFLINE); } } - public GlusterServer getOnlineServer(String clusterName) { - return getOnlineServer(clusterName, ""); - } - - // uses cache - public GlusterServer getOnlineServer(String clusterName, String exceptServerName) { - GlusterServer server = clusterServerCache.get(clusterName); - if (server != null && !server.getName().equals(exceptServerName)) { - return server; - } - - return getNewOnlineServer(clusterName, exceptServerName); - } - - public GlusterServer getNewOnlineServer(String clusterName) { - return getNewOnlineServer(clusterName, ""); - } - - // Doesn't use cache - public GlusterServer getNewOnlineServer(String clusterName, String exceptServerName) { - ClusterInfo cluster = clusterService.getCluster(clusterName); - if (cluster == null) { - return null; - } - - for (ServerInfo serverInfo : cluster.getServers()) { - GlusterServer server = new GlusterServer(serverInfo.getName()); - fetchServerDetails(server); - if (server.isOnline() && !server.getName().equals(exceptServerName)) { - // server is online. add it to cache and return - clusterServerCache.put(clusterName, server); - return server; - } - } - - // no online server found. - return null; - } @GET @Produces(MediaType.APPLICATION_JSON) @@ -160,7 +117,7 @@ public class GlusterServersResource extends AbstractServersResource { return okResponse(new GlusterServerListResponse(glusterServers), mediaType); } - GlusterServer onlineServer = getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -169,7 +126,7 @@ public class GlusterServersResource extends AbstractServersResource { glusterServers = getGlusterServers(clusterName, onlineServer); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -211,7 +168,7 @@ public class GlusterServersResource extends AbstractServersResource { glusterServers = glusterUtil.getGlusterServers(onlineServer); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -259,7 +216,7 @@ public class GlusterServersResource extends AbstractServersResource { throw new GlusterRuntimeException("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -269,7 +226,7 @@ public class GlusterServersResource extends AbstractServersResource { server = glusterUtil.getGlusterServer(onlineServer, serverName); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -283,7 +240,7 @@ public class GlusterServersResource extends AbstractServersResource { } private void performAddServer(String clusterName, String serverName) { - GlusterServer onlineServer = getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } @@ -292,7 +249,7 @@ public class GlusterServersResource extends AbstractServersResource { glusterUtil.addServer(onlineServer.getName(), serverName); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } @@ -388,7 +345,7 @@ public class GlusterServersResource extends AbstractServersResource { if (servers.size() == 1) { // Only one server mapped to the cluster, no "peer detach" required. // remove the cached online server for this cluster if present - clusterServerCache.remove(clusterName); + clusterService.removeOnlineServer(clusterName); } else { try { removeServerFromCluster(clusterName, serverName); @@ -402,7 +359,7 @@ public class GlusterServersResource extends AbstractServersResource { private void removeServerFromCluster(String clusterName, String serverName) { // get an online server that is not same as the server being removed - GlusterServer onlineServer = getOnlineServer(clusterName, serverName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName, serverName); if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } @@ -411,7 +368,7 @@ public class GlusterServersResource extends AbstractServersResource { glusterUtil.removeServer(onlineServer.getName(), serverName); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = getNewOnlineServer(clusterName, serverName); + onlineServer = clusterService.getNewOnlineServer(clusterName, serverName); if (onlineServer == null) { throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); } @@ -420,7 +377,7 @@ public class GlusterServersResource extends AbstractServersResource { if (onlineServer.getName().equals(serverName)) { // since the cached server has been removed from the cluster, remove it from the cache - clusterServerCache.remove(clusterName); + clusterService.removeOnlineServer(clusterName); } clusterService.unmapServerFromCluster(clusterName, serverName); @@ -457,12 +414,12 @@ public class GlusterServersResource extends AbstractServersResource { return badRequestResponse("Disk name must not be empty!"); } - InitializeDiskTask initializeTask = new InitializeDiskTask(diskName, serverName); + InitializeDiskTask initializeTask = new InitializeDiskTask(clusterService, clusterName, diskName, serverName); try { initializeTask.start(); taskResource.addTask(initializeTask); - return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, - initializeTask.getId()); + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + RESOURCE_TASKS + + "/" + initializeTask.getId()); } catch (ConnectionException e) { return errorResponse(e.getMessage()); } 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 44d86b1b..834033d0 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 @@ -45,9 +45,9 @@ 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.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.TaskInfoListResponse; +import com.gluster.storage.management.server.tasks.Task; import com.sun.jersey.spi.resource.Singleton; @Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_TASKS) @@ -130,8 +130,8 @@ public class TasksResource extends AbstractResource { task.commit(); } // updateTask(taskId, taskOperation); - return (Response) acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, - taskId); + return (Response) acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + + RESOURCE_TASKS + "/" + taskId); } catch(GlusterValidationException ve) { return badRequestResponse(ve.getMessage()); } catch (GlusterRuntimeException e) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 0f3fbb95..107d4fb2 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -23,6 +23,9 @@ package com.gluster.storage.management.server.resources; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_ACCESS_PROTOCOLS; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_AUTO_COMMIT; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_BRICKS; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FIX_LAYOUT; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FORCED_DATA_MIGRATE; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_MIGRATE_DATA; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPERATION; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_KEY; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_OPTION_VALUE; @@ -54,9 +57,6 @@ import static com.gluster.storage.management.core.constants.RESTConstants.RESOUR import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_VOLUMES; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_START; import static com.gluster.storage.management.core.constants.RESTConstants.TASK_STOP; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FIX_LAYOUT; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_MIGRATE_DATA; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FORCED_DATA_MIGRATE; import java.io.File; import java.io.IOException; @@ -89,6 +89,7 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeLogMessage; @@ -101,6 +102,8 @@ import com.gluster.storage.management.core.utils.FileUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; import com.gluster.storage.management.server.services.ClusterService; +import com.gluster.storage.management.server.tasks.MigrateDiskTask; +import com.gluster.storage.management.server.tasks.RebalanceVolumeTask; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.ServerUtil; import com.sun.jersey.api.core.InjectParam; @@ -109,13 +112,9 @@ import com.sun.jersey.spi.resource.Singleton; @Singleton @Path(RESOURCE_PATH_CLUSTERS + "/{" + PATH_PARAM_CLUSTER_NAME + "}/" + RESOURCE_VOLUMES) public class VolumesResource extends AbstractResource { - private static final String PREPARE_BRICK_SCRIPT = "create_volume_directory.py"; private static final String VOLUME_DIRECTORY_CLEANUP_SCRIPT = "clear_volume_directory.py"; private static final String VOLUME_BRICK_LOG_SCRIPT = "get_volume_brick_log.py"; - @InjectParam - private GlusterServersResource glusterServersResource; - @InjectParam private ServerUtil serverUtil; @@ -128,6 +127,9 @@ public class VolumesResource extends AbstractResource { @InjectParam private VolumeOptionsDefaults volumeOptionsDefaults; + @InjectParam + private TasksResource taskResource; + @GET @Produces({MediaType.APPLICATION_XML}) public Response getVolumesXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { @@ -153,7 +155,7 @@ public class VolumesResource extends AbstractResource { } public VolumeListResponse getVolumes(String clusterName) { - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return new VolumeListResponse(new ArrayList()); } @@ -162,7 +164,7 @@ public class VolumesResource extends AbstractResource { return new VolumeListResponse(glusterUtil.getAllVolumes(onlineServer.getName())); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return new VolumeListResponse(new ArrayList()); } @@ -199,7 +201,7 @@ public class VolumesResource extends AbstractResource { return badRequestResponse("Stripe count must be a positive integer"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -209,7 +211,7 @@ public class VolumesResource extends AbstractResource { return createdResponse(volumeName); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -287,7 +289,7 @@ public class VolumesResource extends AbstractResource { private Volume getVolume(String clusterName, String volumeName) { Volume volume; - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -296,7 +298,7 @@ public class VolumesResource extends AbstractResource { volume = glusterUtil.getVolume(volumeName, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -325,36 +327,35 @@ public class VolumesResource extends AbstractResource { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); - } - - if (operation.equals(RESTConstants.TASK_REBALANCE_START)) { - return rebalanceStart(clusterName, volumeName, isFixLayout, isMigrateData, isForcedDataMigrate); - } else if (operation.equals(RESTConstants.TASK_REBALANCE_STATUS)) { - return rebalanceStatus(clusterName, volumeName); - } else if (operation.equals(RESTConstants.TASK_REBALANCE_STOP)) { - return rebalanceStop(clusterName, volumeName); + try { + if (operation.equals(RESTConstants.TASK_REBALANCE_START)) { + String taskId = rebalanceStart(clusterName, volumeName, isFixLayout, isMigrateData, isForcedDataMigrate); + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + RESOURCE_TASKS + + "/" + taskId); + } else if (operation.equals(RESTConstants.TASK_REBALANCE_STOP)) { + rebalanceStop(clusterName, volumeName); + } else { + performVolumeOperation(clusterName, volumeName, operation); + } + return noContentResponse(); + } catch(Exception e) { + return errorResponse(e.getMessage()); } - + } + + private void performVolumeOperation(String clusterName, String volumeName, String operation) { + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); try { - performOperation(volumeName, operation, onlineServer); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); - } - - try { - performOperation(volumeName, operation, onlineServer); - } catch(Exception e1) { - // TODO: Log the exception - return errorResponse(e1.getMessage()); + throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } + + performOperation(volumeName, operation, onlineServer); + } catch (ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = clusterService.getNewOnlineServer(clusterName); + performOperation(volumeName, operation, onlineServer); } - return noContentResponse(); } private Status performOperation(String volumeName, String operation, GlusterServer onlineServer) { @@ -397,7 +398,7 @@ public class VolumesResource extends AbstractResource { } List bricks = volume.getBricks(); - Status status = glusterUtil.deleteVolume(volumeName, glusterServersResource.getOnlineServer(clusterName) + Status status = glusterUtil.deleteVolume(volumeName, clusterService.getOnlineServer(clusterName) .getName()); if(!status.isSuccess()) { return errorResponse("Couldn't delete volume [" + volumeName + "]. Error: " + status); @@ -441,7 +442,7 @@ public class VolumesResource extends AbstractResource { deleteFlag = false; } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -467,7 +468,7 @@ public class VolumesResource extends AbstractResource { glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } @@ -544,7 +545,7 @@ public class VolumesResource extends AbstractResource { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -553,7 +554,7 @@ public class VolumesResource extends AbstractResource { glusterUtil.setOption(volumeName, key, value, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -586,7 +587,7 @@ public class VolumesResource extends AbstractResource { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -595,7 +596,7 @@ public class VolumesResource extends AbstractResource { glusterUtil.resetOptions(volumeName, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -869,7 +870,7 @@ public class VolumesResource extends AbstractResource { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -879,7 +880,7 @@ public class VolumesResource extends AbstractResource { glusterUtil.addBricks(volumeName, brickList, onlineServer.getName()); } catch (ConnectionException e) { // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); + onlineServer = clusterService.getNewOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -922,7 +923,7 @@ public class VolumesResource extends AbstractResource { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { return errorResponse("No online servers found in cluster [" + clusterName + "]"); } @@ -933,109 +934,54 @@ public class VolumesResource extends AbstractResource { String taskId = null; try { - taskId = glusterUtil.migrateBrickStart(volumeName, fromBrick, toBrick, autoCommit, onlineServer.getName()); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - - try { - taskId = glusterUtil.migrateBrickStart(volumeName, fromBrick, toBrick, autoCommit, onlineServer.getName()); - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } - } catch(Exception e1) { - return errorResponse(e1.getMessage()); + taskId = migrateBrickStart(clusterName, volumeName, fromBrick, toBrick, autoCommit); + }catch(Exception e) { + return errorResponse(e.getMessage()); } - return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + RESOURCE_TASKS + "/" + + taskId); + } + + private String migrateBrickStart(String clusterName, String volumeName, String fromBrick, String toBrick, + Boolean autoCommit) { + MigrateDiskTask migrateDiskTask = new MigrateDiskTask(clusterService, clusterName, volumeName, fromBrick, + toBrick); + migrateDiskTask.setAutoCommit(autoCommit); + migrateDiskTask.start(); + taskResource.addTask(migrateDiskTask); + return migrateDiskTask.getId(); } - private Response rebalanceStart(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, + private String rebalanceStart(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, Boolean isForcedDataMigrate) { - - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if (onlineServer == null) { - return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); - } - String layout = ""; - String taskId = null; if (isForcedDataMigrate) { - layout = "forced-data-migrate = true"; + layout = "forced-data-migrate"; } else if (isMigrateData) { - layout = "migrate-data = true"; + layout = "migrate-data"; } else if (isFixLayout) { - layout = "fix-layout = true"; + layout = "fix-layout"; } - try { - taskId = glusterUtil.rebalanceStart(volumeName, layout, onlineServer.getName()); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - - try { - taskId = glusterUtil.rebalanceStart(volumeName, layout, onlineServer.getName()); - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } - - return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + return rebalanceStart(clusterName, volumeName, layout); } - private Response rebalanceStatus(String clusterName, String volumeName) { - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if (onlineServer == null) { - return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); - } - - String taskId = null; - try { - taskId = glusterUtil.rebalanceStatus(volumeName, onlineServer.getName()); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - - try { - taskId = glusterUtil.rebalanceStatus(volumeName, onlineServer.getName()); - } catch (Exception e1) { - return errorResponse(e1.getMessage()); - } - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } - - return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + public String rebalanceStart(String clusterName, String volumeName, String layout) { + RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(clusterService, clusterName, volumeName); + rebalanceTask.setLayout(layout); + rebalanceTask.start(); + taskResource.addTask(rebalanceTask); + return rebalanceTask.getId(); } - private Response rebalanceStop(String clusterName, String volumeName) { - GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if (onlineServer == null) { - return notFoundResponse("No online servers found in cluster [" + clusterName + "]"); - } + public void rebalanceStop(String clusterName, String volumeName) { + // TODO: arrive at the task id and fetch it + String taskId = ""; - String taskId = null; - try { - taskId = glusterUtil.rebalanceStop(volumeName, onlineServer.getName()); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - - try { - taskId = glusterUtil.rebalanceStop(volumeName, onlineServer.getName()); - } catch (Exception e1) { - return errorResponse(e1.getMessage()); - } - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } - - return acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS, clusterName, RESOURCE_TASKS, taskId); + taskResource.getTask(taskId).stop(); } - + public static void main(String[] args) throws ClassNotFoundException { VolumesResource vr = new VolumesResource(); // VolumeListResponse response = vr.getAllVolumes(); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java index bb379de6..42bfc736 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java @@ -35,13 +35,13 @@ import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.GlusterServer; -import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.PersistenceDao; import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.utils.GlusterUtil; +import com.gluster.storage.management.server.utils.ServerUtil; import com.gluster.storage.management.server.utils.SshUtil; -import com.sun.jersey.api.core.InjectParam; /** * Service class for functionality related to clusters @@ -60,6 +60,58 @@ public class ClusterService { @Autowired private SshUtil sshUtil; + @Autowired + private ServerUtil serverUtil; + + private LRUCache onlineServerCache = new LRUCache(3); + + public void addOnlineServer(String clusterName, GlusterServer server) { + onlineServerCache.put(clusterName, server); + } + + public void removeOnlineServer(String clusterName) { + onlineServerCache.remove(clusterName); + } + + // uses cache + public GlusterServer getOnlineServer(String clusterName, String exceptServerName) { + GlusterServer server = getOnlineServer(clusterName); + if (server != null && !server.getName().equals(exceptServerName)) { + return server; + } + + return getNewOnlineServer(clusterName, exceptServerName); + } + + public GlusterServer getNewOnlineServer(String clusterName) { + return getNewOnlineServer(clusterName, ""); + } + + public GlusterServer getOnlineServer(String clusterName) { + return getOnlineServer(clusterName, ""); + } + + // Doesn't use cache + public GlusterServer getNewOnlineServer(String clusterName, String exceptServerName) { + ClusterInfo cluster = getCluster(clusterName); + if (cluster == null) { + throw new GlusterRuntimeException("Cluster [" + clusterName + "] is not found!"); + } + + for (ServerInfo serverInfo : cluster.getServers()) { + GlusterServer server = new GlusterServer(serverInfo.getName()); + serverUtil.fetchServerDetails(server); + if (server.isOnline() && !server.getName().equals(exceptServerName)) { + // server is online. add it to cache and return + addOnlineServer(clusterName, server); + return server; + } + } + + // no online server found. + throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]"); + } + public List getAllClusters() { return clusterDao.findAll(); } 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 018cd301..5f3f8e30 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 @@ -21,10 +21,10 @@ 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.services.ClusterService; import com.gluster.storage.management.server.utils.SshUtil; public class InitializeDiskTask extends Task { @@ -36,15 +36,16 @@ public class InitializeDiskTask extends Task { private String diskName; private SshUtil sshUtil = new SshUtil(); - public InitializeDiskTask( String serverName, String diskName) { - super(TASK_TYPE.DISK_FORMAT, diskName, "Initialize disk " + serverName + ":" + diskName, false, false, false); + public InitializeDiskTask(ClusterService clusterService, String clusterName, String serverName, String diskName) { + super(clusterService, clusterName, TASK_TYPE.DISK_FORMAT, diskName, "Initialize disk " + serverName + ":" + + diskName, false, false, false); setServerName(serverName); setDiskName(diskName); } - public InitializeDiskTask(TaskInfo info) { - super(info); + public InitializeDiskTask(ClusterService clusterService, String clusterName, TaskInfo info) { + super(clusterService, clusterName, info); } @Override 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 0b1b67e4..9a31d468 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,13 +20,15 @@ */ package com.gluster.storage.management.server.tasks; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.GlusterServer; 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.services.ClusterService; import com.gluster.storage.management.server.utils.SshUtil; public class MigrateDiskTask extends Task { @@ -61,15 +63,15 @@ public class MigrateDiskTask extends Task { this.autoCommit = autoCommit; } - 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); + public MigrateDiskTask(ClusterService clusterService, String clusterName, String volumeName, String fromBrick, String toBrick) { + super(clusterService, clusterName, TASK_TYPE.BRICK_MIGRATE, volumeName, "Brick Migration on volume [" + + volumeName + "] from [" + fromBrick + "] to [" + toBrick + "]", true, true, true); setFromBrick(fromBrick); setToBrick(toBrick); } - public MigrateDiskTask(TaskInfo info) { - super(info); + public MigrateDiskTask(ClusterService clusterService, String clusterName, TaskInfo info) { + super(clusterService, clusterName, info); } @Override @@ -79,31 +81,48 @@ public class MigrateDiskTask extends Task { @Override public void start() { + try { + startMigration(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + startMigration(getNewOnlineServer().getName()); + } + } + + private void startMigration(String onlineServerName) { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " start"; - ProcessResult processResult = sshUtil.executeRemote(serverName, command); - TaskStatus taskStatus = new TaskStatus(); + ProcessResult processResult = sshUtil.executeRemote(onlineServerName, command); + + System.out.println(command); + System.out.println("[" + processResult.getExitValue() + "] " + processResult.getOutput() ); + if (processResult.isSuccess()) { if (processResult.getOutput().trim().matches(".*started successfully$")) { - taskStatus.setCode(Status.STATUS_CODE_RUNNING); - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); + getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput()))); + return; } - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); } - taskStatus.setMessage(processResult.getOutput()); // Common - getTaskInfo().setStatus(taskStatus); + + // if we come here, it means task couldn't be started successfully. + throw new GlusterRuntimeException(processResult.toString()); } - - @Override public void pause() { + try { + pauseMigration(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + pauseMigration(getNewOnlineServer().getName()); + } + } + + private void pauseMigration(String onlineServer) { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " pause"; - ProcessResult processResult = sshUtil.executeRemote(serverName, command); + ProcessResult processResult = sshUtil.executeRemote(onlineServer, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { if (processResult.getOutput().matches("*pause")) { @@ -131,6 +150,15 @@ public class MigrateDiskTask extends Task { @Override public void stop() { + try { + stopMigration(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + stopMigration(getNewOnlineServer().getName()); + } + } + + private void stopMigration(String serverName) { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " abort"; @@ -152,6 +180,15 @@ public class MigrateDiskTask extends Task { @Override public TaskStatus checkStatus() { + try { + return checkMigrationStatus(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + return checkMigrationStatus(getNewOnlineServer().getName()); + } + } + + private TaskStatus checkMigrationStatus(String serverName) { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " status"; ProcessResult processResult = sshUtil.executeRemote(serverName, command); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java index f696a823..7f9fb6bf 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java @@ -20,12 +20,14 @@ */ package com.gluster.storage.management.server.tasks; +import com.gluster.storage.management.core.exceptions.ConnectionException; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; 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.services.ClusterService; import com.gluster.storage.management.server.utils.SshUtil; public class RebalanceVolumeTask extends Task { @@ -33,12 +35,12 @@ public class RebalanceVolumeTask extends Task { private String layout; private SshUtil sshUtil = new SshUtil(); - public RebalanceVolumeTask(TaskInfo taskInfo) { - super(taskInfo); + public RebalanceVolumeTask(ClusterService clusterService, String clusterName, TaskInfo taskInfo) { + super(clusterService, clusterName, taskInfo); } - public RebalanceVolumeTask(String volumeName) { - super(TASK_TYPE.VOLUME_REBALANCE, volumeName, "Volume rebalance running on " + volumeName, false, true, false); + public RebalanceVolumeTask(ClusterService clusterService, String clusterName, String volumeName) { + super(clusterService, clusterName, TASK_TYPE.VOLUME_REBALANCE, volumeName, "Volume rebalance running on " + volumeName, false, true, false); } @Override @@ -48,20 +50,25 @@ public class RebalanceVolumeTask extends Task { @Override public void start() { + try { + startRebalance(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one + startRebalance(getNewOnlineServer().getName()); + } + } + + private void startRebalance(String serverName) { String command = "gluster volume rebalance " + getTaskInfo().getReference() + " " + getLayout() + " start"; ProcessResult processResult = sshUtil.executeRemote(serverName, command); - TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { if (processResult.getOutput().trim().matches(".*has been successful$")) { - taskStatus.setCode(Status.STATUS_CODE_RUNNING); - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); + getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput()))); } - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); } - taskStatus.setMessage(processResult.getOutput()); // Common - getTaskInfo().setStatus(taskStatus); + + // if we reach here, it means rebalance start failed. + throw new GlusterRuntimeException(processResult.toString()); } @Override @@ -72,6 +79,15 @@ public class RebalanceVolumeTask extends Task { @Override public void stop() { + try { + stopRebalance(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one + stopRebalance(getNewOnlineServer().getName()); + } + } + + private void stopRebalance(String serverName) { String command = "gluster volume rebalance " + getTaskInfo().getReference() + " stop"; ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); @@ -96,6 +112,16 @@ public class RebalanceVolumeTask extends Task { @Override public TaskStatus checkStatus() { + try { + return checkRebalanceStatus(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + return checkRebalanceStatus(getNewOnlineServer().getName()); + } + } + + // TODO: This method should move to glusterUtil + private TaskStatus checkRebalanceStatus(String serverName) { String command = "gluster volume rebalance " + getTaskInfo().getReference() + " status"; ProcessResult processResult = sshUtil.executeRemote(serverName, command); TaskStatus taskStatus = new TaskStatus(); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java new file mode 100644 index 00000000..cdc56400 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java @@ -0,0 +1,110 @@ +/** + * Task.java + * + * Copyright (c) 2011 Gluster, Inc. + * 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 + * . + */ +package com.gluster.storage.management.server.tasks; + +import com.gluster.storage.management.core.exceptions.ConnectionException; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.TaskInfo; +import com.gluster.storage.management.core.model.TaskStatus; +import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE; +import com.gluster.storage.management.server.services.ClusterService; + +public abstract class Task { + public String[] TASK_TYPE_STR = { "Format Disk", "Migrate Brick", "Volume Rebalance" }; + + protected TaskInfo taskInfo; + protected String clusterName; + private ClusterService clusterService; + + public Task(ClusterService clusterService, String clusterName, TASK_TYPE type, String reference, String desc, boolean canPause, boolean canStop, boolean canCommit) { + TaskInfo taskInfo = new TaskInfo(); + taskInfo.setType(type); + 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()); + init(clusterService, clusterName, taskInfo); + } + + public Task(ClusterService clusterService, String clusterName, TaskInfo taskInfo) { + init(clusterService, clusterName, taskInfo); + } + + private void init(ClusterService clusterService, String clusterName, TaskInfo taskInfo) { + this.clusterService = clusterService; + setClusterName(clusterName); + setTaskInfo(taskInfo); + } + + protected GlusterServer getOnlineServer() { + return clusterService.getOnlineServer(clusterName); + } + + protected GlusterServer getNewOnlineServer() { + return clusterService.getNewOnlineServer(clusterName); + } + + protected GlusterServer getNewOnlineServer(String exceptServerName) { + return clusterService.getNewOnlineServer(clusterName, exceptServerName); + } + + public String getTypeStr() { + return TASK_TYPE_STR[taskInfo.getType().ordinal()]; + } + + public TASK_TYPE getType() { + return getTaskInfo().getType(); + } + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public TaskInfo getTaskInfo() { + return taskInfo; + } + + public void setTaskInfo(TaskInfo info) { + this.taskInfo = info; + } + + public abstract String getId(); + + public abstract void start(); + + public abstract void resume(); + + public abstract void stop(); + + 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.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 c2da8d6c..788e3eab 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 @@ -536,65 +536,6 @@ public class GlusterUtil { return logFileName; } - - public String migrateBrickStart(String volumeName, String fromBrick, String toBrick, Boolean autoCommit, - String knownServer) { - MigrateDiskTask migrateDiskTask = new MigrateDiskTask(volumeName, fromBrick, toBrick); - migrateDiskTask.setOnlineServer(knownServer); - migrateDiskTask.setAutoCommit(autoCommit); - 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 migrateDiskTask.getId(); - } - - public String rebalanceStart(String volumeName, String layout, String knownServer) { - - RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); - rebalanceTask.setOnlineServer(knownServer); - rebalanceTask.setLayout(layout); - rebalanceTask.start(); - int status = rebalanceTask.getTaskInfo().getStatus().getCode(); - - if(status != Status.STATUS_CODE_FAILURE) { - taskResource.addTask(rebalanceTask); - } else { - throw new GlusterRuntimeException( rebalanceTask.getTaskInfo().getStatus().getMessage()); - } - return rebalanceTask.getId(); - } - - public String rebalanceStatus(String volumeName, String knownServer) { - RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); - rebalanceTask.setOnlineServer(knownServer); - - rebalanceTask.checkStatus(); - int status = rebalanceTask.getTaskInfo().getStatus().getCode(); - - if (status == Status.STATUS_CODE_FAILURE) { - throw new GlusterRuntimeException(rebalanceTask.getTaskInfo().getStatus().getMessage()); - } - return rebalanceTask.getId(); - } - - public String rebalanceStop(String volumeName, String knownServer) { - RebalanceVolumeTask rebalanceTask = new RebalanceVolumeTask(volumeName); - rebalanceTask.setOnlineServer(knownServer); - - rebalanceTask.stop(); - int status = rebalanceTask.getTaskInfo().getStatus().getCode(); - - if (status == Status.STATUS_CODE_FAILURE) { - throw new GlusterRuntimeException(rebalanceTask.getTaskInfo().getStatus().getMessage()); - } - return rebalanceTask.getId(); - } - public Status removeBricks(String volumeName, List bricks, String knownServer) { StringBuilder command = new StringBuilder("gluster --mode=script volume remove-brick " + volumeName); for (String brickDir : bricks) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java index ed1aea75..3524d35d 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java @@ -42,6 +42,7 @@ import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.GenericResponse; import com.gluster.storage.management.core.utils.ProcessResult; @@ -76,6 +77,22 @@ public class ServerUtil { String scriptPath = servletContext.getRealPath(SCRIPT_DIR) + CoreConstants.FILE_SEPARATOR + scriptName; return scriptPath; } + + /** + * Fetch details of the given server. The server name must be populated in the object before calling this method. + * + * @param server + * Server whose details are to be fetched + */ + public void fetchServerDetails(Server server) { + // fetch standard server details like cpu, disk, memory details + Object response = executeOnServer(true, server.getName(), "get_server_details.py --only-data-disks", Server.class); + if (response instanceof Status) { + // TODO: check if this happened because the server is not reachable, and if yes, set it's status as offline + throw new GlusterRuntimeException(((Status)response).getMessage()); + } + server.copyFrom((Server) response); // Update the details in object + } /** * Executes given command on given server -- cgit From bb8929ddef5725c4ea30fca056f00605113453d9 Mon Sep 17 00:00:00 2001 From: Selvasundaram Date: Thu, 30 Jun 2011 12:34:51 +0530 Subject: login issue fix --- .../management/server/services/ClusterService.java | 20 ++++++++++++++------ .../storage/management/server/utils/ServerUtil.java | 1 - 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java index 42bfc736..b622c3a1 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java @@ -33,8 +33,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.PersistenceDao; @@ -75,7 +77,7 @@ public class ClusterService { // uses cache public GlusterServer getOnlineServer(String clusterName, String exceptServerName) { - GlusterServer server = getOnlineServer(clusterName); + GlusterServer server = onlineServerCache.get(clusterName); if (server != null && !server.getName().equals(exceptServerName)) { return server; } @@ -100,11 +102,17 @@ public class ClusterService { for (ServerInfo serverInfo : cluster.getServers()) { GlusterServer server = new GlusterServer(serverInfo.getName()); - serverUtil.fetchServerDetails(server); - if (server.isOnline() && !server.getName().equals(exceptServerName)) { - // server is online. add it to cache and return - addOnlineServer(clusterName, server); - return server; + server.setStatus(SERVER_STATUS.ONLINE); + try { + serverUtil.fetchServerDetails(server); + if (server.isOnline() && !server.getName().equals(exceptServerName)) { + // server is online. add it to cache and return + addOnlineServer(clusterName, server); + return server; + } + } catch(ConnectionException e) { + // server is offline. continue checking next one. + continue; } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java index 3524d35d..ed77def3 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java @@ -88,7 +88,6 @@ public class ServerUtil { // fetch standard server details like cpu, disk, memory details Object response = executeOnServer(true, server.getName(), "get_server_details.py --only-data-disks", Server.class); if (response instanceof Status) { - // TODO: check if this happened because the server is not reachable, and if yes, set it's status as offline throw new GlusterRuntimeException(((Status)response).getMessage()); } server.copyFrom((Server) response); // Update the details in object -- cgit From be3d2044d8269330202f84aba9a0bee6ea210fd8 Mon Sep 17 00:00:00 2001 From: Selvasundaram Date: Thu, 30 Jun 2011 20:11:01 +0530 Subject: Migrate task and UI updates --- .../management/client/GlusterDataModelManager.java | 20 +++++- .../storage/management/client/TasksClient.java | 8 ++- .../storage/management/core/model/Cluster.java | 4 ++ .../storage/management/core/model/Status.java | 1 + .../storage/management/core/model/TaskStatus.java | 2 +- src/com.gluster.storage.management.gui/plugin.xml | 16 +++++ .../management/gui/TasksTableLabelProvider.java | 4 +- .../management/gui/actions/ClearTaskAction.java | 2 +- .../management/gui/actions/CommitTaskAction.java | 54 +++++++++++++++ .../management/gui/actions/PauseTaskAction.java | 7 +- .../management/gui/actions/ResumeTaskAction.java | 7 +- .../management/gui/actions/StopTaskAction.java | 6 +- .../management/gui/views/pages/TasksPage.java | 1 + .../management/server/resources/TasksResource.java | 6 +- .../server/resources/VolumesResource.java | 8 ++- .../management/server/tasks/MigrateDiskTask.java | 80 +++++++++++++++------- .../storage/management/server/tasks/Task.java | 9 +-- 17 files changed, 181 insertions(+), 54 deletions(-) create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CommitTaskAction.java (limited to 'src') 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 87fbed31..9705501a 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 @@ -362,14 +362,28 @@ public class GlusterDataModelManager { } } - public void updateTaskStatus(TaskInfo taskInfo, Status newStatus) { - taskInfo.getStatus().setCode(newStatus.getCode()); - taskInfo.getStatus().setMessage(newStatus.getMessage()); + public void addTask(TaskInfo taskInfo) { + Cluster cluster = model.getCluster(); + cluster.addTaskInfo(taskInfo); + for (ClusterListener listener : listeners) { + listener.taskAdded(taskInfo); + } + } + + // Updating the Task + public void updateTask(TaskInfo taskInfo) { for (ClusterListener listener : listeners) { listener.taskUpdated(taskInfo); } } + public void removeTask(TaskInfo taskInfo) { + Cluster cluster = model.getCluster(); + cluster.removeTaskInfo(taskInfo); + for (ClusterListener listener : listeners) { + listener.taskAdded(taskInfo); + } + } public List getVolumeOptionsDefaults() { return volumeOptionsDefaults; 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 deaeee64..46077371 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 @@ -25,7 +25,6 @@ import java.util.List; import javax.ws.rs.core.MultivaluedMap; -import com.gluster.storage.management.client.utils.ClientUtil; import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.response.TaskInfoListResponse; @@ -76,6 +75,13 @@ public class TasksClient extends AbstractClient { putRequest(taskId, form); } + + public void commitTask(String taskId) { + Form form = new Form(); + form.add(RESTConstants.FORM_PARAM_OPERATION, RESTConstants.TASK_COMMIT); + + putRequest(taskId, form); + } public void getTaskStatus(String taskId) { Form form = new Form(); diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java index 0c094e99..d6757cba 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java @@ -115,6 +115,10 @@ public class Cluster extends Entity { public void addTaskInfo(TaskInfo taskInfo) { this.taskInfoList.add(taskInfo); } + + public void removeTaskInfo(TaskInfo taskInfo) { + this.taskInfoList.remove(taskInfo); + } public List getAlerts() { return alerts; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Status.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Status.java index 95075f78..701fe426 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Status.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Status.java @@ -31,6 +31,7 @@ public class Status { public static final int STATUS_CODE_RUNNING = 3; public static final int STATUS_CODE_PAUSE = 4; public static final int STATUS_CODE_WARNING = 5; + public static final int STATUS_CODE_COMMIT_PENDING = 6; public static final Status STATUS_SUCCESS = new Status(STATUS_CODE_SUCCESS, "Success"); public static final Status STATUS_FAILURE = new Status(STATUS_CODE_FAILURE, "Failure"); diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskStatus.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskStatus.java index 46dc7b31..c1205c0e 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskStatus.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskStatus.java @@ -22,7 +22,7 @@ package com.gluster.storage.management.core.model; public class TaskStatus extends Status { - private boolean isPercentageSupported; + private boolean isPercentageSupported = false; private float percentCompleted; private String description; diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index c5c25c33..0addb428 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -683,6 +683,22 @@ toolbarPath="Normal" tooltip="To clear selected task from task list"> + + { private static final String[] TASK_TABLE_COLUMN_NAMES = new String[] { "Task", "Status"}; + @SuppressWarnings("unchecked") public TasksPage(IWorkbenchSite site, Composite parent, int style, Object taskInfo) { super(site, parent, style, false, false, taskInfo); this.taskInfoList = (List) taskInfo; 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 834033d0..53122f11 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 @@ -126,12 +126,10 @@ public class TasksResource extends AbstractResource { task.pause(); } else if (taskOperation.equals(RESTConstants.TASK_STOP)) { task.stop(); - } else if(taskOperation.equals(RESTConstants.TASK_COMMIT)) { + } else if (taskOperation.equals(RESTConstants.TASK_COMMIT)) { task.commit(); } - // updateTask(taskId, taskOperation); - return (Response) acceptedResponse(RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" - + RESOURCE_TASKS + "/" + taskId); + return (Response) noContentResponse(); } catch(GlusterValidationException ve) { return badRequestResponse(ve.getMessage()); } catch (GlusterRuntimeException e) { diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 107d4fb2..3e89b8ca 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -950,7 +950,7 @@ public class VolumesResource extends AbstractResource { migrateDiskTask.setAutoCommit(autoCommit); migrateDiskTask.start(); taskResource.addTask(migrateDiskTask); - return migrateDiskTask.getId(); + return migrateDiskTask.getTaskInfo().getName(); // Return Task ID } private String rebalanceStart(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData, @@ -1005,6 +1005,10 @@ public class VolumesResource extends AbstractResource { // System.out.println("Code : " + status.getCode()); // System.out.println("Message " + status.getMessage()); - vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true); + // vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true); + + String taskId = vr.migrateBrickStart("myGluster", "students", "devserver1:/export/sdc/students", + "devserver2:/export/sdb/students", true); + } } 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 9a31d468..9bdc9c94 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 @@ -22,7 +22,6 @@ package com.gluster.storage.management.server.tasks; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; -import com.gluster.storage.management.core.model.GlusterServer; 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; @@ -30,6 +29,7 @@ import com.gluster.storage.management.core.model.TaskStatus; import com.gluster.storage.management.core.utils.ProcessResult; import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.utils.SshUtil; +import com.sun.jersey.core.util.Base64; public class MigrateDiskTask extends Task { @@ -68,6 +68,7 @@ public class MigrateDiskTask extends Task { + volumeName + "] from [" + fromBrick + "] to [" + toBrick + "]", true, true, true); setFromBrick(fromBrick); setToBrick(toBrick); + taskInfo.setName(getId()); } public MigrateDiskTask(ClusterService clusterService, String clusterName, TaskInfo info) { @@ -76,7 +77,7 @@ public class MigrateDiskTask extends Task { @Override public String getId() { - return taskInfo.getType() + "-" + taskInfo.getReference() + "-" + fromBrick + "-" + toBrick; + return new String( Base64.encode( taskInfo.getType() + "-" + taskInfo.getReference() + "-" + fromBrick + "-" + toBrick )); } @Override @@ -93,13 +94,9 @@ public class MigrateDiskTask extends Task { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + getToBrick() + " start"; ProcessResult processResult = sshUtil.executeRemote(onlineServerName, command); - - System.out.println(command); - System.out.println("[" + processResult.getExitValue() + "] " + processResult.getOutput() ); - if (processResult.isSuccess()) { if (processResult.getOutput().trim().matches(".*started successfully$")) { - getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput()))); + getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput().trim()))); return; } } @@ -125,16 +122,16 @@ public class MigrateDiskTask extends Task { ProcessResult processResult = sshUtil.executeRemote(onlineServer, command); TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { - if (processResult.getOutput().matches("*pause")) { + if (processResult.getOutput().matches("*pause")) { //TODO replace correct pattern to identify the pause status taskStatus.setCode(Status.STATUS_CODE_PAUSE); - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); + taskStatus.setMessage(processResult.getOutput()); + getTaskInfo().setStatus(taskStatus); + return; } - } else { - taskStatus.setCode(Status.STATUS_CODE_FAILURE); - } - taskStatus.setMessage(processResult.getOutput()); // Common - getTaskInfo().setStatus(taskStatus); + } + + // if we reach here, it means rebalance start failed. + throw new GlusterRuntimeException(processResult.toString()); } @@ -145,7 +142,12 @@ public class MigrateDiskTask extends Task { @Override public void commit() { - // TODO Auto-generated method stub + try { + commitMigration(getOnlineServer().getName()); + } catch(ConnectionException e) { + // online server might have gone offline. try with a new one. + commitMigration(getNewOnlineServer().getName()); + } } @Override @@ -167,14 +169,14 @@ public class MigrateDiskTask extends Task { if (processResult.isSuccess()) { if (processResult.getOutput().trim().matches(".*aborted successfully$")) { 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); + taskStatus.setMessage(processResult.getOutput()); + getTaskInfo().setStatus(taskStatus); + return; + } + } + + // if we reach here, it means rebalance start failed. + throw new GlusterRuntimeException(processResult.toString()); } @@ -187,6 +189,27 @@ public class MigrateDiskTask extends Task { return checkMigrationStatus(getNewOnlineServer().getName()); } } + + + public void commitMigration(String serverName) { + String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " + + getToBrick() + " commit"; + + ProcessResult processResult = sshUtil.executeRemote(serverName, command); + TaskStatus taskStatus = new TaskStatus(); + if (processResult.isSuccess()) { + if (processResult.getOutput().trim().matches(".*commit successful$")) { + taskStatus.setCode(Status.STATUS_CODE_SUCCESS); + taskStatus.setMessage(processResult.getOutput()); // Common + getTaskInfo().setStatus(taskStatus); + return; + } + } + + // if we reach here, it means rebalance start failed. + throw new GlusterRuntimeException(processResult.toString()); + } + private TaskStatus checkMigrationStatus(String serverName) { String command = "gluster volume replace-brick " + getTaskInfo().getReference() + " " + getFromBrick() + " " @@ -195,7 +218,10 @@ public class MigrateDiskTask extends Task { TaskStatus taskStatus = new TaskStatus(); if (processResult.isSuccess()) { if (processResult.getOutput().trim().matches("^Number of files migrated.*Migration complete$")) { - taskStatus.setCode(Status.STATUS_CODE_SUCCESS); + taskStatus.setCode(Status.STATUS_CODE_COMMIT_PENDING); + if (autoCommit) { + commitMigration(serverName); + } } else if ( processResult.getOutput().trim().matches("^Number of files migrated.*Current file=.*")) { taskStatus.setCode(Status.STATUS_CODE_RUNNING); } else { @@ -204,7 +230,9 @@ public class MigrateDiskTask extends Task { } else { taskStatus.setCode(Status.STATUS_CODE_FAILURE); } - taskStatus.setMessage(processResult.getOutput()); // Common + + taskStatus.setMessage(processResult.getOutput()); // common + taskInfo.setStatus(taskStatus); // Update the task status return taskStatus; } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java index cdc56400..49cd0b8b 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java @@ -20,11 +20,10 @@ */ package com.gluster.storage.management.server.tasks; -import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.TaskInfo; -import com.gluster.storage.management.core.model.TaskStatus; import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE; +import com.gluster.storage.management.core.model.TaskStatus; import com.gluster.storage.management.server.services.ClusterService; public abstract class Task { @@ -39,10 +38,12 @@ public abstract class Task { taskInfo.setType(type); taskInfo.setReference(reference); taskInfo.setDescription(desc); + taskInfo.setCanPause(canPause); + taskInfo.setCanStop(canStop); + taskInfo.setCanCommit(canCommit); - // IMPORTANT. This call must be in the end since getId may need to use the values set in above statements - taskInfo.setName(getId()); init(clusterService, clusterName, taskInfo); + } public Task(ClusterService clusterService, String clusterName, TaskInfo taskInfo) { -- cgit From d18b409920b37fd585655f33f1405e3859355760 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 28 Jun 2011 18:47:48 +0530 Subject: Changes to avoid webstart authentication dialog --- .../src/com/gluster/storage/management/gui/Application.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java index 0e269c3a..598f9639 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java @@ -73,6 +73,8 @@ public class Application implements IApplication { * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) */ public Object start(IApplicationContext context) { + setSystemProperties(); + Display display = PlatformUI.createDisplay(); final boolean[] loginSuccess = new boolean[1]; @@ -96,6 +98,12 @@ public class Application implements IApplication { } } + private void setSystemProperties() { + // TODO: Trying this to avoid the webstart authentication dialog + // to be tested, and removed if this doesn't work. + System.setProperty("javaws.cfg.jauthenticator", "none"); + } + /* * (non-Javadoc) * -- cgit From 3f7ac1fef7574d6470a3eecec0703627109c829e Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Thu, 30 Jun 2011 21:12:28 +0530 Subject: Added rolling file appender configuration. --- src/com.gluster.storage.management.server/src/log4j.properties | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/com.gluster.storage.management.server/src/log4j.properties b/src/com.gluster.storage.management.server/src/log4j.properties index d7712c96..f84009d3 100644 --- a/src/com.gluster.storage.management.server/src/log4j.properties +++ b/src/com.gluster.storage.management.server/src/log4j.properties @@ -7,6 +7,13 @@ log4j.appender.CONSOLE.threshold=DEBUG log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{dd MMM, yyyy HH:mm:ss} %p: %c %t - %m%n +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=${catalina.home}/logs/tomcat.log +log4j.appender.R.MaxFileSize=10MB +log4j.appender.R.MaxBackupIndex=10 +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n + log4j.logger.org.springframework=ERROR log4j.logger.org.springframework.aop=DEBUG log4j.logger.com.gluster=INFO \ No newline at end of file -- cgit From d0d2cd23f6f64b3645a108033586383158b2f7ac Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 1 Jul 2011 11:36:40 +0530 Subject: Login was failing in case of newly created cluster - fixed. Modified SshUtil to trim output of remote execution. --- .../storage/management/server/resources/VolumesResource.java | 10 ++++++++-- .../com/gluster/storage/management/server/utils/SshUtil.java | 12 +++++------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index 3e89b8ca..c9ae0fe5 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -89,7 +89,6 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Status; -import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeLogMessage; @@ -101,6 +100,7 @@ import com.gluster.storage.management.core.utils.DateUtil; import com.gluster.storage.management.core.utils.FileUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; +import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.tasks.MigrateDiskTask; import com.gluster.storage.management.server.tasks.RebalanceVolumeTask; @@ -147,9 +147,15 @@ public class VolumesResource extends AbstractResource { return badRequestResponse("Cluster name must not be empty!"); } - if (clusterService.getCluster(clusterName) == null) { + ClusterInfo cluster = clusterService.getCluster(clusterName); + if (cluster == null) { return notFoundResponse("Cluster [" + clusterName + "] not found!"); } + + if(cluster.getServers().size() == 0) { + // no server added yet. return an empty array. + return okResponse(new VolumeListResponse(), mediaType); + } return okResponse(getVolumes(clusterName), mediaType); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index d15142e6..2ebf011b 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -20,13 +20,11 @@ package com.gluster.storage.management.server.utils; import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Arrays; -import java.util.Date; import org.springframework.stereotype.Component; @@ -270,7 +268,7 @@ public class SshUtil { readFromStream(stderrReader, output); } - return prepareProcessResult(session, condition, output); + return prepareProcessResult(session, condition, output.toString().trim()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -278,17 +276,17 @@ public class SshUtil { } } - private ProcessResult prepareProcessResult(Session session, int condition, StringBuilder output) { + private ProcessResult prepareProcessResult(Session session, int condition, String output) { ProcessResult result = null; if (wasTerminated(condition)) { - result = new ProcessResult(ProcessResult.FAILURE, output.toString()); + result = new ProcessResult(ProcessResult.FAILURE, output); } else { if (hasErrors(condition, session)) { Integer exitStatus = session.getExitStatus(); int statusCode = (exitStatus == null ? ProcessResult.FAILURE : exitStatus); - result = new ProcessResult(statusCode, output.toString()); + result = new ProcessResult(statusCode, output); } else { - result = new ProcessResult(ProcessResult.SUCCESS, output.toString()); + result = new ProcessResult(ProcessResult.SUCCESS, output); } } return result; -- cgit From 40d4024c47ca1e1e15e2500a5412791d364bd8b0 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 1 Jul 2011 13:59:21 +0530 Subject: Introduced configuration for SSH related timeouts --- .../storage/management/server/utils/SshUtil.java | 64 ++++++++++++++-------- .../src/spring/gluster-server-base.xml | 14 +++++ 2 files changed, 56 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index 2ebf011b..d56cd47c 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -26,6 +26,8 @@ import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Arrays; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ch.ethz.ssh2.ChannelCondition; @@ -59,6 +61,15 @@ public class SshUtil { private static final String USER_NAME = "root"; // TODO: Make default password configurable private static final String DEFAULT_PASSWORD = "syst3m"; + + private static final Logger logger = Logger.getLogger(SshUtil.class); + + @Autowired + private Integer sshConnectTimeout; + @Autowired + private Integer sshKexTimeout; + @Autowired + private Integer sshExecTimeout; public boolean hasDefaultPassword(String serverName) { try { @@ -207,29 +218,28 @@ public class SshUtil { Connection conn; conn = new Connection(serverName); try { - // tcp connection timeout = 3 sec, ssh connection timeout = 10 sec - conn.connect(null, 3000, 10000); + conn.connect(null, sshConnectTimeout, sshKexTimeout); } catch (IOException e) { - e.printStackTrace(); + logger.error("Couldn't establish SSH connection with server [" + serverName + "]", e); throw new ConnectionException("Exception while creating SSH connection with server [" + serverName + "]", e); } return conn; } - private boolean wasTerminated(int condition) { - return ((condition | ChannelCondition.EXIT_SIGNAL) == condition); - } - private boolean hasErrors(int condition, Session session) { return (hasErrorStream(condition) || (exitedGracefully(condition) && exitedWithError(session))); } + + private boolean timedOut(int condition) { + return (condition == ChannelCondition.TIMEOUT); + } private boolean exitedWithError(Session session) { return session.getExitStatus() != ProcessResult.SUCCESS; } private boolean exitedGracefully(int condition) { - return (condition | ChannelCondition.EXIT_STATUS) == condition; + return (condition == ChannelCondition.EXIT_STATUS); } private boolean hasErrorStream(int condition) { @@ -248,8 +258,10 @@ public class SshUtil { session.close(); return result; } catch (IOException e) { - throw new GlusterRuntimeException("Exception while executing command [" + command + "] on [" - + sshConnection.getHostname() + "]", e); + String errMsg = "Exception while executing command [" + command + "] on [" + sshConnection.getHostname() + + "]"; + logger.error(errMsg, e); + throw new GlusterRuntimeException(errMsg, e); } } @@ -258,29 +270,37 @@ public class SshUtil { // a) gracefully with an exit status, OR // b) because of a termination signal // c) command takes to long to exit (timeout) - int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS - | ChannelCondition.TIMEOUT, 5000); + int condition = session.waitForCondition(ChannelCondition.EXIT_SIGNAL | ChannelCondition.EXIT_STATUS, + sshExecTimeout); StringBuilder output = new StringBuilder(); try { - readFromStream(stdoutReader, output); - if (hasErrors(condition, session)) { - readFromStream(stderrReader, output); + if(!timedOut(condition)) { + readFromStream(stdoutReader, output); + if (hasErrors(condition, session)) { + readFromStream(stderrReader, output); + } } return prepareProcessResult(session, condition, output.toString().trim()); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; + String errMsg = "Error while reading output stream from SSH connection!"; + logger.error(errMsg, e); + return new ProcessResult(ProcessResult.FAILURE, errMsg); } } private ProcessResult prepareProcessResult(Session session, int condition, String output) { ProcessResult result = null; - if (wasTerminated(condition)) { + switch(condition) { + case ChannelCondition.TIMEOUT: + result = new ProcessResult(ProcessResult.FAILURE, "Command timed out!"); + break; + case ChannelCondition.EXIT_SIGNAL: + // terminated result = new ProcessResult(ProcessResult.FAILURE, output); - } else { + break; + default: if (hasErrors(condition, session)) { Integer exitStatus = session.getExitStatus(); int statusCode = (exitStatus == null ? ProcessResult.FAILURE : exitStatus); @@ -288,12 +308,12 @@ public class SshUtil { } else { result = new ProcessResult(ProcessResult.SUCCESS, output); } + break; } return result; } - private void readFromStream(BufferedReader streamReader, StringBuilder output) throws IOException, - UnsupportedEncodingException { + private void readFromStream(BufferedReader streamReader, StringBuilder output) throws IOException { while (true) { String line = streamReader.readLine(); if (line == null) { diff --git a/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml b/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml index 3c7d6436..700d996f 100644 --- a/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml +++ b/src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml @@ -21,6 +21,20 @@ + + + + + + + + + + + + + + -- cgit