summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTim <timothyasir@gluster.com>2011-07-01 14:47:05 +0530
committerTim <timothyasir@gluster.com>2011-07-01 14:47:05 +0530
commit9cdc7095308011332392ddd040b34106ef3abd6a (patch)
treea4b6d72ef81611be53bf46f940cd8ff70eadbf15 /src
parent19ed9b4866499d9c264c8db8fc616fb5a5e36ce3 (diff)
parent40d4024c47ca1e1e15e2500a5412791d364bd8b0 (diff)
Merge remote branch 'upstream/master'
Diffstat (limited to 'src')
-rw-r--r--src/com.gluster.storage.management.client/.classpath4
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java55
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/ClustersClient.java44
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/DiscoveredServersClient.java42
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java77
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java9
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java31
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java74
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java36
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java12
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java27
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java4
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java6
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java19
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Status.java1
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java83
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskInfo.java54
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/TaskStatus.java2
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java13
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerListResponse.java26
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/ServerNameListResponse.java46
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskInfoListResponse.java (renamed from src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/TaskListResponse.java)34
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java3
-rw-r--r--src/com.gluster.storage.management.gui/icons/close_task.pngbin0 -> 588 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/pause_task.pngbin0 -> 427 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/star.pngbin0 -> 244 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/start_task.gifbin0 -> 470 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/stop_task.pngbin0 -> 411 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/disk.pngbin0 -> 603 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/help.pngbin0 -> 932 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/logs.pngbin0 -> 611 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/server.pngbin0 -> 725 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/servers.pngbin0 -> 393 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/settings.pngbin0 -> 588 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.pngbin0 -> 635 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/16x16/volume.pngbin0 -> 697 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/disk.pngbin0 -> 1155 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/help.pngbin0 -> 2231 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/logs.pngbin0 -> 1886 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/server.pngbin0 -> 1591 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/servers.pngbin0 -> 1264 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/settings.pngbin0 -> 2544 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.pngbin0 -> 1399 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/32x32/volume.pngbin0 -> 1446 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/48x48/server.pngbin0 -> 3295 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.pngbin0 -> 2853 bytes
-rw-r--r--src/com.gluster.storage.management.gui/icons/tango/48x48/volume.pngbin0 -> 2965 bytes
-rw-r--r--src/com.gluster.storage.management.gui/plugin.xml156
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java8
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java23
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java45
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ClearTaskAction.java53
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CommitTaskAction.java54
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java14
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java76
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java37
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java23
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java55
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopTaskAction.java54
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java50
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java123
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java60
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java30
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java45
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java1
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java7
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java12
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java39
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java8
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java90
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerLogsPage.java23
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java117
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeLogsPage.java22
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java100
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java2
-rwxr-xr-xsrc/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py40
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractResource.java45
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AbstractServersResource.java19
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java1
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java100
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java247
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/TasksResource.java122
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java63
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java218
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java68
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java114
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/MigrateDiskTask.java188
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java153
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java111
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java17
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java16
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java76
-rw-r--r--src/com.gluster.storage.management.server/src/log4j.properties7
-rw-r--r--src/com.gluster.storage.management.server/src/spring/gluster-server-base.xml14
100 files changed, 2650 insertions, 1010 deletions
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 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry exported="true" kind="lib" path="keystore/"/>
- <classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-client-1.5.jar" sourcepath="/data/downloads/sun/jersey/sources/jersey-client-1.5-sources.jar"/>
- <classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-core-1.5.jar" sourcepath="/data/downloads/sun/jersey/sources/jersey-core-1.5-sources.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-client-1.5.jar" sourcepath="/home/selvam/sources/jersey/jersey-client-1.5-sources.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-core-1.5.jar" sourcepath="/home/selvam/sources/jersey/jersey-core-1.5-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry excluding="keystore/" kind="src" path="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..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
@@ -9,6 +9,7 @@ import static com.gluster.storage.management.client.constants.ClientConstants.TR
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.security.KeyStore;
import javax.net.ssl.HostnameVerifier;
@@ -21,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;
@@ -31,6 +33,7 @@ import com.sun.jersey.api.representation.Form;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import com.sun.jersey.core.util.MultivaluedMapImpl;
+
public abstract class AbstractClient {
private static final String HTTP_HEADER_AUTH = "Authorization";
protected static final MultivaluedMap<String, String> NO_PARAMS = new MultivaluedMapImpl();
@@ -39,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.
@@ -59,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) {
@@ -121,12 +130,12 @@ 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<String, String> queryParams, Class responseClass) {
+ private <T> T fetchResource(WebResource res, MultivaluedMap<String, String> queryParams, Class<T> responseClass) {
try {
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);
}
}
@@ -139,13 +148,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);
}
@@ -262,9 +272,13 @@ public abstract class AbstractClient {
postRequest(resource.path(subResourceName), form);
}
- private void putRequest(WebResource resource, Form form) {
+ private ClientResponse putRequest(WebResource resource, Form form) {
try {
- prepareFormRequestBuilder(resource).put(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));
}
@@ -286,6 +300,12 @@ public abstract class AbstractClient {
protected void putRequest(String subResourceName, Form form) {
putRequest(resource.path(subResourceName), form);
}
+
+
+ protected URI putRequestURI(String subResourceName, Form form) {
+ ClientResponse response = putRequest(resource.path(subResourceName), form);
+ return response.getLocation();
+ }
/**
* Submits given Form using PUT method to the given sub-resource and returns the object received as response
@@ -353,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> T fetchResource(URI uri, Class<T> responseClass) {
+ return fetchResource(client.resource(uri), NO_PARAMS, responseClass);
+ }
}
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 e055a2dd..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
@@ -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,36 @@ public class DiscoveredServersClient extends AbstractClient {
}
@SuppressWarnings("rawtypes")
- private Object getDiscoveredServers(Boolean getDetails, Class responseClass) {
+ private Object getDiscoveredServers(Boolean details, Class responseClass) {
MultivaluedMap<String, String> 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<String> getDiscoveredServerNames() {
+ return ((ServerNameListResponse) getDiscoveredServers(Boolean.FALSE, ServerNameListResponse.class))
+ .getServerNames();
}
- public ServerListResponse getDiscoveredServerDetails() {
- return (ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class);
+ public List<Server> getDiscoveredServerDetails() {
+ return ((ServerListResponse) getDiscoveredServers(Boolean.TRUE, ServerListResponse.class)).getServers();
}
- @SuppressWarnings("unchecked")
public Server getServer(String serverName) {
- GenericResponse<Server> response = (GenericResponse<Server>) 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()) {
+ try {
+ usersClient.authenticate("gluster", "gluster");
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<String> discoveredServerNames = serverResource.getDiscoveredServerNames();
+ System.out.println(discoveredServerNames);
+ List<Server> 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/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java
index 3c5aedf5..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
@@ -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;
@@ -35,15 +36,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 +91,6 @@ public class GlusterDataModelManager {
initializeAutoDiscoveredServers(cluster);
// initializeDisks();
-
initializeTasks(cluster);
initializeAlerts(cluster);
initializeVolumeOptionsDefaults();
@@ -105,14 +103,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) {
@@ -125,10 +116,40 @@ public class GlusterDataModelManager {
}
public void initializeTasks(Cluster cluster) {
- List<TaskInfo> taskInfoList = new TasksClient(cluster.getName()).getAllTasks();
+ // List<TaskInfo> taskInfoList = new TasksClient(cluster.getName()).getAllTasks();
+ List<TaskInfo> taskInfoList = getDummyTasks();
cluster.setTaskInfoList(taskInfoList);
}
+ private List<TaskInfo> getDummyTasks() {
+ List<TaskInfo> taskInfoList = new ArrayList<TaskInfo>();
+
+ // Task #1
+ TaskInfo taskInfo = new TaskInfo();
+ taskInfo.setType(TASK_TYPE.BRICK_MIGRATE);
+ taskInfo.setName("Migrate Brick-music");
+ taskInfo.setCanPause(true);
+ taskInfo.setCanStop(true);
+ taskInfo.setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, "")));
+
+ taskInfo.getStatus().setMessage("Migrating file xxxxx to yyyy");
+ taskInfo.setDescription("Migrate Brick on volume [music] from /export/adb/music to /export/sdc/music.");
+ taskInfoList.add(taskInfo);
+ // Task #2
+ taskInfo = new TaskInfo();
+ taskInfo.setType(TASK_TYPE.DISK_FORMAT);
+ taskInfo.setName("Format Disk-server1:sdc");
+ taskInfo.setCanPause(false);
+ taskInfo.setCanStop(false);
+ taskInfo.setStatus( new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "")));
+ taskInfo.getStatus().setMessage("Format completes 80% ...");
+ taskInfo.setDescription("Formatting disk server1:sdc.");
+ taskInfoList.add(taskInfo);
+
+
+ return taskInfoList;
+ }
+
public void initializeAlerts(Cluster cluster) {
cluster.setAlerts(new AlertsClient(cluster.getName()).getAllAlerts());
}
@@ -182,7 +203,7 @@ public class GlusterDataModelManager {
Disk disk = null;
List<Disk> volumeDisks = new ArrayList<Disk>();
for (Brick brick : volume.getBricks()) {
- disk = getDisk(brick.getDiskName());
+ disk = getDisk(brick.getServerName() + ":" + brick.getDiskName());
// disk = new Disk();
// disk.setServerName(brick.getServerName());
// disk.setName(brick.getDiskName());
@@ -319,7 +340,7 @@ public class GlusterDataModelManager {
}
}
- public void removeBricks(Volume volume, List<Brick> bricks) {
+ public void removeBricks(Volume volume, Set<Brick> bricks) {
for (ClusterListener listener : listeners) {
listener.volumeChanged(volume, new Event(EVENT_TYPE.BRICKS_REMOVED, bricks));
}
@@ -341,6 +362,29 @@ public class GlusterDataModelManager {
}
}
+ 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<VolumeOptionInfo> getVolumeOptionsDefaults() {
return volumeOptionsDefaults;
}
@@ -421,4 +465,5 @@ public class GlusterDataModelManager {
}
return volumeNames;
}
+
}
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..b6d0a426 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
@@ -62,13 +62,18 @@ 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);
}
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<GlusterServer> glusterServers = glusterServersClient.getServers();
for (GlusterServer server : glusterServers) {
@@ -79,6 +84,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/TasksClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/TasksClient.java
index b5ee1d1c..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
@@ -20,21 +20,23 @@
*/
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.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.gluster.storage.management.core.response.TaskInfoListResponse;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.core.util.MultivaluedMapImpl;
public class TasksClient extends AbstractClient {
+ public TasksClient() {
+ super();
+ }
+
public TasksClient(String clusterName) {
super(clusterName);
}
@@ -48,14 +50,8 @@ public class TasksClient extends AbstractClient {
return RESTConstants.RESOURCE_PATH_CLUSTERS + "/" + clusterName + "/" + RESTConstants.RESOURCE_TASKS + "/";
}
- @SuppressWarnings("unchecked")
public List<TaskInfo> getAllTasks() { // TaskListResponse get only the list of taskInfo not list of Tasks
- TaskListResponse response = (TaskListResponse) fetchResource(TaskListResponse.class);
- if (response.getStatus().isSuccess()) {
- return (List<TaskInfo>) response.getData();
- } else {
- throw new GlusterRuntimeException("Exception on fetching tasks [" + response.getStatus().getMessage() + "]");
- }
+ return ((TaskInfoListResponse) fetchResource(TaskInfoListResponse.class)).getTaskList();
}
// see startMigration @ VolumesClient, etc
@@ -79,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();
@@ -90,7 +93,11 @@ public class TasksClient extends AbstractClient {
public void deleteTask(String taskId) {
MultivaluedMap<String, String> 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 84ed4e4c..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
@@ -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,59 @@ 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"));
-
- // change password to gluster1
- System.out.println(authClient.changePassword("gluster", "gluster", "gluster1"));
-
- // change it back to gluster
- System.out.println(authClient.changePassword("gluster", "gluster1", "gluster"));
+// 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 d237f010..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
@@ -29,8 +29,10 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P
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 java.net.URI;
import java.util.Date;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.MultivaluedMap;
@@ -38,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;
@@ -175,7 +178,7 @@ public class VolumesClient extends AbstractClient {
downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath);
}
- public void removeBricks(String volumeName, List<Brick> BrickList, boolean deleteOption) {
+ public void removeBricks(String volumeName, Set<Brick> BrickList, boolean deleteOption) {
String bricks = StringUtil.collectionToString(GlusterCoreUtil.getQualifiedBrickList(BrickList), ",");
MultivaluedMap<String, String> queryParams = prepareRemoveBrickQueryParams(volumeName, bricks, deleteOption);
deleteSubResource(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, queryParams);
@@ -220,22 +223,45 @@ 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);
+ return putRequestURI(volumeName + "/" + RESTConstants.RESOURCE_BRICKS, form);
+ }
+
+ 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);
+ form.add(RESTConstants.FORM_PARAM_MIGRATE_DATA, migrateData);
+ 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();
- 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 a2d222a8..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
@@ -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";
@@ -44,8 +45,12 @@ 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";
+ 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";
@@ -56,7 +61,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";
@@ -67,12 +71,17 @@ 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";
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 PATH_PARAM_USER = "user";
public static final String QUERY_PARAM_BRICK_NAME = "brickName";
public static final String QUERY_PARAM_DISKS = "disks";
@@ -85,6 +94,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/exceptions/GlusterValidationException.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java
new file mode 100644
index 00000000..ca5e01f8
--- /dev/null
+++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/exceptions/GlusterValidationException.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.core.exceptions;
+
+public class GlusterValidationException extends GlusterRuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public GlusterValidationException(String message) {
+ super(message);
+ }
+}
diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/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<Alert> getAlerts() {
return alerts;
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/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/Task.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java
deleted file mode 100644
index 45eb07ba..00000000
--- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Task.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Task.java
- *
- * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- * This file is part of Gluster Management Console.
- *
- * Gluster Management Console is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * Gluster Management Console is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-package com.gluster.storage.management.core.model;
-
-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 String serverName;
-
- public Task(TASK_TYPE type, String reference) {
- taskInfo = new TaskInfo();
- taskInfo.setType(type);
- taskInfo.setId(getTypeStr() + "-" + reference); // construct id
- taskInfo.setReference(reference);
- }
-
- 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 TaskInfo start();
-
- public abstract TaskInfo resume();
-
- public abstract TaskInfo stop();
-
- public abstract TaskInfo pause();
-
- public abstract TaskInfo status();
-
- public abstract void setTaskDescription();
-
-}
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/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.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<VolumeLogMessage> logMessages = new ArrayList<VolumeLogMessage>();
public LogMessageListResponse() {
@@ -23,11 +22,6 @@ public class LogMessageListResponse extends AbstractResponse {
setLogMessages(logMessages);
}
- public LogMessageListResponse(Status status, List<VolumeLogMessage> logMessages) {
- setStatus(status);
- setLogMessages(logMessages);
- }
-
@XmlElement(name = "logMessage", type = VolumeLogMessage.class)
public List<VolumeLogMessage> getLogMessages() {
return logMessages;
@@ -36,9 +30,4 @@ public class LogMessageListResponse extends AbstractResponse {
public void setLogMessages(List<VolumeLogMessage> logMessages) {
this.logMessages = logMessages;
}
-
- @Override
- public Object getData() {
- return getLogMessages();
- }
}
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<Server> servers = new ArrayList<Server>();
public ServerListResponse() {
}
- public ServerListResponse(Status status, List<Server> servers) {
- setStatus(status);
+ public ServerListResponse(List<Server> servers) {
setServers(servers);
}
- @XmlElementWrapper(name = "servers")
@XmlElement(name = "server", type=Server.class)
public List<Server> getServers() {
return servers;
}
- /**
- * @param servers
- * the servers to set
- */
public void setServers(List<Server> servers) {
this.servers = servers;
}
-
- /*
- * (non-Javadoc)
- *
- * @see com.gluster.storage.management.core.model.Response#getData()
- */
- @Override
- @XmlTransient
- public List<Server> 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. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.core.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<String> serverNames = new ArrayList<String>();
+
+ public ServerNameListResponse() {
+ }
+
+ public ServerNameListResponse(List<String> serverNames) {
+ this.serverNames = serverNames;
+ }
+
+ @XmlElement(name = "server", type = String.class)
+ public List<String> getServerNames() {
+ return serverNames;
+ }
+}
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/TaskInfoListResponse.java
index 2637b197..0ab27c35 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/TaskInfoListResponse.java
@@ -20,35 +20,31 @@
*/
package com.gluster.storage.management.core.response;
-import java.util.ArrayList;
import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
-import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.model.TaskInfo;
-@XmlRootElement
-public class TaskListResponse extends AbstractResponse {
- private List<TaskInfo> taskList = new ArrayList<TaskInfo>();
- private Status status;
-
- public Status getStatus() {
- return status;
- }
+@XmlRootElement(name = "tasks")
+public class TaskInfoListResponse {
+ private List<TaskInfo> taskInfoList;
- public void setStatus(Status status) {
- this.status = status;
- }
+ public TaskInfoListResponse() {
+ }
- public void setData(List<TaskInfo> taskList) {
- this.taskList.clear();
- this.taskList.addAll(taskList);
+ public TaskInfoListResponse(List<TaskInfo> taskInfoList) {
+ this.taskInfoList = taskInfoList;
+ }
+
+ @XmlElement(name="task", type=TaskInfo.class)
+ public List<TaskInfo> getTaskList() {
+ return taskInfoList;
}
- @Override
- public Object getData() {
- return this.taskList;
+ public void setTaskList(List<TaskInfo> taskInfoList) {
+ this.taskInfoList = taskInfoList;
}
}
diff --git a/src/com.gluster.storage.management.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<String> getQualifiedBrickList(List<Brick> bricks) {
+ public static final List<String> getQualifiedBrickList(Set<Brick> bricks) {
List<String> qualifiedBricks = new ArrayList<String>();
for (Brick brick : bricks) {
qualifiedBricks.add(brick.getQualifiedName());
diff --git a/src/com.gluster.storage.management.gui/icons/close_task.png b/src/com.gluster.storage.management.gui/icons/close_task.png
new file mode 100644
index 00000000..933272b4
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/close_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/pause_task.png b/src/com.gluster.storage.management.gui/icons/pause_task.png
new file mode 100644
index 00000000..af57b25d
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/pause_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/star.png b/src/com.gluster.storage.management.gui/icons/star.png
new file mode 100644
index 00000000..5f8fc748
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/star.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/start_task.gif b/src/com.gluster.storage.management.gui/icons/start_task.gif
new file mode 100644
index 00000000..2dfaef50
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/start_task.gif
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/stop_task.png b/src/com.gluster.storage.management.gui/icons/stop_task.png
new file mode 100644
index 00000000..7c6af7f0
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/stop_task.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png
new file mode 100644
index 00000000..5c3b8587
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/disk.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/help.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/logs.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/server.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/servers.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/settings.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume-create.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/16x16/volume.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/disk.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/help.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/logs.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/server.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/servers.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/settings.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume-create.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/32x32/volume.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/48x48/server.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume-create.png
Binary files 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
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/icons/tango/48x48/volume.png
Binary files differ
diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml
index af065b7d..112c8e81 100644
--- a/src/com.gluster.storage.management.gui/plugin.xml
+++ b/src/com.gluster.storage.management.gui/plugin.xml
@@ -30,14 +30,6 @@
restorable="true">
</view>
<view
- category="org.eclipse.ui"
- class="org.eclipse.ui.ExtensionFactory:progressView"
- icon="icons/progress-bar.png"
- id="org.eclipse.ui.views.ProgressView"
- name="Tasks in Progress"
- restorable="true">
- </view>
- <view
allowMultiple="false"
category="com.gluster.storage.management.gui.category"
class="com.gluster.storage.management.gui.views.DiscoveredServersView"
@@ -62,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">
@@ -107,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">
@@ -116,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">
@@ -134,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">
@@ -143,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">
@@ -161,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">
@@ -170,11 +162,20 @@
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">
</view>
+ <view
+ allowMultiple="false"
+ category="com.gluster.storage.management.gui.category"
+ class="com.gluster.storage.management.gui.views.TasksView"
+ icon="icons/progress-bar.png"
+ id="com.gluster.storage.management.gui.views.TasksView"
+ name="Tasks"
+ restorable="true">
+ </view>
</extension>
<extension
point="org.eclipse.ui.commands">
@@ -249,10 +250,35 @@
name="Remove Brick">
</command>
<command
+ categoryId="com.gluster.storage.management.gui.category"
description="Add Brick"
id="com.gluster.storage.management.gui.commands.AddDisk"
name="Add Brick">
</command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Pause Task"
+ id="com.gluster.storage.management.gui.commands.Pause"
+ name="Pause">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Resume Task"
+ id="com.gluster.storage.management.gui.commands.Resume"
+ name="Resume">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Stop Task"
+ id="com.gluster.storage.management.gui.commands.Stop"
+ name="Stop">
+ </command>
+ <command
+ categoryId="com.gluster.storage.management.gui.category"
+ description="Delete Task"
+ id="com.gluster.storage.management.gui.commands.Delete"
+ name="Delete">
+ </command>
</extension>
<extension
point="org.eclipse.ui.bindings">
@@ -374,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="&amp;Settings"
menubarPath="com.gluster.storage.management.gui.menu.edit/edit"
@@ -519,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 &amp;Logs"
menubarPath="com.gluster.storage.management.gui.menu.volume/volume"
@@ -535,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 &amp;Options"
menubarPath="com.gluster.storage.management.gui.menu.volume/volume"
@@ -643,9 +669,89 @@
visible="false">
<action
allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.ClearTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Clear"
+ icon="icons/close_task.png"
+ id="com.gluster.storage.management.gui.actions.Clear"
+ label="&amp;Clear Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To clear selected task from task list">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.CommitTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Commit"
+ icon="icons/stop.png"
+ id="com.gluster.storage.management.gui.actions.Commit"
+ label="&amp;Commit TaskTask"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Commit the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.StopTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Stop"
+ icon="icons/stop_task.png"
+ id="com.gluster.storage.management.gui.actions.Stop"
+ label="&amp;Stop Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Stop the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.ResumeTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Pause"
+ icon="icons/start_task.gif"
+ id="com.gluster.storage.management.gui.actions.Resume"
+ label="&amp;Resume Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Resume the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
+ class="com.gluster.storage.management.gui.actions.PauseTaskAction"
+ definitionId="com.gluster.storage.management.gui.commands.Pause"
+ icon="icons/pause_task.png"
+ id="com.gluster.storage.management.gui.actions.Pause"
+ label="&amp;Pause Task"
+ menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
+ mode="FORCE_TEXT"
+ pulldown="false"
+ retarget="false"
+ state="false"
+ style="push"
+ toolbarPath="Normal"
+ tooltip="To Pause the selected task">
+ </action>
+ <action
+ allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.CreateVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.CreateVolume"
- icon="icons/volume-create.png"
+ icon="icons/tango/32x32/volume-create.png"
id="com.gluster.storage.management.gui.actions.CreateVolumeAction"
label="Create &amp;Volume"
menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
@@ -1006,6 +1112,18 @@
standalone="false"
visible="false">
</view>
+ <view
+ closeable="false"
+ id="com.gluster.storage.management.gui.views.TasksView"
+ minimized="false"
+ moveable="false"
+ ratio="0.30f"
+ relationship="stack"
+ relative="com.gluster.storage.management.gui.views.ClusterSummaryView"
+ showTitle="true"
+ standalone="false"
+ visible="false">
+ </view>
</perspectiveExtension>
</extension>
<extension
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/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)
*
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java
index 65124bf9..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";
@@ -55,9 +55,14 @@ public interface IImageKeys {
public static final String LOW_DISK_SPACE = "icons/disk.png";
public static final String DISK_OFFLINE = "icons/status-offline.png";
+ public static final String PAUSE_TASK = "icons/pause_task.gif";
+ public static final String RESUME_TASK = "icons/resume_task.gif";
+ public static final String STOP_TASK = "icons/stop_task.gif";
+ public static final String CLEAR_TASK = "icons/close_task.gif";
+
public static final String OVERLAY_OFFLINE = "icons/status-offline-small.png";
public static final String OVERLAY_ONLINE = "icons/status-online-small.png";
- public static final String OVERLAY_STAR = "icons/star-small.png";
+ 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";
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java
new file mode 100644
index 00000000..82aa1f44
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TasksTableLabelProvider.java
@@ -0,0 +1,45 @@
+/**
+ * TasksTableLabelProvider.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui;
+
+import org.eclipse.swt.graphics.Image;
+
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.views.pages.TasksPage.TASK_TABLE_COLUMN_INDICES;
+
+
+public class TasksTableLabelProvider extends TableLabelProviderAdapter {
+
+ @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().trim() : taskInfo.getStatus().getMessage().trim();
+ }
+}
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..f1eb8a94
--- /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.removeTask(taskInfo);
+ } 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/CommitTaskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CommitTaskAction.java
new file mode 100644
index 00000000..9655b2b3
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CommitTaskAction.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;
+import com.gluster.storage.management.core.model.TaskStatus;
+
+public class CommitTaskAction 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().commitTask(taskInfo.getName());
+ taskInfo.setStatus(new TaskStatus(new Status(Status.STATUS_CODE_SUCCESS, taskInfo.getName()
+ + " is commited")));
+ modelManager.updateTask(taskInfo);
+ } 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.canCommit()
+ && taskInfo.getStatus().getCode() == Status.STATUS_CODE_COMMIT_PENDING);
+ }
+ }
+
+ @Override
+ public void dispose() {
+
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java
index bbb29253..56ea8179 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java
@@ -18,14 +18,16 @@
*******************************************************************************/
package com.gluster.storage.management.gui.actions;
+import java.util.Set;
+
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import com.gluster.storage.management.core.model.Brick;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.gui.dialogs.MigrateDiskWizard;
+import com.gluster.storage.management.gui.utils.GUIHelper;
public class MigrateDiskAction extends AbstractActionDelegate {
private Volume volume;
@@ -33,9 +35,6 @@ public class MigrateDiskAction extends AbstractActionDelegate {
@Override
protected void performAction(IAction action) {
-// MigrateDiskDialog dialog = new MigrateDiskDialog(window.getShell(), volume, disk);
-// dialog.create();
-// dialog.open();
MigrateDiskWizard wizard = new MigrateDiskWizard(volume, brick);
WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
@@ -47,15 +46,16 @@ public class MigrateDiskAction extends AbstractActionDelegate {
@Override
public void selectionChanged(IAction action, ISelection selection) {
super.selectionChanged(action, selection);
-
+ Set<Brick> bricks;
if (selectedEntity instanceof Volume) {
volume = (Volume) selectedEntity;
}
action.setEnabled(false);
if (selectedEntity instanceof Brick) {
- brick = (Brick) selectedEntity;
- action.setEnabled(((StructuredSelection) selection).size() == 1);
+ bricks = GUIHelper.getInstance().getSelectedEntities(getWindow(), Brick.class);
+ brick = (Brick) bricks.iterator().next();
+ action.setEnabled(brick != null);
}
}
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..b36b7855
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PauseTaskAction.java
@@ -0,0 +1,76 @@
+/**
+ * PauseTaskAction.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.client.TasksClient;
+import com.gluster.storage.management.core.model.Status;
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskStatus;
+
+
+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());
+ taskInfo.setStatus(new TaskStatus(new Status(Status.STATUS_CODE_PAUSE, taskInfo.getName()
+ + " is Paused")));
+ modelManager.updateTask(taskInfo);
+ } 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/RebalanceVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java
index 5339beb0..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
@@ -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().rebalanceStart(volume.getName(), false, false, false);
+ showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] rebalance started successfully!");
+ } catch (Exception e) {
+ showErrorDialog(actionDesc,
+ "Volume rebalance could not be 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.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<Brick> bricks;
+ private Set<Brick> 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<Brick> getSelectedBricks(ISelection selection) {
- List<Brick> selectedBricks = new ArrayList<Brick>();
-
- if (selection instanceof IStructuredSelection) {
- Iterator<Object> iter = ((IStructuredSelection) selection).iterator();
- while (iter.hasNext()) {
- Object selectedObj = iter.next();
- if (selectedObj instanceof Brick) {
- selectedBricks.add((Brick) selectedObj);
- }
- }
- }
- return selectedBricks;
- }
-
- private List<String> getBrickList(List<Brick> bricks) {
+ private List<String> getBrickList(Set<Brick> bricks) {
List<String> brickList = new ArrayList<String>();
for (Brick brick : bricks) {
brickList.add(brick.getServerName() + ":" + brick.getBrickDirectory());
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..fc80b04d
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResumeTaskAction.java
@@ -0,0 +1,55 @@
+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;
+import com.gluster.storage.management.core.model.TaskStatus;
+
+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());
+ taskInfo.setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, taskInfo.getName()
+ + " is Resumed")));
+ modelManager.updateTask(taskInfo);
+ } 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..abde4e57
--- /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;
+import com.gluster.storage.management.core.model.TaskStatus;
+
+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());
+ taskInfo.setStatus( new TaskStatus( new Status(Status.STATUS_CODE_SUCCESS, taskInfo.getName() + " is Stopped")));
+ modelManager.updateTask(taskInfo);
+ } 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/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<String> 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 563e6416..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
@@ -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;
@@ -199,79 +201,74 @@ 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();
+ 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());
+
+ IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();
+ boolean showClusterSelectionDialog = preferenceStore.getBoolean(PreferenceConstants.P_SHOW_CLUSTER_SELECTION_DIALOG);
+
+ CLUSTER_MODE mode;
+ String clusterName = null;
+ if (!showClusterSelectionDialog) {
+ 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;
}
-
- 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();
- }
- } else {
- MessageDialog.openError(getShell(), "Authentication Failed", loginStatus.getMessage());
}
- }
- public void createOrRegisterCluster(ClustersClient clustersClient, String clusterName, String serverName,
- CLUSTER_MODE mode) {
- String errTitle = null;
+ String serverName = null;
- try {
- switch (mode) {
- case SELECT:
+ 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;
- case CREATE:
- errTitle = "Cluster Creation Failed!";
- clustersClient.createCluster(clusterName);
- break;
- case REGISTER:
- errTitle = "Cluster Registration Failed!";
- clustersClient.registerCluster(clusterName, serverName);
- break;
}
+ mode = clusterDialog.getClusterMode();
+ clusterName = clusterDialog.getClusterName();
+ serverName = clusterDialog.getServerName();
+ } else {
+ mode = CLUSTER_MODE.SELECT;
+ }
+
+ try {
+ createOrRegisterCluster(clustersClient, clusterName, serverName, mode);
+ GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken(), clusterName);
+ super.okPressed();
} catch (Exception e) {
- MessageDialog.openError(getShell(), errTitle, e.getMessage());
setReturnCode(RETURN_CODE_ERROR);
+ MessageDialog.openError(getShell(), "Gluster Management Console", e.getMessage());
+ }
+ }
+
+ public void createOrRegisterCluster(ClustersClient clustersClient, String clusterName, String serverName,
+ CLUSTER_MODE mode) {
+ 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.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java
index ba5ef867..4533ca23 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java
@@ -23,13 +23,16 @@ import java.util.List;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
@@ -62,6 +65,8 @@ public class MigrateDiskPage1 extends WizardPage {
private TableViewer tableViewerFrom;
+ private Button autoCompleteCheckbox;
+
private ITableLabelProvider getDiskLabelProvider(final String volumeName) {
return new TableLabelProviderAdapter() {
@@ -74,9 +79,9 @@ public class MigrateDiskPage1 extends WizardPage {
return (columnIndex == DISK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? disk.getServerName()
: columnIndex == DISK_TABLE_COLUMN_INDICES.BRICK_DIRECTORY.ordinal() ? disk.getMountPoint() + "/" + volumeName
: columnIndex == DISK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal() ? NumberUtil
- .formatNumber(disk.getFreeSpace())
+ .formatNumber(disk.getFreeSpace() / 1024 ) /* Coverted to GB */
: columnIndex == DISK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal() ? NumberUtil
- .formatNumber(disk.getSpace()) : "Invalid");
+ .formatNumber(disk.getSpace() / 1024) : "Invalid");
}
};
}
@@ -118,10 +123,6 @@ public class MigrateDiskPage1 extends WizardPage {
this.volume = volume;
this.fromBrick = brick;
setTitle("Migrate Brick [" + volume.getName() + "]");
- // setDescription("Migrate data from one disk to another for the chosen Volume. " +
- // "This will copy all data present in the \"from disk\" of the volume " +
- // "to \"to disk\", remove \"from disk\" from the volume, and " +
- // "add \"to disk\" to the volume");
setPageDescription(null, null);
setPageComplete(false);
}
@@ -162,12 +163,18 @@ public class MigrateDiskPage1 extends WizardPage {
return tableViewerComposite;
}
- public Disk getSourceDisk() {
- return getSelectedDisk(tableViewerFrom);
+ public String getSourceBrickDir() {
+ Disk sourceDisk = getSelectedDisk(tableViewerFrom);
+ return sourceDisk.getQualifiedBrickName(volume.getName());
}
- public Disk getTargetDisk() {
- return getSelectedDisk(tableViewerTo);
+ public String getTargetBrickDir() {
+ Disk targetDisk = getSelectedDisk(tableViewerTo);
+ return targetDisk.getQualifiedBrickName(volume.getName());
+ }
+
+ public Boolean getAutoCommitSelection() {
+ return autoCompleteCheckbox.getSelection();
}
/**
@@ -200,7 +207,7 @@ public class MigrateDiskPage1 extends WizardPage {
GlusterDataModelManager glusterDataModelManager = GlusterDataModelManager.getInstance();
List<Disk> fromBricks = glusterDataModelManager.getReadyDisksOfVolume(volume);
- List<Disk> toDisks = glusterDataModelManager.getReadyDisksOfAllServersExcluding( glusterDataModelManager.getReadyDisksOfVolume(volume));
+ List<Disk> toDisks = glusterDataModelManager.getReadyDisksOfAllServersExcluding( fromBricks );
tableViewerFrom = createTableViewer(container, diskLabelProvider, fromBricks, txtFilterFrom);
@@ -208,6 +215,17 @@ public class MigrateDiskPage1 extends WizardPage {
setFromDisk(tableViewerFrom, fromBrick);
}
tableViewerTo = createTableViewer(container, diskLabelProvider, toDisks, txtFilterTo);
+
+ // Auto commit selection field
+ Composite autoCommitContainer = new Composite(container, SWT.NONE);
+ GridData data = new GridData();
+ data.horizontalSpan = 2;
+ autoCommitContainer.setLayoutData(data);
+ autoCompleteCheckbox = new Button(autoCommitContainer, SWT.CHECK);
+ autoCompleteCheckbox.setSelection(true);
+ Label lblAutoComplete = new Label(autoCommitContainer, SWT.NONE);
+ lblAutoComplete.setText("Auto commit on migration complete");
+ autoCommitContainer.setLayout( container.getLayout());
}
private void setFromDisk(TableViewer tableViewer, Brick brickToSelect) {
@@ -220,9 +238,17 @@ public class MigrateDiskPage1 extends WizardPage {
}
}
}
+
+ private void refreshButtonStatus() {
+ if(tableViewerFrom.getSelection().isEmpty() || tableViewerTo.getSelection().isEmpty()) {
+ setPageComplete(false);
+ } else {
+ setPageComplete(true);
+ }
+ }
private TableViewer createTableViewer(Composite container, ITableLabelProvider diskLabelProvider,
- List<Disk> fromDisks, Text txtFilterText) {
+ List<Disk> bricks, Text txtFilterText) {
Composite tableViewerComposite = createTableViewerComposite(container);
TableViewer tableViewer = new TableViewer(tableViewerComposite, SWT.SINGLE);
@@ -232,7 +258,15 @@ public class MigrateDiskPage1 extends WizardPage {
setupDiskTable(tableViewerComposite, tableViewer.getTable());
guiHelper.createFilter(tableViewer, txtFilterText, false);
- tableViewer.setInput(fromDisks.toArray());
+ tableViewer.setInput(bricks.toArray());
+
+ tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ refreshButtonStatus();
+ }
+ });
return tableViewer;
}
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 60cbd387..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 {
@@ -47,14 +51,24 @@ public class MigrateDiskWizard extends Wizard {
@Override
public boolean performFinish() {
- Disk sourceDisk = page.getSourceDisk();
- Disk targetDisk = page.getTargetDisk();
- Boolean autoCommit = true; //TODO get auto commit from user selection
- // TODO add custom confirm dialog
-
+ String sourceDir = page.getSourceBrickDir();
+ String targetDir = page.getTargetBrickDir();
+ Boolean autoCommit = page.getAutoCommitSelection();
VolumesClient volumesClient = new VolumesClient();
- volumesClient.startMigration(volume.getName(), sourceDisk.getQualifiedName(), targetDisk.getQualifiedName(), autoCommit);
-
+
+ try {
+ 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());
+ }
return true;
}
}
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..431a8128 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<String> 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.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..d6fd5d03 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();
@@ -416,6 +417,7 @@ public class GUIHelper {
return selectedEntities;
}
+
public void configureCheckboxTableViewer(final CheckboxTableViewer tableViewer) {
tableViewer.addCheckStateListener(new ICheckStateListener() {
@@ -450,6 +452,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/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);
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
index b4b31a0a..ab1e55ab 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java
@@ -29,6 +29,7 @@ import com.gluster.storage.management.core.model.Entity;
import com.gluster.storage.management.core.model.EntityGroup;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.Server;
+import com.gluster.storage.management.core.model.TaskInfo;
import com.gluster.storage.management.core.model.Volume;
/**
@@ -80,6 +81,7 @@ public class GlusterViewsManager implements ViewsManager {
private void showViewsForCluster(Cluster cluster) throws PartInitException {
page.showView(ClusterSummaryView.ID);
+ page.showView(TasksView.ID, null, IWorkbenchPage.VIEW_CREATE);
}
private void showViewsForVolume(Volume volume) throws PartInitException {
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java
new file mode 100644
index 00000000..fb772d46
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/TasksView.java
@@ -0,0 +1,39 @@
+package com.gluster.storage.management.gui.views;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+
+import com.gluster.storage.management.client.GlusterDataModelManager;
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.views.pages.TasksPage;
+
+public class TasksView extends ViewPart {
+
+ public static final String ID = TasksView.class.getName();
+ private TasksPage page;
+
+
+ public TasksView() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ page = new TasksPage(getSite(), parent, SWT.NONE, getAllTasks());
+ page.layout(); // IMP: lays out the form properly
+ }
+
+
+ private List<TaskInfo> getAllTasks() {
+ return GlusterDataModelManager.getInstance().getModel().getCluster().getTaskInfoList();
+ }
+
+ @Override
+ public void setFocus() {
+ page.setFocus();
+ }
+
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
index 311014a0..a43330c4 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java
@@ -35,8 +35,8 @@ import com.gluster.storage.management.client.GlusterDataModelManager;
import com.gluster.storage.management.core.model.Alert;
import com.gluster.storage.management.core.model.Cluster;
import com.gluster.storage.management.core.model.EntityGroup;
-import com.gluster.storage.management.core.model.Task.TASK_TYPE;
import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE;
import com.gluster.storage.management.core.model.Volume;
import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS;
import com.gluster.storage.management.gui.IImageKeys;
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java
index 133aed38..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
@@ -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;
@@ -56,7 +57,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage<Disk> im
protected abstract int getStatusColumnIndex();
public AbstractDisksPage(final Composite parent, int style, IWorkbenchSite site, List<Disk> disks) {
- super(site, parent, style, disks);
+ super(site, parent, style, true, true, disks);
this.disks = disks;
// creates hyperlinks for "unitialized" disks
@@ -199,8 +200,11 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage<Disk> 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.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
index dfa06f85..a37773e1 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableViewerPage.java
@@ -26,6 +26,7 @@ import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -50,15 +51,20 @@ import com.gluster.storage.management.gui.utils.GUIHelper;
public abstract class AbstractTableViewerPage<T> extends Composite {
protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
- protected CheckboxTableViewer tableViewer;
+ protected TableViewer tableViewer;
+ private boolean useCheckboxes;
+ private boolean multiSelection;
protected GUIHelper guiHelper = GUIHelper.getInstance();
protected Composite parent;
private Hyperlink linkAll, linkNone;
- public AbstractTableViewerPage(IWorkbenchSite site, final Composite parent, int style, Object model) {
+ public AbstractTableViewerPage(IWorkbenchSite site, final Composite parent, int style, boolean useChechboxes, boolean multiSelection, Object model) {
super(parent, style);
this.parent = parent;
+
+ this.useCheckboxes = useChechboxes;
+ this.multiSelection = multiSelection;
toolkit.adapt(this);
toolkit.paintBordersFor(this);
@@ -69,7 +75,7 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
Text filterText = guiHelper.createFilterText(toolkit, this);
- setupServerTableViewer(site, filterText);
+ setupTableViewer(site, filterText);
tableViewer.setInput(model);
parent.layout(); // Important - this actually paints the table
@@ -78,27 +84,35 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
}
public void createCheckboxSelectionLinks() {
- // create the "select all/none" links
- toolkit.createLabel(this, "Select");
- linkAll = toolkit.createHyperlink(this, "all", SWT.NONE);
- linkAll.addHyperlinkListener(new HyperlinkAdapter() {
- @Override
- public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
- tableViewer.setAllChecked(true);
- tableViewer.setSelection(new StructuredSelection(getAllEntities()));
- }
- });
-
- toolkit.createLabel(this, " / ");
-
- linkNone = toolkit.createHyperlink(this, "none", SWT.NONE);
- linkNone.addHyperlinkListener(new HyperlinkAdapter() {
- @Override
- public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
- tableViewer.setAllChecked(false);
- tableViewer.setSelection(null);
- }
- });
+ if (useCheckboxes) {
+ // create the "select all/none" links
+ toolkit.createLabel(this, "Select");
+ linkAll = toolkit.createHyperlink(this, "all", SWT.NONE);
+ linkAll.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ ((CheckboxTableViewer) tableViewer).setAllChecked(true);
+ tableViewer.setSelection(new StructuredSelection(getAllEntities()));
+ }
+ });
+
+ toolkit.createLabel(this, " / ");
+
+ linkNone = toolkit.createHyperlink(this, "none", SWT.NONE);
+ linkNone.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+ ((CheckboxTableViewer) tableViewer).setAllChecked(false);
+ tableViewer.setSelection(null);
+ }
+ });
+ } else {
+ // create dummy labels to maintain layout
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ toolkit.createLabel(this, "");
+ }
}
private void createListeners(final Composite parent) {
@@ -145,7 +159,7 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
setLayout(layout);
}
- private void setupServerTable(Composite parent, Table table) {
+ protected void setupTable(Composite parent, Table table) {
table.setHeaderVisible(true);
table.setLinesVisible(false);
@@ -155,15 +169,19 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
setColumnProperties(table);
}
- private CheckboxTableViewer createServerTableViewer(Composite parent) {
- CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
+ private void createTableViewer(Composite parent) {
+ int style = SWT.FLAT | SWT.FULL_SELECTION;
+ style |= (multiSelection ? SWT.MULTI : SWT.SINGLE);
+
+ if(useCheckboxes) {
+ tableViewer = CheckboxTableViewer.newCheckList(parent, style);
+ } else {
+ tableViewer = new TableViewer(parent, style);
+ }
tableViewer.setLabelProvider(getLabelProvider());
tableViewer.setContentProvider(getContentProvider());
-
- setupServerTable(parent, tableViewer.getTable());
-
- return tableViewer;
+ setupTable(parent, tableViewer.getTable());
}
private Composite createTableViewerComposite() {
@@ -182,13 +200,15 @@ public abstract class AbstractTableViewerPage<T> extends Composite {
return tableViewerComposite;
}
- private void setupServerTableViewer(IWorkbenchSite site, final Text filterText) {
+ private void setupTableViewer(IWorkbenchSite site, final Text filterText) {
Composite tableViewerComposite = createTableViewerComposite();
- tableViewer = createServerTableViewer(tableViewerComposite);
+ createTableViewer(tableViewerComposite);
site.setSelectionProvider(tableViewer);
- // make sure that table selection is driven by checkbox selection
- guiHelper.configureCheckboxTableViewer(tableViewer);
+ if(useCheckboxes) {
+ // make sure that table selection is driven by checkbox selection
+ guiHelper.configureCheckboxTableViewer((CheckboxTableViewer)tableViewer);
+ }
// Create a case insensitive filter for the table viewer using the filter text field
guiHelper.createFilter(tableViewer, filterText, false);
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
index b83914eb..9805daec 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/BricksPage.java
@@ -47,7 +47,7 @@ public class BricksPage extends AbstractTableViewerPage<Brick> {
"Total Space (GB)", "Status" };
public BricksPage(Composite parent, int style, IWorkbenchSite site, final List<Brick> bricks) {
- super(site, parent, style, bricks);
+ super(site, parent, style, true, true, bricks);
this.bricks = bricks;
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
index 87644622..be4df7ad 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/GlusterServersPage.java
@@ -49,7 +49,7 @@ public class GlusterServersPage extends AbstractTableViewerPage<GlusterServer> {
"IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Free Space (GB)", "Total \n Space (GB)", "Status" }; // Removed "Preferred\nNetwork",
public GlusterServersPage(IWorkbenchSite site, final Composite parent, int style, final EntityGroup<GlusterServer> servers) {
- super(site, parent, style, servers);
+ super(site, parent, style, true, true, servers);
this.glusterServers = servers.getEntities();
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/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/ServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
index 48b8892c..f285dd9f 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java
@@ -55,7 +55,7 @@ public class ServersPage extends AbstractTableViewerPage<Server> {
// "Total Disk\n Space (GB)", "Disk Space\nin Use (GB)"};
public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup<Server> serversGroup) {
- super(site, parent, SWT.NONE, serversGroup);
+ super(site, parent, SWT.NONE, true, true, serversGroup);
this.servers = serversGroup.getEntities();
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java
new file mode 100644
index 00000000..ce68e22f
--- /dev/null
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/TasksPage.java
@@ -0,0 +1,117 @@
+/**
+ * TasksPage.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.gui.views.pages;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.IWorkbenchSite;
+
+import com.gluster.storage.management.core.model.ClusterListener;
+import com.gluster.storage.management.core.model.DefaultClusterListener;
+import com.gluster.storage.management.core.model.TaskInfo;
+import com.gluster.storage.management.gui.TasksTableLabelProvider;
+
+public class TasksPage extends AbstractTableViewerPage<TaskInfo> {
+ private List<TaskInfo> taskInfoList;
+
+ public enum TASK_TABLE_COLUMN_INDICES {
+ TASK, STATUS
+ };
+
+ private static final String[] TASK_TABLE_COLUMN_NAMES = new String[] { "Task", "Status"};
+
+
+ @SuppressWarnings("unchecked")
+ public TasksPage(IWorkbenchSite site, Composite parent, int style, Object taskInfo) {
+ super(site, parent, style, false, false, taskInfo);
+ this.taskInfoList = (List<TaskInfo>) taskInfo;
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#createClusterListener()
+ */
+ @Override
+ protected ClusterListener createClusterListener() {
+ return new DefaultClusterListener() {
+ @Override
+ public void taskAdded(TaskInfo taskInfo) {
+ refreshViewer();
+ }
+
+ @Override
+ public void taskRemoved(TaskInfo taskInfo) {
+ refreshViewer();
+ }
+
+ private void refreshViewer() {
+ tableViewer.refresh();
+ parent.update();
+ }
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getColumnNames()
+ */
+ @Override
+ protected String[] getColumnNames() {
+ return TASK_TABLE_COLUMN_NAMES;
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#setColumnProperties(org.eclipse.swt.widgets.Table)
+ */
+ @Override
+ protected void setColumnProperties(Table table) {
+ guiHelper.setColumnProperties(table, TASK_TABLE_COLUMN_INDICES.TASK.ordinal(), SWT.LEFT, 50);
+ guiHelper.setColumnProperties(table, TASK_TABLE_COLUMN_INDICES.STATUS.ordinal(), SWT.LEFT, 50);
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getLabelProvider()
+ */
+ @Override
+ protected IBaseLabelProvider getLabelProvider() {
+ return new TasksTableLabelProvider();
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getContentProvider()
+ */
+ @Override
+ protected IContentProvider getContentProvider() {
+ return new ArrayContentProvider();
+ }
+
+ /* (non-Javadoc)
+ * @see com.gluster.storage.management.gui.views.pages.AbstractTableViewerPage#getAllEntities()
+ */
+ @Override
+ protected List<TaskInfo> getAllEntities() {
+ return taskInfoList;
+ }
+}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/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) {
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
index bd003f3b..956fc215 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumeOptionsPage.java
@@ -40,6 +40,7 @@ import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
@@ -91,9 +92,9 @@ public class VolumeOptionsPage extends Composite {
toolkit.paintBordersFor(this);
setupPageLayout();
+ addTopButton = createAddButton();
filterText = guiHelper.createFilterText(toolkit, this);
- addTopButton = createAddButton();
setupOptionsTableViewer(filterText);
addBottomButton = createAddButton();
@@ -114,48 +115,7 @@ public class VolumeOptionsPage extends Composite {
}
private Button createAddButton() {
- Button button = toolkit.createButton(this, "&Add", SWT.FLAT);
- button.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- // add an empty option to be filled up by user
- volume.setOption("", "");
-
- tableViewer.refresh();
- tableViewer.setSelection(new StructuredSelection(getEntry("")));
- keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry
-
- // disable the add button AND search filter textbox till user fills up the new option
- setAddButtonsEnabled(false);
- filterText.setEnabled(false);
- }
-
- private Entry<String, String> getEntry(String key) {
- for (Entry<String, String> entry : volume.getOptions().entrySet()) {
- if (entry.getKey().equals(key)) {
- return entry;
- }
- }
- return null;
- }
- });
-
- // Make sure that add button is enabled only when search filter textbox is empty
- filterText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- if (filterText.getText().length() > 0) {
- setAddButtonsEnabled(false);
- } else {
- if (defaultVolumeOptions.size() == volume.getOptions().size()) {
- setAddButtonsEnabled(false);
- } else {
- setAddButtonsEnabled(true);
- }
- }
- }
- });
- return button;
+ return toolkit.createButton(this, "&Add", SWT.FLAT);
}
private void registerListeners(final Composite parent) {
@@ -243,11 +203,55 @@ public class VolumeOptionsPage extends Composite {
return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size() - 1]);
}
};
+
+ SelectionListener addButtonSelectionListener = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // add an empty option to be filled up by user
+ volume.setOption("", "");
+
+ tableViewer.refresh();
+ tableViewer.setSelection(new StructuredSelection(getEntry("")));
+ keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry
+
+ // disable the add button AND search filter textbox till user fills up the new option
+ setAddButtonsEnabled(false);
+ filterText.setEnabled(false);
+ }
+
+ private Entry<String, String> getEntry(String key) {
+ for (Entry<String, String> entry : volume.getOptions().entrySet()) {
+ if (entry.getKey().equals(key)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+ };
+ addTopButton.addSelectionListener(addButtonSelectionListener);
+ addBottomButton.addSelectionListener(addButtonSelectionListener);
+
+ // Make sure that add button is enabled only when search filter textbox is empty
+ filterText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ if (filterText.getText().length() > 0) {
+ setAddButtonsEnabled(false);
+ } else {
+ if (defaultVolumeOptions.size() == volume.getOptions().size()) {
+ setAddButtonsEnabled(false);
+ } else {
+ setAddButtonsEnabled(true);
+ }
+ }
+ }
+ });
+
GlusterDataModelManager.getInstance().addClusterListener(clusterListener);
}
private void setupPageLayout() {
- final GridLayout layout = new GridLayout(1, false);
+ final GridLayout layout = new GridLayout(2, false);
layout.verticalSpacing = 10;
layout.marginTop = 10;
setLayout(layout);
@@ -256,7 +260,7 @@ public class VolumeOptionsPage extends Composite {
private void setupOptionsTable(Composite parent) {
Table table = tableViewer.getTable();
table.setHeaderVisible(true);
- table.setLinesVisible(false);
+ table.setLinesVisible(true);
TableColumnLayout tableColumnLayout = createTableColumnLayout();
parent.setLayout(tableColumnLayout);
@@ -337,7 +341,11 @@ public class VolumeOptionsPage extends Composite {
private Composite createTableViewerComposite() {
Composite tableViewerComposite = new Composite(this, SWT.NO);
tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
- tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.horizontalSpan = 2;
+ tableViewerComposite.setLayoutData(layoutData);
+
return tableViewerComposite;
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
index 3a8891d4..33eb6da7 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java
@@ -48,7 +48,7 @@ public class VolumesPage extends AbstractTableViewerPage<Volume> {
"Number of\nBricks", "Transport Type", "Status" };
public VolumesPage(final Composite parent, IWorkbenchSite site, EntityGroup<Volume> volumes) {
- super(site, parent, SWT.NONE, volumes);
+ super(site, parent, SWT.NONE, true, true, volumes);
}
@Override
diff --git a/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py b/src/com.gluster.storage.management.server.scripts/src/get_volume_brick_log.py
index 7c912412..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
@@ -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,12 @@ 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, 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()
@@ -61,38 +61,32 @@ 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)
if i < 0:
i = 0
+ logMessagesTag = rs.createTag("logMessages")
+ rs.addTag(logMessagesTag)
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()
+ return rs.toxml()
##--end of getVolumeLog()
def main():
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..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,21 +65,32 @@ 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();
+ }
+
+ /**
+ * 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 <b>base URI</b> 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();
}
/**
@@ -123,6 +134,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.
@@ -138,6 +158,17 @@ public class AbstractResource {
}
/**
+ * 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/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 <Server> object
- }
+ // TODO: Remove this class!
}
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/resources/DiscoveredServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/DiscoveredServersResource.java
index aba88d82..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
@@ -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<Server> 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<Server> getDiscoveredServerDetails() {
List<Server> discoveredServers = new ArrayList<Server>();
- List<String> serverNames = getDiscoveredServerNames();
- GenericResponse<Server> 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<Server> 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<Server>(new Status(e), null);
+ // TODO: Log the exception
+ return errorResponse(e.getMessage());
}
- return new GenericResponse<Server>(Status.STATUS_SUCCESS, server);
+ }
+
+ private Server getDiscoveredServer(String serverName) {
+ Server server = new Server(serverName);
+ serverUtil.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());
}
}
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 6e15e106..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
@@ -18,13 +18,14 @@
*******************************************************************************/
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_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 java.util.ArrayList;
import java.util.List;
@@ -33,6 +34,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;
@@ -43,17 +45,16 @@ 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;
import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS;
-import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.response.GlusterServerListResponse;
-import com.gluster.storage.management.core.response.GlusterServerResponse;
-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;
@@ -65,128 +66,90 @@ import com.sun.jersey.spi.resource.Singleton;
public class GlusterServersResource extends AbstractServersResource {
public static final String HOSTNAMETAG = "hostname:";
- private LRUCache<String, GlusterServer> clusterServerCache = new LRUCache<String, GlusterServer>(3);
-
+
@InjectParam
private DiscoveredServersResource discoveredServersResource;
-
+
+ @InjectParam
+ 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) {
+ 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)
- 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<GlusterServer> glusterServers = new ArrayList<GlusterServer>();
-
+
if (clusterName == null || clusterName.isEmpty()) {
return badRequestResponse("Cluster name must not be empty!");
}
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) {
+ if (cluster.getServers().size() == 0) {
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 + "]");
}
-
+
try {
glusterServers = getGlusterServers(clusterName, onlineServer);
- } catch(ConnectionException e) {
+ } 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 + "]");
}
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<GlusterServer> glusterServers, GlusterServer onlineServer) {
String errMsg = "";
-
+
for (GlusterServer server : glusterServers) {
if (server.getStatus() == SERVER_STATUS.ONLINE && !server.getName().equals(onlineServer.getName())) {
try {
@@ -203,13 +166,13 @@ public class GlusterServersResource extends AbstractServersResource {
List<GlusterServer> 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) {
+ onlineServer = clusterService.getNewOnlineServer(clusterName);
+ if (onlineServer == null) {
throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]");
}
-
+
glusterServers = glusterUtil.getGlusterServers(onlineServer);
}
return glusterServers;
@@ -218,8 +181,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);
}
@@ -227,8 +189,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);
}
@@ -236,7 +197,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());
}
}
@@ -255,93 +216,93 @@ 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 + "]");
}
-
+
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);
+ onlineServer = clusterService.getNewOnlineServer(clusterName);
if (onlineServer == null) {
throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]");
}
server = glusterUtil.getGlusterServer(onlineServer, serverName);
}
-
- if(server.isOnline()) {
+
+ if (server.isOnline()) {
fetchServerDetails(server);
}
return server;
}
private void performAddServer(String clusterName, String serverName) {
- GlusterServer onlineServer = getOnlineServer(clusterName);
- if(onlineServer == null) {
+ GlusterServer onlineServer = clusterService.getOnlineServer(clusterName);
+ 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) {
+ onlineServer = clusterService.getNewOnlineServer(clusterName);
+ 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!");
+ return notFoundResponse("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<ServerInfo> 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);
@@ -366,40 +327,39 @@ 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) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ if (cluster == null) {
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
List<ServerInfo> 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);
+ clusterService.removeOnlineServer(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);
+ GlusterServer onlineServer = clusterService.getOnlineServer(clusterName, serverName);
if (onlineServer == null) {
throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]");
}
@@ -408,34 +368,63 @@ 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 + "]");
}
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.removeOnlineServer(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<ServerInfo> 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 + "}/" + 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) {
+
+ 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!");
+ }
+
+ 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());
+ } catch (ConnectionException e) {
+ return errorResponse(e.getMessage());
+ }
+ }
+
private void setGlusterUtil(GlusterUtil glusterUtil) {
this.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..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
@@ -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,25 @@ 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.model.Task;
+import com.gluster.storage.management.core.exceptions.GlusterValidationException;
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.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)
@Singleton
-public class TasksResource {
+public class TasksResource extends AbstractResource {
private Map<String, Task> tasksMap = new HashMap<String, Task>();
public TasksResource() {
}
-
- public void addTask(Task task) { // task should be one of MuigrateDiskTask, FormatDiskTask, etc
+ public void addTask(Task task) {
tasksMap.put(task.getId(), task);
}
@@ -70,18 +69,11 @@ public class TasksResource {
public List<TaskInfo> getAllTasksInfo() {
List<TaskInfo> allTasksInfo = new ArrayList<TaskInfo>();
for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
- allTasksInfo.add(entry.getValue().getTaskInfo());
+ checkTaskStatus(entry.getKey());
+ allTasksInfo.add(entry.getValue().getTaskInfo()); // TaskInfo with latest status
}
return allTasksInfo;
}
-
- public List<Task> getAllTasks() {
- List<Task> allTasks = new ArrayList<Task>();
- for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
- allTasks.add(entry.getValue());
- }
- return allTasks;
- }
public Task getTask(String taskId) {
for (Map.Entry<String, Task> entry : tasksMap.entrySet()) {
@@ -91,63 +83,93 @@ public class TasksResource {
}
return null;
}
-
+
@GET
@Produces(MediaType.APPLICATION_XML)
- public TaskListResponse getTasks() {
- TaskListResponse taskListResponse = new TaskListResponse();
+ public Response getTasks() {
+ try {
+ return okResponse(new TaskInfoListResponse(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, ""));
+ return (Response) noContentResponse();
+ } 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/resources/UsersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/UsersResource.java
index 0326793b..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
@@ -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,68 +28,60 @@ 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;
-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
@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();
}
}
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..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
@@ -23,8 +23,12 @@ 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_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;
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 +37,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 +47,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,16 +94,16 @@ 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.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,14 +112,10 @@ 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;
@InjectParam
@@ -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) {
@@ -145,15 +147,21 @@ public class VolumesResource extends AbstractResource {
return badRequestResponse("Cluster name must not be empty!");
}
- if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ 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);
}
public VolumeListResponse getVolumes(String clusterName) {
- GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
+ GlusterServer onlineServer = clusterService.getOnlineServer(clusterName);
if (onlineServer == null) {
return new VolumeListResponse(new ArrayList<Volume>());
}
@@ -162,7 +170,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<Volume>());
}
@@ -188,7 +196,7 @@ public class VolumesResource extends AbstractResource {
}
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) {
@@ -199,7 +207,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 +217,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 + "]");
}
@@ -274,7 +282,7 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
try {
@@ -287,7 +295,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 +304,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 + "]");
}
@@ -309,7 +317,10 @@ 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!");
}
@@ -319,31 +330,38 @@ public class VolumesResource extends AbstractResource {
}
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 + "]");
+ 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) {
@@ -370,7 +388,7 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
if (deleteFlag == null) {
@@ -386,7 +404,7 @@ public class VolumesResource extends AbstractResource {
}
List<Brick> 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);
@@ -423,14 +441,14 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
if(deleteFlag == null) {
deleteFlag = false;
}
- GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName);
+ GlusterServer onlineServer = clusterService.getOnlineServer(clusterName);
if (onlineServer == null) {
return errorResponse("No online servers found in cluster [" + clusterName + "]");
}
@@ -456,7 +474,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 + "]");
}
@@ -530,10 +548,10 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ 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 + "]");
}
@@ -542,7 +560,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 + "]");
}
@@ -572,10 +590,10 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ 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 + "]");
}
@@ -584,7 +602,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 + "]");
}
@@ -628,27 +646,20 @@ public class VolumesResource extends AbstractResource {
// Usage: get_volume_disk_log.py <volumeName> <diskName> <lineCount>
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<VolumeLogMessage> 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<VolumeLogMessage> logMessages = response.getLogMessages();
- for (VolumeLogMessage logMessage : logMessages) {
- logMessage.setBrickDirectory(brick.getBrickDirectory());
- logMessage.setMessage(logMessage.getMessage().trim());
- logMessage.setSeverity(logMessage.getSeverity().trim());
- }
- return logMessages;
}
@GET
@@ -665,7 +676,7 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
try {
@@ -757,7 +768,7 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ return notFoundResponse("Cluster [" + clusterName + "] not found!");
}
List<VolumeLogMessage> logMessages = null;
@@ -862,10 +873,10 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ 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 + "]");
}
@@ -875,7 +886,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 + "]");
}
@@ -915,10 +926,10 @@ public class VolumesResource extends AbstractResource {
}
if (clusterService.getCluster(clusterName) == null) {
- return badRequestResponse("Cluster [" + clusterName + "] not found!");
+ 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 + "]");
}
@@ -929,23 +940,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.getTaskInfo().getName(); // Return Task ID
+ }
+
+ private String rebalanceStart(String clusterName, String volumeName, Boolean isFixLayout, Boolean isMigrateData,
+ Boolean isForcedDataMigrate) {
+ String layout = "";
+ if (isForcedDataMigrate) {
+ layout = "forced-data-migrate";
+ } else if (isMigrateData) {
+ layout = "migrate-data";
+ } else if (isFixLayout) {
+ layout = "fix-layout";
+ }
+
+ return rebalanceStart(clusterName, volumeName, layout);
+ }
+
+ 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();
+ }
+
+ public void rebalanceStop(String clusterName, String volumeName) {
+ // TODO: arrive at the task id and fetch it
+ String taskId = "";
+
+ taskResource.getTask(taskId).stop();
+ }
+
public static void main(String[] args) throws ClassNotFoundException {
VolumesResource vr = new VolumesResource();
// VolumeListResponse response = vr.getAllVolumes();
@@ -969,6 +1011,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/services/ClusterService.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java
index 0aabb714..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,15 +33,17 @@ 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.Status;
+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;
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,12 +62,70 @@ public class ClusterService {
@Autowired
private SshUtil sshUtil;
+ @Autowired
+ private ServerUtil serverUtil;
+
+ private LRUCache<String, GlusterServer> onlineServerCache = new LRUCache<String, GlusterServer>(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 = onlineServerCache.get(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());
+ 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;
+ }
+ }
+
+ // no online server found.
+ throw new GlusterRuntimeException("No online server found in cluster [" + clusterName + "]");
+ }
+
public List<ClusterInfo> getAllClusters() {
return clusterDao.findAll();
}
public ClusterInfo getCluster(String clusterName) {
- List<ClusterInfo> clusters = clusterDao.findBy("name = ?1", clusterName);
+ List<ClusterInfo> clusters = clusterDao.findBy("UPPER(name) = ?1", clusterName.toUpperCase());
if(clusters.size() == 0) {
return null;
}
@@ -74,7 +134,7 @@ public class ClusterService {
}
public ClusterInfo getClusterForServer(String serverName) {
- List<ServerInfo> servers = serverDao.findBy("name = ?1", serverName);
+ List<ServerInfo> servers = serverDao.findBy("UPPER(name) = ?1", serverName.toUpperCase());
if(servers.size() == 0) {
return null;
}
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..5f3f8e30
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/InitializeDiskTask.java
@@ -0,0 +1,114 @@
+/**
+ * InitializeDiskTask.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.server.tasks;
+
+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.server.services.ClusterService;
+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(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(ClusterService clusterService, String clusterName, TaskInfo info) {
+ super(clusterService, clusterName, info);
+ }
+
+ @Override
+ public String getId() {
+ return taskInfo.getType() + "-" + serverName + ":" + diskName;
+ }
+
+ @Override
+ public void resume() {
+ getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not resume disk initialization")));
+ }
+
+ @Override
+ public void stop() {
+ getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not stop disk initialization")));
+ }
+
+ @Override
+ public void pause() {
+ getTaskInfo().setStatus( new TaskStatus( new Status(Status.STATUS_CODE_FAILURE, "Can not suspend disk initialization")));
+ }
+
+ @Override
+ public void commit() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public TASK_TYPE getType() {
+ return TASK_TYPE.DISK_FORMAT;
+ }
+
+ @Override
+ public TaskInfo getTaskInfo() {
+ return getTaskInfo();
+ }
+
+ @Override
+ public void start() {
+ getTaskInfo().setStatus(
+ new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), INITIALIZE_DISK_SCRIPT + " "
+ + getDiskName()))));
+ }
+
+ @Override
+ public TaskStatus checkStatus() {
+ return new TaskStatus(new Status(sshUtil.executeRemote(getServerName(), INITIALIZE_DISK_STATUS_SCRIPT + " "
+ + 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;
+ }
+}
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..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
@@ -20,13 +20,16 @@
*/
package com.gluster.storage.management.server.tasks;
-import org.springframework.beans.factory.annotation.Autowired;
-
+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;
+import com.sun.jersey.core.util.Base64;
public class MigrateDiskTask extends Task {
@@ -60,67 +63,176 @@ public class MigrateDiskTask extends Task {
this.autoCommit = autoCommit;
}
- public MigrateDiskTask(TASK_TYPE type, String volumeName, String fromBrick, String toBrick) {
- super(type, volumeName);
+ 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);
- setTaskDescription();
- getTaskInfo().setCanPause(true);
- getTaskInfo().setCanStop(true);
+ taskInfo.setName(getId());
}
- public MigrateDiskTask(TaskInfo info) {
- super(info);
- setTaskDescription();
+ public MigrateDiskTask(ClusterService clusterService, String clusterName, TaskInfo info) {
+ super(clusterService, clusterName, info);
}
@Override
public String getId() {
- return getTaskInfo().getId();
+ return new String( Base64.encode( 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() {
+ 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(onlineServerName, command);
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().trim().matches(".*started successfully$")) {
+ getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput().trim())));
+ return;
+ }
+ }
+
+ // if we come here, it means task couldn't be started successfully.
+ throw new GlusterRuntimeException(processResult.toString());
}
@Override
- public TaskInfo resume() {
- return start();
+ 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(onlineServer, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().matches("*pause")) { //TODO replace correct pattern to identify the pause status
+ taskStatus.setCode(Status.STATUS_CODE_PAUSE);
+ taskStatus.setMessage(processResult.getOutput());
+ getTaskInfo().setStatus(taskStatus);
+ return;
+ }
+ }
+
+ // if we reach here, it means rebalance start failed.
+ throw new GlusterRuntimeException(processResult.toString());
+ }
+
+
+ @Override
+ public void resume() {
+ start();
+ }
+
@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 commit() {
+ try {
+ commitMigration(getOnlineServer().getName());
+ } catch(ConnectionException e) {
+ // online server might have gone offline. try with a new one.
+ commitMigration(getNewOnlineServer().getName());
+ }
}
@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 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";
+
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().trim().matches(".*aborted successfully$")) {
+ taskStatus.setCode(Status.STATUS_CODE_SUCCESS);
+ taskStatus.setMessage(processResult.getOutput());
+ getTaskInfo().setStatus(taskStatus);
+ return;
+ }
+ }
+ // if we reach here, it means rebalance start failed.
+ throw new GlusterRuntimeException(processResult.toString());
}
@Override
- public void setTaskDescription() {
- TaskInfo taskInfo = getTaskInfo();
- getTaskInfo().setDescription(
- getTypeStr() + " on volume [" + taskInfo.getReference() + "] from [" + getFromBrick()
- + "] to [" + getToBrick() + "]");
+ 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());
+ }
}
-
- @Override
- public TaskInfo status() {
- return getTaskInfo();
+
+ 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() + " "
+ + getToBrick() + " status";
+ ProcessResult processResult = sshUtil.executeRemote(serverName, command);
+ TaskStatus taskStatus = new TaskStatus();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().trim().matches("^Number of files migrated.*Migration complete$")) {
+ 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 {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+ } else {
+ taskStatus.setCode(Status.STATUS_CODE_FAILURE);
+ }
+
+ 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/RebalanceVolumeTask.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java
new file mode 100644
index 00000000..7f9fb6bf
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/RebalanceVolumeTask.java
@@ -0,0 +1,153 @@
+/**
+ * RebalanceVolumeTask.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.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.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 {
+
+ private String layout;
+ private SshUtil sshUtil = new SshUtil();
+
+ public RebalanceVolumeTask(ClusterService clusterService, String clusterName, TaskInfo taskInfo) {
+ super(clusterService, clusterName, taskInfo);
+ }
+
+ 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
+ public String getId() {
+ return taskInfo.getType() + "-" + taskInfo.getReference();
+ }
+
+ @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);
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().trim().matches(".*has been successful$")) {
+ getTaskInfo().setStatus(new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, processResult.getOutput())));
+ }
+ }
+
+ // if we reach here, it means rebalance start failed.
+ throw new GlusterRuntimeException(processResult.toString());
+ }
+
+ @Override
+ public void resume() {
+ getTaskInfo().setStatus(
+ new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Pause/Resume is not supported in Volume Rebalance")));
+ }
+
+ @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();
+ 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 void pause() {
+ getTaskInfo().setStatus(
+ new TaskStatus(new Status(Status.STATUS_CODE_FAILURE, "Pause/Resume is not supported in Volume Rebalance")));
+ }
+
+ @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();
+ if (processResult.isSuccess()) {
+ if (processResult.getOutput().trim().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) {
+ this.layout = layout;
+ }
+
+ public String getLayout() {
+ 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/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..49cd0b8b
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/tasks/Task.java
@@ -0,0 +1,111 @@
+/**
+ * Task.java
+ *
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+package com.gluster.storage.management.server.tasks;
+
+import com.gluster.storage.management.core.model.GlusterServer;
+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;
+
+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);
+ taskInfo.setCanPause(canPause);
+ taskInfo.setCanStop(canStop);
+ taskInfo.setCanCommit(canCommit);
+
+ 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 670ffb5c..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
@@ -36,7 +36,6 @@ 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.Volume;
import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE;
@@ -47,6 +46,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
@@ -536,21 +536,6 @@ public class GlusterUtil {
return logFileName;
}
-
- 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.setOnlineServer(knownServer);
- migrateDiskTask.setAutoCommit(autoCommit);
-
- TaskInfo taskInfo = migrateDiskTask.start();
- if (taskInfo.isSuccess()) {
- taskResource.addTask(migrateDiskTask);
- }
-
- return taskInfo.getId();
- }
-
public Status removeBricks(String volumeName, List<String> 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..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
@@ -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,21 @@ 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) {
+ throw new GlusterRuntimeException(((Status)response).getMessage());
+ }
+ server.copyFrom((Server) response); // Update the details in <Server> object
+ }
/**
* Executes given command on given server
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..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
@@ -20,14 +20,14 @@ 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.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ch.ethz.ssh2.ChannelCondition;
@@ -61,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 {
@@ -209,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) {
@@ -250,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);
}
}
@@ -259,41 +269,51 @@ 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,
+ 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);
+ 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, StringBuilder output) {
+ private ProcessResult prepareProcessResult(Session session, int condition, String output) {
ProcessResult result = null;
- if (wasTerminated(condition)) {
- result = new ProcessResult(ProcessResult.FAILURE, output.toString());
- } else {
+ 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);
+ break;
+ default:
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);
}
+ 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/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
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 @@
<constructor-arg value="vmware" />
</bean>
+ <!-- SSH timeouts - all in milliseconds. zero means no timeout. -->
+ <!-- Connect the underlying TCP socket to the server with the given timeout value (SSH) -->
+ <bean id="sshConnectTimeout" class="java.lang.Integer">
+ <constructor-arg value="10000" />
+ </bean>
+ <!-- Timeout for complete connection establishment (SSH) -->
+ <bean id="sshKexTimeout" class="java.lang.Integer">
+ <constructor-arg value="60000" />
+ </bean>
+ <!-- Command execution timeout (SSH) -->
+ <bean id="sshExecTimeout" class="java.lang.Integer">
+ <constructor-arg value="120000" />
+ </bean>
+
<!-- Gluster Management Gateway Version -->
<bean id="appVersion" class="java.lang.String">
<constructor-arg value="1.0.0" />