From 585603532b2fea19e2784a4aa8e0dbf904e7b4d6 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 3 Jun 2011 20:03:04 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- .../src/disable-ssh-password-auth.sh | 30 ++++++++++++++++++++++ .../server/resources/ClustersResource.java | 1 - .../storage/management/server/utils/SshUtil.java | 12 +++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100755 src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh diff --git a/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh b/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh new file mode 100755 index 00000000..07ee1a3a --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +#----------------------------------------------------------------------------- +# disable-ssh-password-auth.sh +# Script for disabling SSH password authentication. This is used by the +# management gateway after installing the public key, so that the gluster +# node can be accessed (using ssh) only from the management gateway. +#----------------------------------------------------------------------------- + +CONFIG_FILE="/etc/ssh/sshd_config" +TIMESTAMP=`date +%d%m%Y%H%M%S` +BACKUP_FILE="${CONFIG_FILE}_${TIMESTAMP}" +TEMP_FILE="/tmp/new_sshd_config_${TIMESTAMP}" + +# Modify config file to disable password authentication, redirect to a temp file +# TODO: disable only if enabled! +sed "s/^PasswordAuthentication yes$/PasswordAuthentication no/g" ${CONFIG_FILE} > ${TEMP_FILE} + +# Secure the file by changing permissions (600) +chmod 600 ${TEMP_FILE} + +# Take backup of config file +cp ${CONFIG_FILE} ${BACKUP_FILE} + +# Overwrite config file with the modified one +mv ${TEMP_FILE} ${CONFIG_FILE} + +# Re-start ssh daemon +/etc/init.d/sshd restart + 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 6955b723..e1971322 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 @@ -93,7 +93,6 @@ public class ClustersResource { return new StringListResponse(clusterList); } - @SuppressWarnings("unchecked") @POST @Produces(MediaType.TEXT_XML) public Status createCluster(@FormParam(FORM_PARAM_CLUSTER_NAME) String clusterName) { 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 82cec63b..1cc51d23 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 @@ -55,6 +55,7 @@ public class SshUtil { private LRUCache sshConnCache = new LRUCache(10); private static final File PEM_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa"); private static final File PUBLIC_KEY_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa.pub"); + private static final String SCRIPT_DISABLE_SSH_PASSWORD_AUTH = "disable-ssh-password-auth.sh"; // TODO: Make user name configurable private static final String USER_NAME = "root"; @@ -89,7 +90,6 @@ public class SshUtil { localTempFile.delete(); } try { - // get authorized_keys from server scpClient.get(SSH_AUTHORIZED_KEYS_PATH, TEMP_DIR); } catch (IOException e) { @@ -119,7 +119,15 @@ public class SshUtil { throw new GlusterRuntimeException("Couldn't add public key to server [" + serverName + "]", e); } - // TODO: Disable password based ssh connections + disableSshPasswordLogin(serverName, scpClient); + } + + private void disableSshPasswordLogin(String serverName, SCPClient scpClient) { + ProcessResult result = executeRemote(serverName, SCRIPT_DISABLE_SSH_PASSWORD_AUTH); + if(!result.isSuccess()) { + throw new GlusterRuntimeException("Couldn't disable SSH password authentication on [" + serverName + + "]. Error: " + result); + } } private Connection getConnectionWithPassword(String serverName) { -- cgit From d7d090fb9881cec058cb08ef8bc76126041dc893 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 3 Jun 2011 20:03:04 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- build/package-scripts.sh | 2 +- .../src/disable-ssh-password-auth.sh | 30 ++++++++++++++++++++++ .../server/resources/ClustersResource.java | 1 - .../storage/management/server/utils/SshUtil.java | 12 +++++++-- 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100755 src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh diff --git a/build/package-scripts.sh b/build/package-scripts.sh index 723d2d05..142e079e 100755 --- a/build/package-scripts.sh +++ b/build/package-scripts.sh @@ -12,7 +12,7 @@ prepare-script-dir() get-scripts() { cd ${DIR_NAME} - cp ../src/com.gluster.storage.management.server.scripts/src/*.py . + cp ../src/com.gluster.storage.management.server.scripts/src/*.* . cd - } diff --git a/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh b/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh new file mode 100755 index 00000000..07ee1a3a --- /dev/null +++ b/src/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +#----------------------------------------------------------------------------- +# disable-ssh-password-auth.sh +# Script for disabling SSH password authentication. This is used by the +# management gateway after installing the public key, so that the gluster +# node can be accessed (using ssh) only from the management gateway. +#----------------------------------------------------------------------------- + +CONFIG_FILE="/etc/ssh/sshd_config" +TIMESTAMP=`date +%d%m%Y%H%M%S` +BACKUP_FILE="${CONFIG_FILE}_${TIMESTAMP}" +TEMP_FILE="/tmp/new_sshd_config_${TIMESTAMP}" + +# Modify config file to disable password authentication, redirect to a temp file +# TODO: disable only if enabled! +sed "s/^PasswordAuthentication yes$/PasswordAuthentication no/g" ${CONFIG_FILE} > ${TEMP_FILE} + +# Secure the file by changing permissions (600) +chmod 600 ${TEMP_FILE} + +# Take backup of config file +cp ${CONFIG_FILE} ${BACKUP_FILE} + +# Overwrite config file with the modified one +mv ${TEMP_FILE} ${CONFIG_FILE} + +# Re-start ssh daemon +/etc/init.d/sshd restart + 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 6955b723..e1971322 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 @@ -93,7 +93,6 @@ public class ClustersResource { return new StringListResponse(clusterList); } - @SuppressWarnings("unchecked") @POST @Produces(MediaType.TEXT_XML) public Status createCluster(@FormParam(FORM_PARAM_CLUSTER_NAME) String clusterName) { 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 82cec63b..1cc51d23 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 @@ -55,6 +55,7 @@ public class SshUtil { private LRUCache sshConnCache = new LRUCache(10); private static final File PEM_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa"); private static final File PUBLIC_KEY_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa.pub"); + private static final String SCRIPT_DISABLE_SSH_PASSWORD_AUTH = "disable-ssh-password-auth.sh"; // TODO: Make user name configurable private static final String USER_NAME = "root"; @@ -89,7 +90,6 @@ public class SshUtil { localTempFile.delete(); } try { - // get authorized_keys from server scpClient.get(SSH_AUTHORIZED_KEYS_PATH, TEMP_DIR); } catch (IOException e) { @@ -119,7 +119,15 @@ public class SshUtil { throw new GlusterRuntimeException("Couldn't add public key to server [" + serverName + "]", e); } - // TODO: Disable password based ssh connections + disableSshPasswordLogin(serverName, scpClient); + } + + private void disableSshPasswordLogin(String serverName, SCPClient scpClient) { + ProcessResult result = executeRemote(serverName, SCRIPT_DISABLE_SSH_PASSWORD_AUTH); + if(!result.isSuccess()) { + throw new GlusterRuntimeException("Couldn't disable SSH password authentication on [" + serverName + + "]. Error: " + result); + } } private Connection getConnectionWithPassword(String serverName) { -- cgit From 4d109b1521c1f6e09f007aeacbb319443c45dfc8 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 6 Jun 2011 13:37:16 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- .../storage/management/client/VolumesClient.java | 14 ++-- .../management/core/constants/RESTConstants.java | 2 +- .../gui/views/details/VolumeLogsPage.java | 26 +++---- .../server/resources/GlusterServersResource.java | 68 +++-------------- .../server/resources/VolumesResource.java | 31 ++++++-- .../management/server/services/ClusterService.java | 87 ++++++++++++++++++++++ 6 files changed, 140 insertions(+), 88 deletions(-) create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java 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 4ab21a01..43435675 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 @@ -120,8 +120,8 @@ public class VolumesClient extends AbstractClient { * * @param volumeName * Name of volume whose logs are to be fetched - * @param diskName - * Name of the disk whose logs are to be fetched. Pass ALL to fetch log messages from all disks of the + * @param brickName + * Name of the brick whose logs are to be fetched. Pass ALL to fetch log messages from all bricks of the * volume. * @param severity * Log severity {@link GlusterConstants#VOLUME_LOG_LEVELS_ARR}. Pass ALL to fetch log messages of all @@ -134,9 +134,9 @@ public class VolumesClient extends AbstractClient { * Number of most recent log messages to be fetched (from each disk) * @return Log Message List response received from the Gluster Management Server. */ - public LogMessageListResponse getLogs(String volumeName, String diskName, String severity, Date fromTimestamp, + public LogMessageListResponse getLogs(String volumeName, String brickName, String severity, Date fromTimestamp, Date toTimestamp, int messageCount) { - MultivaluedMap queryParams = prepareGetLogQueryParams(diskName, severity, fromTimestamp, + MultivaluedMap queryParams = prepareGetLogQueryParams(brickName, severity, fromTimestamp, toTimestamp, messageCount); return (LogMessageListResponse) fetchSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS, @@ -169,12 +169,12 @@ public class VolumesClient extends AbstractClient { return queryParams; } - private MultivaluedMap prepareGetLogQueryParams(String diskName, String severity, + private MultivaluedMap prepareGetLogQueryParams(String brickName, String severity, Date fromTimestamp, Date toTimestamp, int messageCount) { MultivaluedMap queryParams = new MultivaluedMapImpl(); queryParams.add(RESTConstants.QUERY_PARAM_LINE_COUNT, "" + messageCount); - if (!diskName.equals(CoreConstants.ALL)) { - queryParams.add(RESTConstants.QUERY_PARAM_DISK_NAME, diskName); + if (!brickName.equals(CoreConstants.ALL)) { + queryParams.add(RESTConstants.QUERY_PARAM_BRICK_NAME, brickName); } if (!severity.equals(CoreConstants.ALL)) { 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 33323021..428eb53f 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 @@ -57,7 +57,7 @@ public class RESTConstants { public static final String PATH_PARAM_CLUSTER_NAME = "clusterName"; public static final String PATH_PARAM_SERVER_NAME = "serverName"; - public static final String QUERY_PARAM_DISK_NAME = "diskName"; + public static final String QUERY_PARAM_BRICK_NAME = "brickName"; public static final String QUERY_PARAM_DISKS = "disks"; public static final String QUERY_PARAM_BRICKS = "bricks"; public static final String QUERY_PARAM_LINE_COUNT = "lineCount"; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java index 811b4c5c..f2170162 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java @@ -73,7 +73,7 @@ public class VolumeLogsPage extends Composite { private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Disk", "Severity", "Message" }; private TableViewer tableViewer; - private Combo disksCombo; + private Combo bricksCombo; private Combo severityCombo; private DateTime fromDate; private DateTime fromTime; @@ -110,8 +110,8 @@ public class VolumeLogsPage extends Composite { createLineCountLabel(composite); createLineCountText(composite); - createDiskLabel(composite); - createDisksCombo(composite); + createBricksLabel(composite); + createBricksCombo(composite); createSeverityLabel(composite); createSeverityCombo(composite); @@ -185,7 +185,7 @@ public class VolumeLogsPage extends Composite { return; } - LogMessageListResponse response = client.getLogs(volume.getName(), disksCombo.getText(), + LogMessageListResponse response = client.getLogs(volume.getName(), bricksCombo.getText(), severityCombo.getText(), fromTimestamp, toTimestamp, Integer.parseInt(lineCountText.getText())); Status status = response.getStatus(); if (status.isSuccess()) { @@ -321,17 +321,17 @@ public class VolumeLogsPage extends Composite { lblSeverity.setBounds(480, 15, 70, 20); } - private void createDisksCombo(Composite composite) { - disksCombo = new Combo(composite, SWT.READ_ONLY); - disksCombo.setBounds(365, 15, 100, 20); - disksCombo.setItems( volume.getBrickDirectories().toArray(new String[0])); - disksCombo.add(CoreConstants.ALL, 0); - toolkit.adapt(disksCombo); - toolkit.paintBordersFor(disksCombo); - disksCombo.select(0); + private void createBricksCombo(Composite composite) { + bricksCombo = new Combo(composite, SWT.READ_ONLY); + bricksCombo.setBounds(365, 15, 100, 20); + bricksCombo.setItems( volume.getBrickDirectories().toArray(new String[0])); + bricksCombo.add(CoreConstants.ALL, 0); + toolkit.adapt(bricksCombo); + toolkit.paintBordersFor(bricksCombo); + bricksCombo.select(0); } - private void createDiskLabel(Composite composite) { + private void createBricksLabel(Composite composite) { Label lblMessagesAndFilter = toolkit.createLabel(composite, "messages, and filter on bricks", SWT.NONE); lblMessagesAndFilter.setBounds(160, 15, 200, 20); } 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 608783a1..7de9015d 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,16 +18,15 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; import java.util.ArrayList; import java.util.List; -import javax.persistence.EntityTransaction; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; @@ -42,7 +41,6 @@ import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; -import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.model.Status; @@ -50,8 +48,8 @@ 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.PersistenceDao; import com.gluster.storage.management.server.data.ServerInfo; +import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.SshUtil; import com.sun.jersey.api.core.InjectParam; @@ -69,7 +67,7 @@ public class GlusterServersResource extends AbstractServersResource { private DiscoveredServersResource discoveredServersResource; @Autowired - private PersistenceDao clusterDao; + private ClusterService clusterService; @Autowired private SshUtil sshUtil; @@ -103,8 +101,7 @@ public class GlusterServersResource extends AbstractServersResource { // Doesn't use cache public GlusterServer getNewOnlineServer(String clusterName, String exceptServerName) { - // no known online server for this cluster. find one. - ClusterInfo cluster = getCluster(clusterName); + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return null; } @@ -129,7 +126,7 @@ public class GlusterServersResource extends AbstractServersResource { @PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { List glusterServers = new ArrayList(); - ClusterInfo cluster = getCluster(clusterName); + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return new GlusterServerListResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"), null); @@ -226,7 +223,7 @@ public class GlusterServersResource extends AbstractServersResource { @Produces(MediaType.TEXT_XML) public GlusterServerResponse addServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @FormParam(FORM_PARAM_SERVER_NAME) String serverName) { - ClusterInfo cluster = getCluster(clusterName); + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"), null); @@ -255,7 +252,7 @@ public class GlusterServersResource extends AbstractServersResource { try { // add the cluster-server mapping - addServerToCluster(clusterName, serverName); + clusterService.mapServerToCluster(clusterName, serverName); } catch (Exception e) { return new GlusterServerResponse(new Status(Status.STATUS_CODE_PART_SUCCESS, e.getMessage()), null); } @@ -281,59 +278,12 @@ public class GlusterServersResource extends AbstractServersResource { return serverResponse; } - private void addServerToCluster(String clusterName, String serverName) { - EntityTransaction txn = clusterDao.startTransaction(); - ClusterInfo cluster = getCluster(clusterName); - ServerInfo server = new ServerInfo(serverName); - server.setCluster(cluster); - try { - clusterDao.save(server); - cluster.addServer(server); - clusterDao.update(cluster); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - throw new GlusterRuntimeException("Couldn't create cluster-server mapping [" + clusterName + "][" - + serverName + "]! Error: " + e.getMessage(), e); - } - } - - private void removeServerFromCluster(String clusterName, String serverName) { - EntityTransaction txn = clusterDao.startTransaction(); - ClusterInfo cluster = getCluster(clusterName); - List servers = cluster.getServers(); - for(ServerInfo server : servers) { - if(server.getName().equals(serverName)) { - servers.remove(server); - clusterDao.delete(server); - break; - } - } - try { - clusterDao.update(cluster); - txn.commit(); - } catch(Exception e) { - txn.rollback(); - throw new GlusterRuntimeException("Couldn't unmap server [" + serverName + "] from cluster [" + clusterName - + "]! Error: " + e.getMessage(), e); - } - } - - private ClusterInfo getCluster(String clusterName) { - List clusters = clusterDao.findBy("name = ?1", clusterName); - if(clusters.size() == 0) { - return null; - } - - return clusters.get(0); - } - @DELETE @Produces(MediaType.TEXT_XML) @Path("{" + PATH_PARAM_SERVER_NAME + "}") public Status removeServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { - ClusterInfo cluster = getCluster(clusterName); + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"); } @@ -379,7 +329,7 @@ public class GlusterServersResource extends AbstractServersResource { try { - removeServerFromCluster(clusterName, serverName); + clusterService.unmapServerFromCluster(clusterName, serverName); } catch (Exception e) { return new Status(Status.STATUS_CODE_PART_SUCCESS, e.getMessage()); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index d16f7678..204d23a9 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 @@ -29,9 +29,8 @@ import static com.gluster.storage.management.core.constants.RESTConstants.FORM_P import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_VOLUME_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICKS; +import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_BRICK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DELETE_OPTION; -import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DISK_NAME; -import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DOWNLOAD; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_FROM_TIMESTAMP; 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; @@ -69,6 +68,8 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.StreamingOutput; +import org.springframework.beans.factory.annotation.Autowired; + import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; @@ -87,6 +88,8 @@ import com.gluster.storage.management.core.utils.FileUtil; import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; +import com.gluster.storage.management.server.data.ClusterInfo; +import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.ServerUtil; import com.sun.jersey.api.core.InjectParam; @@ -102,11 +105,14 @@ public class VolumesResource { @InjectParam private GlusterServersResource glusterServersResource; - @InjectParam + @Autowired private ServerUtil serverUtil; - @InjectParam + @Autowired private GlusterUtil glusterUtil; + + @Autowired + private ClusterService clusterService; private FileUtil fileUtil = new FileUtil(); @@ -467,17 +473,26 @@ public class VolumesResource { @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS) public LogMessageListResponse getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, - @QueryParam(QUERY_PARAM_DISK_NAME) String brickName, + @QueryParam(QUERY_PARAM_BRICK_NAME) String brickName, @QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity, @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, - @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, - @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { + @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount) { List logMessages = null; + ClusterInfo cluster = clusterService.getCluster(clusterName); + if(cluster == null) { + return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + + "] doesn't exist!"), null); + } + try { - // TODO: Fetch logs from brick(s) of given cluster only Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); + if(volume == null) { + return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Volume [" + volumeName + + "] doesn't exist in cluster [" + clusterName + "]!"), null); + } + if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) { logMessages = getLogsForAllBricks(volume, lineCount); } else { 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 new file mode 100644 index 00000000..d043278c --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.services; + +import java.util.List; + +import javax.persistence.EntityTransaction; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.server.data.ClusterInfo; +import com.gluster.storage.management.server.data.PersistenceDao; +import com.gluster.storage.management.server.data.ServerInfo; + +/** + * Service class for functionality related to clusters + */ +@Component +public class ClusterService { + @Autowired + private PersistenceDao clusterDao; + + public ClusterInfo getCluster(String clusterName) { + List clusters = clusterDao.findBy("name = ?1", clusterName); + if(clusters.size() == 0) { + return null; + } + + return clusters.get(0); + } + + public void mapServerToCluster(String clusterName, String serverName) { + EntityTransaction txn = clusterDao.startTransaction(); + ClusterInfo cluster = getCluster(clusterName); + ServerInfo server = new ServerInfo(serverName); + server.setCluster(cluster); + try { + clusterDao.save(server); + cluster.addServer(server); + clusterDao.update(cluster); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + throw new GlusterRuntimeException("Couldn't create cluster-server mapping [" + clusterName + "][" + + serverName + "]! Error: " + e.getMessage(), e); + } + } + + public void unmapServerFromCluster(String clusterName, String serverName) { + EntityTransaction txn = clusterDao.startTransaction(); + ClusterInfo cluster = getCluster(clusterName); + List servers = cluster.getServers(); + for(ServerInfo server : servers) { + if(server.getName().equals(serverName)) { + servers.remove(server); + clusterDao.delete(server); + break; + } + } + try { + clusterDao.update(cluster); + txn.commit(); + } catch(Exception e) { + txn.rollback(); + throw new GlusterRuntimeException("Couldn't unmap server [" + serverName + "] from cluster [" + clusterName + + "]! Error: " + e.getMessage(), e); + } + } +} -- cgit From f21ed62520fe8a8fec4f6180ebaab070b2a24598 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Mon, 6 Jun 2011 14:56:31 +0530 Subject: UI Changes - Disk to brick label changes --- .../storage/management/core/model/Alert.java | 4 +- .../management/core/model/GlusterDummyModel.java | 12 +-- .../storage/management/core/model/LogMessage.java | 91 ------------------ .../storage/management/core/model/RunningTask.java | 4 +- .../management/core/model/VolumeLogMessage.java | 102 +++++++++++++++++++++ .../core/response/LogMessageListResponse.java | 12 +-- .../gui/VolumeLogTableLabelProvider.java | 8 +- .../management/gui/dialogs/CreateVolumePage1.java | 8 +- .../management/gui/views/ClusterSummaryView.java | 4 +- .../management/gui/views/VolumeSummaryView.java | 2 +- .../management/gui/views/VolumesSummaryView.java | 6 +- .../gui/views/details/VolumeLogsPage.java | 12 +-- .../server/resources/AlertsResource.java | 2 +- .../server/resources/RunningTaskResource.java | 4 +- .../server/resources/VolumesResource.java | 33 +++---- 15 files changed, 158 insertions(+), 146 deletions(-) delete mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java index c0077a30..db8a9018 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java @@ -6,11 +6,11 @@ import javax.xml.bind.annotation.XmlRootElement; public class Alert { public enum ALERT_TYPES { - CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_DISKS_ALERT, OFFLINE_SERVERS_ALERT + CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_BRICKS_ALERT, OFFLINE_SERVERS_ALERT }; public static final String[] ALERT_TYPE_STR = { "High CPU Usage", "High Memory Usage", "Low Disk Space", - "Offline Disk", "Offline Server" }; + "Offline Brick", "Offline Server" }; protected String id; protected ALERT_TYPES type; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java index eed67904..40de70ec 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java @@ -34,7 +34,7 @@ public class GlusterDummyModel { private GlusterServer server1, server2, server3, server4, server5; private Volume volume1, volume2, volume3, volume4, volume5; private Disk s1da, s1db, s2da, s2db, s2dc, s2dd, s3da, s4da, s5da, s5db; - private static List logMessages = new ArrayList(); + private static List logMessages = new ArrayList(); private static GlusterDummyModel instance = new GlusterDummyModel(); private GlusterDataModel model; @@ -212,21 +212,21 @@ public class GlusterDummyModel { cluster.setAutoDiscoveredServers(servers); } - private void addMessages(List messages, Disk disk, String severity, int count) { + private void addMessages(List messages, Disk disk, String severity, int count) { for (int i = 1; i <= count; i++) { String message = severity + "message" + i; - messages.add(new LogMessage(new Date(), disk.getQualifiedName(), severity, message)); + messages.add(new VolumeLogMessage(new Date(), disk.getQualifiedName(), disk.getMountPoint(), severity, message)); } } - private void addMessagesForDisk(List logMessages, Disk disk) { + private void addMessagesForDisk(List logMessages, Disk disk) { addMessages(logMessages, disk, "SEVERE", 5); addMessages(logMessages, disk, "WARNING", 5); addMessages(logMessages, disk, "DEBUG", 5); addMessages(logMessages, disk, "INFO", 5); } - public List createDummyLogMessages() { + public List createDummyLogMessages() { addMessagesForDisk(logMessages, s1da); addMessagesForDisk(logMessages, s1db); addMessagesForDisk(logMessages, s2da); @@ -239,7 +239,7 @@ public class GlusterDummyModel { return logMessages; } - public static List getDummyLogMessages() { + public static List getDummyLogMessages() { return logMessages; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java deleted file mode 100644 index 15c758a1..00000000 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Gluster, Inc. - * This file is part of Gluster Management Console. - * - * Gluster Management Console is free software; you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Gluster Management Console is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License - * for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * . - *******************************************************************************/ -package com.gluster.storage.management.core.model; - -import java.util.Date; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.gluster.storage.management.core.model.adapters.VolumeLogDateAdapter; -import com.gluster.storage.management.core.utils.StringUtil; - -@XmlRootElement -public class LogMessage implements Filterable { - private Date timestamp; - // TODO: Replace disk with brick, rename class as VolumeLogMessage - private String disk; - private String severity; - private String message; - - public LogMessage() { - } - - public LogMessage(String logMessage) { - // TODO: Parse the log message and extract fields - } - - @XmlElement(name = "timestamp", required = true) - @XmlJavaTypeAdapter(VolumeLogDateAdapter.class) - public Date getTimestamp() { - return timestamp; - } - - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - - public String getDisk() { - return disk; - } - - public void setDisk(String disk) { - this.disk = disk; - } - - public String getSeverity() { - return severity; - } - - public void setSeverity(String severity) { - this.severity = severity; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public LogMessage(Date timestamp, String disk, String severity, String message) { - setTimestamp(timestamp); - setDisk(disk); - setSeverity(severity); - setMessage(message); - } - - @Override - public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getSeverity() + getTimestamp() + getDisk() + getMessage(), filterString, - caseSensitive); - } -} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java index 24b342e2..773137bb 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java @@ -23,10 +23,10 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class RunningTask { public enum TASK_TYPES { - DISK_FORMAT, DISK_MIGRATE, VOLUME_REBALANCE + DISK_FORMAT, BRICK_MIGRATE, VOLUME_REBALANCE }; - public String[] TASK_TYPE_STR = { "Formatting Disk", "Disk Migration", "Volume Rebalance" }; + public String[] TASK_TYPE_STR = { "Formatting Disk", "Brick Migration", "Volume Rebalance" }; protected String id; protected TASK_TYPES type; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java new file mode 100644 index 00000000..ab88d917 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.gluster.storage.management.core.model.adapters.VolumeLogDateAdapter; +import com.gluster.storage.management.core.utils.StringUtil; + +@XmlRootElement +public class VolumeLogMessage implements Filterable { + private Date timestamp; + // TODO: Replace disk with brick, rename class as VolumeLogMessage + private String brick; + private String disk; + private String severity; + private String message; + + public VolumeLogMessage() { + } + + public VolumeLogMessage(String logMessage) { + // TODO: Parse the log message and extract fields + } + + @XmlElement(name = "timestamp", required = true) + @XmlJavaTypeAdapter(VolumeLogDateAdapter.class) + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getDisk() { + return disk; + } + + public void setDisk(String disk) { + this.disk = disk; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setBrickDirectory(String brickDirectory) { + this.brick = brickDirectory; + } + + public String getBrickDirectory() { + return brick; + } + + public VolumeLogMessage(Date timestamp, String disk, String brickDirectory, String severity, String message) { + setTimestamp(timestamp); + setDisk(disk); + setBrickDirectory(brickDirectory); + setSeverity(severity); + setMessage(message); + } + + @Override + public boolean filter(String filterString, boolean caseSensitive) { + return StringUtil.filterString(getSeverity() + getTimestamp() + getDisk() + getMessage(), filterString, + caseSensitive); + } + +} 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 191334d3..be374e8b 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 @@ -10,28 +10,28 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.model.Status; @XmlRootElement(name = "response") public class LogMessageListResponse extends AbstractResponse { - private List logMessages = new ArrayList(); + private List logMessages = new ArrayList(); public LogMessageListResponse() { } - public LogMessageListResponse(Status status, List logMessages) { + public LogMessageListResponse(Status status, List logMessages) { setStatus(status); setLogMessages(logMessages); } @XmlElementWrapper(name = "logMessages") - @XmlElement(name = "logMessage", type = LogMessage.class) - public List getLogMessages() { + @XmlElement(name = "logMessage", type = VolumeLogMessage.class) + public List getLogMessages() { return logMessages; } - public void setLogMessages(List logMessages) { + public void setLogMessages(List logMessages) { this.logMessages = logMessages; } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java index 9858a25b..396d1821 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java @@ -19,21 +19,21 @@ package com.gluster.storage.management.gui; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.utils.DateUtil; import com.gluster.storage.management.gui.views.details.VolumeLogsPage.LOG_TABLE_COLUMN_INDICES; public class VolumeLogTableLabelProvider extends TableLabelProviderAdapter { @Override public String getColumnText(Object element, int columnIndex) { - if (!(element instanceof LogMessage)) { + if (!(element instanceof VolumeLogMessage)) { return null; } - LogMessage logMessage = (LogMessage) element; + VolumeLogMessage logMessage = (VolumeLogMessage) element; return (columnIndex == LOG_TABLE_COLUMN_INDICES.DATE.ordinal() ? DateUtil.formatDate(logMessage.getTimestamp()) : columnIndex == LOG_TABLE_COLUMN_INDICES.TIME.ordinal() ? DateUtil.formatTime(logMessage.getTimestamp()) - : columnIndex == LOG_TABLE_COLUMN_INDICES.DISK.ordinal() ? logMessage.getDisk() + : columnIndex == LOG_TABLE_COLUMN_INDICES.BRICK.ordinal() ? logMessage.getBrickDirectory() : columnIndex == LOG_TABLE_COLUMN_INDICES.SEVERITY.ordinal() ? "" + logMessage.getSeverity() : columnIndex == LOG_TABLE_COLUMN_INDICES.MESSAGE.ordinal() ? logMessage.getMessage() : "Invalid"); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java index d46c71d8..e7f46a66 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java @@ -213,7 +213,7 @@ public class CreateVolumePage1 extends WizardPage { private void createDisksLabel(Composite container) { Label lblDisks = new Label(container, SWT.RIGHT); lblDisks.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - lblDisks.setText("Disks: "); + lblDisks.setText("Bricks: "); } private void createTransportTypeValueLabel(Composite container) { @@ -340,15 +340,15 @@ public class CreateVolumePage1 extends WizardPage { int diskCount = selectedDisks.size(); if(diskCount < 1) { - setError("At least one disk must be selected!"); + setError("At least one brick must be selected!"); } VOLUME_TYPE volumeType = (VOLUME_TYPE) ((IStructuredSelection) typeComboViewer .getSelection()).getFirstElement(); if (volumeType == VOLUME_TYPE.DISTRIBUTED_MIRROR && diskCount % 2 != 0) { - setError("Mirror type volume requires disks in multiples of two"); + setError("Mirror type volume requires bricks in multiples of two"); } else if (volumeType == VOLUME_TYPE.DISTRIBUTED_STRIPE && diskCount % 4 != 0) { - setError("Stripe type volume requires disks in multiples of four"); + setError("Stripe type volume requires bricks in multiples of four"); } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index da9d6544..cc5c2b63 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -184,7 +184,7 @@ public class ClusterSummaryView extends ViewPart { CLabel lblAlert = new CLabel(section, SWT.FLAT); Image alertImage = null; switch (alert.getType()) { - case OFFLINE_VOLUME_DISKS_ALERT: + case OFFLINE_VOLUME_BRICKS_ALERT: alertImage = guiHelper.getImage(IImageKeys.DISK_OFFLINE); break; case DISK_USAGE_ALERT: @@ -293,7 +293,7 @@ public class ClusterSummaryView extends ViewPart { case DISK_FORMAT: taskImage = guiHelper.getImage(IImageKeys.DISK); break; - case DISK_MIGRATE: + case BRICK_MIGRATE: taskImage = guiHelper.getImage(IImageKeys.DISK_MIGRATE); break; case VOLUME_REBALANCE: diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java index 11717ee7..2d9b8700 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java @@ -127,7 +127,7 @@ public class VolumeSummaryView extends ViewPart { List alerts = GlusterDataModelManager.getInstance().getModel().getCluster().getAlerts(); for (int i = 0; i < alerts.size(); i++) { - if (alerts.get(i).getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT + if (alerts.get(i).getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT && alerts.get(i).getReference().split(":")[0].trim().equals(volume.getName())) { addAlertLabel(section, alerts.get(i)); } 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 7909f155..990e569c 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 @@ -96,7 +96,7 @@ public class VolumesSummaryView extends ViewPart { } private void addAlertLabel(Composite section, Alert alert) { - if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT) { + if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT) { CLabel lblAlert = new CLabel(section, SWT.NONE); lblAlert.setImage((alert.getType() == Alert.ALERT_TYPES.DISK_USAGE_ALERT) ? guiHelper .getImage(IImageKeys.LOW_DISK_SPACE) : guiHelper.getImage(IImageKeys.DISK_OFFLINE)); @@ -118,14 +118,14 @@ public class VolumesSummaryView extends ViewPart { private void addRunningTaskLabel(Composite section, RunningTask task) { // Task related to Volumes context - if (task.getType() == RunningTask.TASK_TYPES.DISK_MIGRATE + if (task.getType() == RunningTask.TASK_TYPES.BRICK_MIGRATE || task.getType() == RunningTask.TASK_TYPES.VOLUME_REBALANCE) { if (task.getStatus().isPercentageSupported()) { // TODO Progress bar } CLabel lblAlert = new CLabel(section, SWT.NONE); lblAlert.setText(task.getTaskInfo()); - lblAlert.setImage((task.getType() == RunningTask.TASK_TYPES.DISK_MIGRATE) ? guiHelper + lblAlert.setImage((task.getType() == RunningTask.TASK_TYPES.BRICK_MIGRATE) ? guiHelper .getImage(IImageKeys.DISK_MIGRATE) : guiHelper.getImage(IImageKeys.VOLUME_REBALANCE)); lblAlert.redraw(); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java index 811b4c5c..a7249dab 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java @@ -51,7 +51,7 @@ import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.GlusterConstants; import com.gluster.storage.management.core.constants.GlusterConstants.VOLUME_LOG_LEVELS; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.response.LogMessageListResponse; @@ -68,10 +68,10 @@ public class VolumeLogsPage extends Composite { private Volume volume; public enum LOG_TABLE_COLUMN_INDICES { - DATE, TIME, DISK, SEVERITY, MESSAGE + DATE, TIME, BRICK, SEVERITY, MESSAGE }; - private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Disk", "Severity", "Message" }; + private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Brick", "Severity", "Message" }; private TableViewer tableViewer; private Combo disksCombo; private Combo severityCombo; @@ -189,8 +189,8 @@ public class VolumeLogsPage extends Composite { severityCombo.getText(), fromTimestamp, toTimestamp, Integer.parseInt(lineCountText.getText())); Status status = response.getStatus(); if (status.isSuccess()) { - List logMessages = response.getLogMessages(); - tableViewer.setInput(logMessages.toArray(new LogMessage[0])); + List logMessages = response.getLogMessages(); + tableViewer.setInput(logMessages.toArray(new VolumeLogMessage[0])); tableViewer.refresh(); } else { MessageDialog.openError(getShell(), "Volume Logs", "Error while fetching volume logs: [" + status @@ -373,7 +373,7 @@ public class VolumeLogsPage extends Composite { setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DATE, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.TIME, SWT.CENTER, 50); - setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DISK, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.BRICK, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.SEVERITY, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.MESSAGE, SWT.LEFT, 100); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java index 4283b5d6..060ce60c 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java @@ -54,7 +54,7 @@ public class AlertsResource { alert = new Alert(); alert.setId("0004"); alert.setReference("Volume3:server2:sda1"); // volume:[Disk name] - alert.setType(Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT); + alert.setType(Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT); alert.setMessage(alert.getAlertType(alert.getType()) + " in volume [" + alert.getReference().split(":")[0] + "] disk [" + alert.getReference().split(":")[1] + ":" + alert.getReference().split(":")[2] + "]"); alerts.add(alert); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java index 10ce5da3..c9eb0ecd 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java @@ -76,10 +76,10 @@ public class RunningTaskResource { // MigrateDisk task = new RunningTask(); task.setId("0003"); - task.setType(RunningTask.TASK_TYPES.DISK_MIGRATE); + task.setType(RunningTask.TASK_TYPES.BRICK_MIGRATE); task.setReference("Volume3:server1:sda1"); // Disk reference task.setTaskInfo(task.getTaskType(task.getType()) + " for volume [" + task.getReference().split(":")[0] - + "] disk [" + task.getReference().split(":")[1] + ":" + task.getReference().split(":")[2] + "]"); + + "] brick [" + task.getReference().split(":")[1] + ":" + task.getReference().split(":")[2] + "]"); task.setStatus(taskStatus); runningTasks.add(task); 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 d16f7678..92a4e0cf 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 @@ -75,9 +75,9 @@ import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.GlusterServer; -import com.gluster.storage.management.core.model.LogMessage; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; +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.VolumeListResponse; @@ -385,7 +385,7 @@ public class VolumesResource { return new Status(Status.STATUS_CODE_SUCCESS, "Directories cleaned up successfully!"); } - private List getBrickLogs(Volume volume, Brick brick, Integer lineCount) + private List getBrickLogs(Volume volume, Brick brick, Integer lineCount) throws GlusterRuntimeException { String logDir = glusterUtil.getLogLocation(volume.getName(), brick.getQualifiedName(), brick.getServerName()); String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); @@ -408,9 +408,10 @@ public class VolumesResource { } // populate disk and trim other fields - List logMessages = response.getLogMessages(); - for (LogMessage logMessage : logMessages) { + List logMessages = response.getLogMessages(); + for (VolumeLogMessage logMessage : logMessages) { logMessage.setDisk(brick.getDiskName()); + logMessage.setBrickDirectory(brick.getBrickDirectory()); logMessage.setMessage(logMessage.getMessage().trim()); logMessage.setSeverity(logMessage.getSeverity().trim()); } @@ -473,7 +474,7 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { - List logMessages = null; + List logMessages = null; try { // TODO: Fetch logs from brick(s) of given cluster only @@ -498,7 +499,7 @@ public class VolumesResource { return new LogMessageListResponse(Status.STATUS_SUCCESS, logMessages); } - private void filterLogsByTime(List logMessages, String fromTimestamp, String toTimestamp) { + private void filterLogsByTime(List logMessages, String fromTimestamp, String toTimestamp) { Date fromTime = null, toTime = null; if (fromTimestamp != null && !fromTimestamp.isEmpty()) { @@ -509,8 +510,8 @@ public class VolumesResource { toTime = DateUtil.stringToDate(toTimestamp); } - List messagesToRemove = new ArrayList(); - for (LogMessage logMessage : logMessages) { + List messagesToRemove = new ArrayList(); + for (VolumeLogMessage logMessage : logMessages) { Date logTimestamp = logMessage.getTimestamp(); if (fromTime != null && logTimestamp.before(fromTime)) { messagesToRemove.add(logMessage); @@ -524,13 +525,13 @@ public class VolumesResource { logMessages.removeAll(messagesToRemove); } - private void filterLogsBySeverity(List logMessages, String severity) { + private void filterLogsBySeverity(List logMessages, String severity) { if (severity == null || severity.isEmpty()) { return; } - List messagesToRemove = new ArrayList(); - for (LogMessage logMessage : logMessages) { + List messagesToRemove = new ArrayList(); + for (VolumeLogMessage logMessage : logMessages) { if (!logMessage.getSeverity().equals(severity)) { messagesToRemove.add(logMessage); } @@ -538,18 +539,18 @@ public class VolumesResource { logMessages.removeAll(messagesToRemove); } - private List getLogsForAllBricks(Volume volume, Integer lineCount) { - List logMessages; - logMessages = new ArrayList(); + private List getLogsForAllBricks(Volume volume, Integer lineCount) { + List logMessages; + logMessages = new ArrayList(); // fetch logs for every brick of the volume for (Brick brick : volume.getBricks()) { logMessages.addAll(getBrickLogs(volume, brick, lineCount)); } // Sort the log messages based on log timestamp - Collections.sort(logMessages, new Comparator() { + Collections.sort(logMessages, new Comparator() { @Override - public int compare(LogMessage message1, LogMessage message2) { + public int compare(VolumeLogMessage message1, VolumeLogMessage message2) { return message1.getTimestamp().compareTo(message2.getTimestamp()); } }); -- cgit From 623a16fef5f5e1885dbc273b1220430c7d1e79ce Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Mon, 6 Jun 2011 14:56:31 +0530 Subject: UI Changes - Disk to brick label changes --- .../storage/management/core/model/Alert.java | 4 +- .../management/core/model/GlusterDummyModel.java | 12 +-- .../storage/management/core/model/LogMessage.java | 91 ---------------------- .../storage/management/core/model/RunningTask.java | 4 +- .../management/core/model/VolumeLogMessage.java | 91 ++++++++++++++++++++++ .../core/response/LogMessageListResponse.java | 12 +-- .../gui/VolumeLogTableLabelProvider.java | 8 +- .../management/gui/dialogs/CreateVolumePage1.java | 8 +- .../management/gui/views/ClusterSummaryView.java | 4 +- .../management/gui/views/VolumeSummaryView.java | 2 +- .../management/gui/views/VolumesSummaryView.java | 6 +- .../gui/views/details/VolumeLogsPage.java | 12 +-- .../server/resources/AlertsResource.java | 2 +- .../server/resources/RunningTaskResource.java | 4 +- .../server/resources/VolumesResource.java | 34 ++++---- 15 files changed, 147 insertions(+), 147 deletions(-) delete mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java index c0077a30..db8a9018 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java @@ -6,11 +6,11 @@ import javax.xml.bind.annotation.XmlRootElement; public class Alert { public enum ALERT_TYPES { - CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_DISKS_ALERT, OFFLINE_SERVERS_ALERT + CPU_USAGE_ALERT, MEMORY_USAGE_ALERT, DISK_USAGE_ALERT, OFFLINE_VOLUME_BRICKS_ALERT, OFFLINE_SERVERS_ALERT }; public static final String[] ALERT_TYPE_STR = { "High CPU Usage", "High Memory Usage", "Low Disk Space", - "Offline Disk", "Offline Server" }; + "Offline Brick", "Offline Server" }; protected String id; protected ALERT_TYPES type; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java index eed67904..8921287a 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java @@ -34,7 +34,7 @@ public class GlusterDummyModel { private GlusterServer server1, server2, server3, server4, server5; private Volume volume1, volume2, volume3, volume4, volume5; private Disk s1da, s1db, s2da, s2db, s2dc, s2dd, s3da, s4da, s5da, s5db; - private static List logMessages = new ArrayList(); + private static List logMessages = new ArrayList(); private static GlusterDummyModel instance = new GlusterDummyModel(); private GlusterDataModel model; @@ -212,21 +212,21 @@ public class GlusterDummyModel { cluster.setAutoDiscoveredServers(servers); } - private void addMessages(List messages, Disk disk, String severity, int count) { + private void addMessages(List messages, Disk disk, String severity, int count) { for (int i = 1; i <= count; i++) { String message = severity + "message" + i; - messages.add(new LogMessage(new Date(), disk.getQualifiedName(), severity, message)); + messages.add(new VolumeLogMessage(new Date(), disk.getMountPoint(), severity, message)); } } - private void addMessagesForDisk(List logMessages, Disk disk) { + private void addMessagesForDisk(List logMessages, Disk disk) { addMessages(logMessages, disk, "SEVERE", 5); addMessages(logMessages, disk, "WARNING", 5); addMessages(logMessages, disk, "DEBUG", 5); addMessages(logMessages, disk, "INFO", 5); } - public List createDummyLogMessages() { + public List createDummyLogMessages() { addMessagesForDisk(logMessages, s1da); addMessagesForDisk(logMessages, s1db); addMessagesForDisk(logMessages, s2da); @@ -239,7 +239,7 @@ public class GlusterDummyModel { return logMessages; } - public static List getDummyLogMessages() { + public static List getDummyLogMessages() { return logMessages; } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java deleted file mode 100644 index 15c758a1..00000000 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Gluster, Inc. - * This file is part of Gluster Management Console. - * - * Gluster Management Console is free software; you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Gluster Management Console is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License - * for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * . - *******************************************************************************/ -package com.gluster.storage.management.core.model; - -import java.util.Date; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -import com.gluster.storage.management.core.model.adapters.VolumeLogDateAdapter; -import com.gluster.storage.management.core.utils.StringUtil; - -@XmlRootElement -public class LogMessage implements Filterable { - private Date timestamp; - // TODO: Replace disk with brick, rename class as VolumeLogMessage - private String disk; - private String severity; - private String message; - - public LogMessage() { - } - - public LogMessage(String logMessage) { - // TODO: Parse the log message and extract fields - } - - @XmlElement(name = "timestamp", required = true) - @XmlJavaTypeAdapter(VolumeLogDateAdapter.class) - public Date getTimestamp() { - return timestamp; - } - - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - - public String getDisk() { - return disk; - } - - public void setDisk(String disk) { - this.disk = disk; - } - - public String getSeverity() { - return severity; - } - - public void setSeverity(String severity) { - this.severity = severity; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public LogMessage(Date timestamp, String disk, String severity, String message) { - setTimestamp(timestamp); - setDisk(disk); - setSeverity(severity); - setMessage(message); - } - - @Override - public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getSeverity() + getTimestamp() + getDisk() + getMessage(), filterString, - caseSensitive); - } -} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java index 24b342e2..773137bb 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java @@ -23,10 +23,10 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class RunningTask { public enum TASK_TYPES { - DISK_FORMAT, DISK_MIGRATE, VOLUME_REBALANCE + DISK_FORMAT, BRICK_MIGRATE, VOLUME_REBALANCE }; - public String[] TASK_TYPE_STR = { "Formatting Disk", "Disk Migration", "Volume Rebalance" }; + public String[] TASK_TYPE_STR = { "Formatting Disk", "Brick Migration", "Volume Rebalance" }; protected String id; protected TASK_TYPES type; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java new file mode 100644 index 00000000..b87c46f0 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.util.Date; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.gluster.storage.management.core.model.adapters.VolumeLogDateAdapter; +import com.gluster.storage.management.core.utils.StringUtil; + +@XmlRootElement +public class VolumeLogMessage implements Filterable { + private Date timestamp; + private String brick; + private String severity; + private String message; + + public VolumeLogMessage() { + } + + public VolumeLogMessage(String logMessage) { + // TODO: Parse the log message and extract fields + } + + @XmlElement(name = "timestamp", required = true) + @XmlJavaTypeAdapter(VolumeLogDateAdapter.class) + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setBrickDirectory(String brickDirectory) { + this.brick = brickDirectory; + } + + public String getBrickDirectory() { + return brick; + } + + public VolumeLogMessage(Date timestamp, String brickDirectory, String severity, String message) { + setTimestamp(timestamp); + setBrickDirectory(brickDirectory); + setSeverity(severity); + setMessage(message); + } + + @Override + public boolean filter(String filterString, boolean caseSensitive) { + return StringUtil.filterString(getSeverity() + getTimestamp() + getBrickDirectory() + getMessage(), filterString, + caseSensitive); + } + +} 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 191334d3..be374e8b 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 @@ -10,28 +10,28 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.model.Status; @XmlRootElement(name = "response") public class LogMessageListResponse extends AbstractResponse { - private List logMessages = new ArrayList(); + private List logMessages = new ArrayList(); public LogMessageListResponse() { } - public LogMessageListResponse(Status status, List logMessages) { + public LogMessageListResponse(Status status, List logMessages) { setStatus(status); setLogMessages(logMessages); } @XmlElementWrapper(name = "logMessages") - @XmlElement(name = "logMessage", type = LogMessage.class) - public List getLogMessages() { + @XmlElement(name = "logMessage", type = VolumeLogMessage.class) + public List getLogMessages() { return logMessages; } - public void setLogMessages(List logMessages) { + public void setLogMessages(List logMessages) { this.logMessages = logMessages; } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java index 9858a25b..396d1821 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java @@ -19,21 +19,21 @@ package com.gluster.storage.management.gui; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.utils.DateUtil; import com.gluster.storage.management.gui.views.details.VolumeLogsPage.LOG_TABLE_COLUMN_INDICES; public class VolumeLogTableLabelProvider extends TableLabelProviderAdapter { @Override public String getColumnText(Object element, int columnIndex) { - if (!(element instanceof LogMessage)) { + if (!(element instanceof VolumeLogMessage)) { return null; } - LogMessage logMessage = (LogMessage) element; + VolumeLogMessage logMessage = (VolumeLogMessage) element; return (columnIndex == LOG_TABLE_COLUMN_INDICES.DATE.ordinal() ? DateUtil.formatDate(logMessage.getTimestamp()) : columnIndex == LOG_TABLE_COLUMN_INDICES.TIME.ordinal() ? DateUtil.formatTime(logMessage.getTimestamp()) - : columnIndex == LOG_TABLE_COLUMN_INDICES.DISK.ordinal() ? logMessage.getDisk() + : columnIndex == LOG_TABLE_COLUMN_INDICES.BRICK.ordinal() ? logMessage.getBrickDirectory() : columnIndex == LOG_TABLE_COLUMN_INDICES.SEVERITY.ordinal() ? "" + logMessage.getSeverity() : columnIndex == LOG_TABLE_COLUMN_INDICES.MESSAGE.ordinal() ? logMessage.getMessage() : "Invalid"); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java index d46c71d8..e7f46a66 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java @@ -213,7 +213,7 @@ public class CreateVolumePage1 extends WizardPage { private void createDisksLabel(Composite container) { Label lblDisks = new Label(container, SWT.RIGHT); lblDisks.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - lblDisks.setText("Disks: "); + lblDisks.setText("Bricks: "); } private void createTransportTypeValueLabel(Composite container) { @@ -340,15 +340,15 @@ public class CreateVolumePage1 extends WizardPage { int diskCount = selectedDisks.size(); if(diskCount < 1) { - setError("At least one disk must be selected!"); + setError("At least one brick must be selected!"); } VOLUME_TYPE volumeType = (VOLUME_TYPE) ((IStructuredSelection) typeComboViewer .getSelection()).getFirstElement(); if (volumeType == VOLUME_TYPE.DISTRIBUTED_MIRROR && diskCount % 2 != 0) { - setError("Mirror type volume requires disks in multiples of two"); + setError("Mirror type volume requires bricks in multiples of two"); } else if (volumeType == VOLUME_TYPE.DISTRIBUTED_STRIPE && diskCount % 4 != 0) { - setError("Stripe type volume requires disks in multiples of four"); + setError("Stripe type volume requires bricks in multiples of four"); } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index da9d6544..cc5c2b63 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -184,7 +184,7 @@ public class ClusterSummaryView extends ViewPart { CLabel lblAlert = new CLabel(section, SWT.FLAT); Image alertImage = null; switch (alert.getType()) { - case OFFLINE_VOLUME_DISKS_ALERT: + case OFFLINE_VOLUME_BRICKS_ALERT: alertImage = guiHelper.getImage(IImageKeys.DISK_OFFLINE); break; case DISK_USAGE_ALERT: @@ -293,7 +293,7 @@ public class ClusterSummaryView extends ViewPart { case DISK_FORMAT: taskImage = guiHelper.getImage(IImageKeys.DISK); break; - case DISK_MIGRATE: + case BRICK_MIGRATE: taskImage = guiHelper.getImage(IImageKeys.DISK_MIGRATE); break; case VOLUME_REBALANCE: diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java index 11717ee7..2d9b8700 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java @@ -127,7 +127,7 @@ public class VolumeSummaryView extends ViewPart { List alerts = GlusterDataModelManager.getInstance().getModel().getCluster().getAlerts(); for (int i = 0; i < alerts.size(); i++) { - if (alerts.get(i).getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT + if (alerts.get(i).getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT && alerts.get(i).getReference().split(":")[0].trim().equals(volume.getName())) { addAlertLabel(section, alerts.get(i)); } 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 7909f155..990e569c 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 @@ -96,7 +96,7 @@ public class VolumesSummaryView extends ViewPart { } private void addAlertLabel(Composite section, Alert alert) { - if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT) { + if (alert.getType() == Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT) { CLabel lblAlert = new CLabel(section, SWT.NONE); lblAlert.setImage((alert.getType() == Alert.ALERT_TYPES.DISK_USAGE_ALERT) ? guiHelper .getImage(IImageKeys.LOW_DISK_SPACE) : guiHelper.getImage(IImageKeys.DISK_OFFLINE)); @@ -118,14 +118,14 @@ public class VolumesSummaryView extends ViewPart { private void addRunningTaskLabel(Composite section, RunningTask task) { // Task related to Volumes context - if (task.getType() == RunningTask.TASK_TYPES.DISK_MIGRATE + if (task.getType() == RunningTask.TASK_TYPES.BRICK_MIGRATE || task.getType() == RunningTask.TASK_TYPES.VOLUME_REBALANCE) { if (task.getStatus().isPercentageSupported()) { // TODO Progress bar } CLabel lblAlert = new CLabel(section, SWT.NONE); lblAlert.setText(task.getTaskInfo()); - lblAlert.setImage((task.getType() == RunningTask.TASK_TYPES.DISK_MIGRATE) ? guiHelper + lblAlert.setImage((task.getType() == RunningTask.TASK_TYPES.BRICK_MIGRATE) ? guiHelper .getImage(IImageKeys.DISK_MIGRATE) : guiHelper.getImage(IImageKeys.VOLUME_REBALANCE)); lblAlert.redraw(); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java index 811b4c5c..a7249dab 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java @@ -51,7 +51,7 @@ import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.GlusterConstants; import com.gluster.storage.management.core.constants.GlusterConstants.VOLUME_LOG_LEVELS; -import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.model.VolumeLogMessage; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.response.LogMessageListResponse; @@ -68,10 +68,10 @@ public class VolumeLogsPage extends Composite { private Volume volume; public enum LOG_TABLE_COLUMN_INDICES { - DATE, TIME, DISK, SEVERITY, MESSAGE + DATE, TIME, BRICK, SEVERITY, MESSAGE }; - private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Disk", "Severity", "Message" }; + private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Brick", "Severity", "Message" }; private TableViewer tableViewer; private Combo disksCombo; private Combo severityCombo; @@ -189,8 +189,8 @@ public class VolumeLogsPage extends Composite { severityCombo.getText(), fromTimestamp, toTimestamp, Integer.parseInt(lineCountText.getText())); Status status = response.getStatus(); if (status.isSuccess()) { - List logMessages = response.getLogMessages(); - tableViewer.setInput(logMessages.toArray(new LogMessage[0])); + List logMessages = response.getLogMessages(); + tableViewer.setInput(logMessages.toArray(new VolumeLogMessage[0])); tableViewer.refresh(); } else { MessageDialog.openError(getShell(), "Volume Logs", "Error while fetching volume logs: [" + status @@ -373,7 +373,7 @@ public class VolumeLogsPage extends Composite { setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DATE, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.TIME, SWT.CENTER, 50); - setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DISK, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.BRICK, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.SEVERITY, SWT.CENTER, 50); setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.MESSAGE, SWT.LEFT, 100); } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java index 4283b5d6..060ce60c 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java @@ -54,7 +54,7 @@ public class AlertsResource { alert = new Alert(); alert.setId("0004"); alert.setReference("Volume3:server2:sda1"); // volume:[Disk name] - alert.setType(Alert.ALERT_TYPES.OFFLINE_VOLUME_DISKS_ALERT); + alert.setType(Alert.ALERT_TYPES.OFFLINE_VOLUME_BRICKS_ALERT); alert.setMessage(alert.getAlertType(alert.getType()) + " in volume [" + alert.getReference().split(":")[0] + "] disk [" + alert.getReference().split(":")[1] + ":" + alert.getReference().split(":")[2] + "]"); alerts.add(alert); diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java index 10ce5da3..c9eb0ecd 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java @@ -76,10 +76,10 @@ public class RunningTaskResource { // MigrateDisk task = new RunningTask(); task.setId("0003"); - task.setType(RunningTask.TASK_TYPES.DISK_MIGRATE); + task.setType(RunningTask.TASK_TYPES.BRICK_MIGRATE); task.setReference("Volume3:server1:sda1"); // Disk reference task.setTaskInfo(task.getTaskType(task.getType()) + " for volume [" + task.getReference().split(":")[0] - + "] disk [" + task.getReference().split(":")[1] + ":" + task.getReference().split(":")[2] + "]"); + + "] brick [" + task.getReference().split(":")[1] + ":" + task.getReference().split(":")[2] + "]"); task.setStatus(taskStatus); runningTasks.add(task); 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 d16f7678..b3f7f365 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 @@ -75,9 +75,9 @@ import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.GlusterServer; -import com.gluster.storage.management.core.model.LogMessage; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; +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.VolumeListResponse; @@ -385,7 +385,7 @@ public class VolumesResource { return new Status(Status.STATUS_CODE_SUCCESS, "Directories cleaned up successfully!"); } - private List getBrickLogs(Volume volume, Brick brick, Integer lineCount) + private List getBrickLogs(Volume volume, Brick brick, Integer lineCount) throws GlusterRuntimeException { String logDir = glusterUtil.getLogLocation(volume.getName(), brick.getQualifiedName(), brick.getServerName()); String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); @@ -408,9 +408,9 @@ public class VolumesResource { } // populate disk and trim other fields - List logMessages = response.getLogMessages(); - for (LogMessage logMessage : logMessages) { - logMessage.setDisk(brick.getDiskName()); + List logMessages = response.getLogMessages(); + for (VolumeLogMessage logMessage : logMessages) { + logMessage.setBrickDirectory(brick.getBrickDirectory()); logMessage.setMessage(logMessage.getMessage().trim()); logMessage.setSeverity(logMessage.getSeverity().trim()); } @@ -473,7 +473,7 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { - List logMessages = null; + List logMessages = null; try { // TODO: Fetch logs from brick(s) of given cluster only @@ -498,7 +498,7 @@ public class VolumesResource { return new LogMessageListResponse(Status.STATUS_SUCCESS, logMessages); } - private void filterLogsByTime(List logMessages, String fromTimestamp, String toTimestamp) { + private void filterLogsByTime(List logMessages, String fromTimestamp, String toTimestamp) { Date fromTime = null, toTime = null; if (fromTimestamp != null && !fromTimestamp.isEmpty()) { @@ -509,8 +509,8 @@ public class VolumesResource { toTime = DateUtil.stringToDate(toTimestamp); } - List messagesToRemove = new ArrayList(); - for (LogMessage logMessage : logMessages) { + List messagesToRemove = new ArrayList(); + for (VolumeLogMessage logMessage : logMessages) { Date logTimestamp = logMessage.getTimestamp(); if (fromTime != null && logTimestamp.before(fromTime)) { messagesToRemove.add(logMessage); @@ -524,13 +524,13 @@ public class VolumesResource { logMessages.removeAll(messagesToRemove); } - private void filterLogsBySeverity(List logMessages, String severity) { + private void filterLogsBySeverity(List logMessages, String severity) { if (severity == null || severity.isEmpty()) { return; } - List messagesToRemove = new ArrayList(); - for (LogMessage logMessage : logMessages) { + List messagesToRemove = new ArrayList(); + for (VolumeLogMessage logMessage : logMessages) { if (!logMessage.getSeverity().equals(severity)) { messagesToRemove.add(logMessage); } @@ -538,18 +538,18 @@ public class VolumesResource { logMessages.removeAll(messagesToRemove); } - private List getLogsForAllBricks(Volume volume, Integer lineCount) { - List logMessages; - logMessages = new ArrayList(); + private List getLogsForAllBricks(Volume volume, Integer lineCount) { + List logMessages; + logMessages = new ArrayList(); // fetch logs for every brick of the volume for (Brick brick : volume.getBricks()) { logMessages.addAll(getBrickLogs(volume, brick, lineCount)); } // Sort the log messages based on log timestamp - Collections.sort(logMessages, new Comparator() { + Collections.sort(logMessages, new Comparator() { @Override - public int compare(LogMessage message1, LogMessage message2) { + public int compare(VolumeLogMessage message1, VolumeLogMessage message2) { return message1.getTimestamp().compareTo(message2.getTimestamp()); } }); -- cgit From bfedf9c486788a74cae2c8cb8d97d52fab67bbeb Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 6 Jun 2011 13:37:16 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- .../storage/management/client/VolumesClient.java | 2 +- .../management/server/resources/VolumesResource.java | 20 ++++++++++++++------ .../storage/management/server/utils/ServerUtil.java | 4 ++-- .../storage/management/server/utils/SshUtil.java | 11 +++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) 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 43435675..424fbca7 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 @@ -144,7 +144,7 @@ public class VolumesClient extends AbstractClient { } public void downloadLogs(String volumeName, String filePath) { - downloadSubResource((volumeName) + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); + downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); } public Status removeBricks(String volumeName, List BrickList, boolean deleteOption) { 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 c14290f8..7ef917bd 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 @@ -427,15 +427,24 @@ public class VolumesResource { @GET @Produces(MediaType.APPLICATION_OCTET_STREAM) @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS + "/" + RESOURCE_DOWNLOAD) - public StreamingOutput getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, + public StreamingOutput downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { + final ClusterInfo cluster = clusterService.getCluster(clusterName); + if(cluster == null) { + throw new GlusterRuntimeException("Cluster [" + clusterName + "] doesn't exist!"); + } + + final Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); + if(volume == null) { + throw new GlusterRuntimeException("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + + "]!"); + } + return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { - Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); try { - // TODO: pass clusterName to downloadLogs File archiveFile = new File(downloadLogs(volume)); output.write(fileUtil.readFileAsByteArray(archiveFile)); archiveFile.delete(); @@ -457,8 +466,7 @@ public class VolumesResource { String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); String logFilePath = logDir + CoreConstants.FILE_SEPARATOR + logFileName; - String logContents = serverUtil.getFileFromServer(brick.getServerName(), logFilePath); - fileUtil.createTextFile(tempDirPath + CoreConstants.FILE_SEPARATOR + logFileName, logContents); + serverUtil.getFileFromServer(brick.getServerName(), logFilePath, tempDirPath); } String gzipPath = fileUtil.getTempDirName() + CoreConstants.FILE_SEPARATOR + volume.getName() + "-logs.tar.gz"; @@ -479,7 +487,7 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount) { - List logMessages = null; + List logMessages = null; ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { 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 2a055ee8..ed1aea75 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 @@ -161,8 +161,8 @@ public class ServerUtil { // } // } - public String getFileFromServer(String serverName, String fileName) { - return executeOnServer(serverName, "get_file " + fileName); + public void getFileFromServer(String serverName, String remoteFileName, String localDirName) { + sshUtil.getFile(serverName, remoteFileName, localDirName); } /** 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 1cc51d23..a4728d21 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 @@ -80,6 +80,17 @@ public class SshUtil { } } + public void getFile(String serverName, String remoteFile, String localDir) { + try { + Connection conn = getConnection(serverName); + SCPClient scpClient = new SCPClient(conn); + scpClient.get(remoteFile, localDir); + } catch (IOException e) { + throw new GlusterRuntimeException("Error while fetching file [" + remoteFile + "] from server [" + + serverName + "]", e); + } + } + public synchronized void installPublicKey(String serverName) { Connection conn = getConnectionWithPassword(serverName); SCPClient scpClient = new SCPClient(conn); -- cgit From d75e0387f3c75fa812acd10c258fe33f31ddf8df Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 6 Jun 2011 13:37:16 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- build/package-server.sh | 3 ++- .../storage/management/client/VolumesClient.java | 2 +- .../management/server/resources/VolumesResource.java | 20 ++++++++++++++------ .../storage/management/server/utils/ServerUtil.java | 4 ++-- .../storage/management/server/utils/SshUtil.java | 11 +++++++++++ 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/build/package-server.sh b/build/package-server.sh index 62aae70d..ddd6a92f 100755 --- a/build/package-server.sh +++ b/build/package-server.sh @@ -13,7 +13,8 @@ prepare-dist-dir() get-server-war() { cd ${WAR_NAME} - WAR_FILE=`find -L ${SERVER_DIST_DIR} -name ${WAR_NAME}` + #WAR_FILE=`find -L ${SERVER_DIST_DIR} -name ${WAR_NAME}` + WAR_FILE=`find ${SERVER_DIST_DIR} -name ${WAR_NAME}` jar xvf ${WAR_FILE} cd - } 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 43435675..424fbca7 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 @@ -144,7 +144,7 @@ public class VolumesClient extends AbstractClient { } public void downloadLogs(String volumeName, String filePath) { - downloadSubResource((volumeName) + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); + downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); } public Status removeBricks(String volumeName, List BrickList, boolean deleteOption) { 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 c14290f8..7ef917bd 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 @@ -427,15 +427,24 @@ public class VolumesResource { @GET @Produces(MediaType.APPLICATION_OCTET_STREAM) @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS + "/" + RESOURCE_DOWNLOAD) - public StreamingOutput getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, + public StreamingOutput downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { + final ClusterInfo cluster = clusterService.getCluster(clusterName); + if(cluster == null) { + throw new GlusterRuntimeException("Cluster [" + clusterName + "] doesn't exist!"); + } + + final Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); + if(volume == null) { + throw new GlusterRuntimeException("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + + "]!"); + } + return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { - Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); try { - // TODO: pass clusterName to downloadLogs File archiveFile = new File(downloadLogs(volume)); output.write(fileUtil.readFileAsByteArray(archiveFile)); archiveFile.delete(); @@ -457,8 +466,7 @@ public class VolumesResource { String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); String logFilePath = logDir + CoreConstants.FILE_SEPARATOR + logFileName; - String logContents = serverUtil.getFileFromServer(brick.getServerName(), logFilePath); - fileUtil.createTextFile(tempDirPath + CoreConstants.FILE_SEPARATOR + logFileName, logContents); + serverUtil.getFileFromServer(brick.getServerName(), logFilePath, tempDirPath); } String gzipPath = fileUtil.getTempDirName() + CoreConstants.FILE_SEPARATOR + volume.getName() + "-logs.tar.gz"; @@ -479,7 +487,7 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount) { - List logMessages = null; + List logMessages = null; ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { 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 2a055ee8..ed1aea75 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 @@ -161,8 +161,8 @@ public class ServerUtil { // } // } - public String getFileFromServer(String serverName, String fileName) { - return executeOnServer(serverName, "get_file " + fileName); + public void getFileFromServer(String serverName, String remoteFileName, String localDirName) { + sshUtil.getFile(serverName, remoteFileName, localDirName); } /** 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 1cc51d23..a4728d21 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 @@ -80,6 +80,17 @@ public class SshUtil { } } + public void getFile(String serverName, String remoteFile, String localDir) { + try { + Connection conn = getConnection(serverName); + SCPClient scpClient = new SCPClient(conn); + scpClient.get(remoteFile, localDir); + } catch (IOException e) { + throw new GlusterRuntimeException("Error while fetching file [" + remoteFile + "] from server [" + + serverName + "]", e); + } + } + public synchronized void installPublicKey(String serverName) { Connection conn = getConnectionWithPassword(serverName); SCPClient scpClient = new SCPClient(conn); -- cgit From b40a5819797217090751f972d7ef3c885465a6ae Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 6 Jun 2011 13:37:16 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- .../storage/management/client/VolumesClient.java | 2 +- .../management/server/resources/VolumesResource.java | 20 ++++++++++++++------ .../storage/management/server/utils/ServerUtil.java | 4 ++-- .../storage/management/server/utils/SshUtil.java | 11 +++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) 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 43435675..424fbca7 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 @@ -144,7 +144,7 @@ public class VolumesClient extends AbstractClient { } public void downloadLogs(String volumeName, String filePath) { - downloadSubResource((volumeName) + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); + downloadSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS + "/" + RESTConstants.RESOURCE_DOWNLOAD, filePath); } public Status removeBricks(String volumeName, List BrickList, boolean deleteOption) { 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 c14290f8..7ef917bd 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 @@ -427,15 +427,24 @@ public class VolumesResource { @GET @Produces(MediaType.APPLICATION_OCTET_STREAM) @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS + "/" + RESOURCE_DOWNLOAD) - public StreamingOutput getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, + public StreamingOutput downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { + final ClusterInfo cluster = clusterService.getCluster(clusterName); + if(cluster == null) { + throw new GlusterRuntimeException("Cluster [" + clusterName + "] doesn't exist!"); + } + + final Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); + if(volume == null) { + throw new GlusterRuntimeException("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + + "]!"); + } + return new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { - Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); try { - // TODO: pass clusterName to downloadLogs File archiveFile = new File(downloadLogs(volume)); output.write(fileUtil.readFileAsByteArray(archiveFile)); archiveFile.delete(); @@ -457,8 +466,7 @@ public class VolumesResource { String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); String logFilePath = logDir + CoreConstants.FILE_SEPARATOR + logFileName; - String logContents = serverUtil.getFileFromServer(brick.getServerName(), logFilePath); - fileUtil.createTextFile(tempDirPath + CoreConstants.FILE_SEPARATOR + logFileName, logContents); + serverUtil.getFileFromServer(brick.getServerName(), logFilePath, tempDirPath); } String gzipPath = fileUtil.getTempDirName() + CoreConstants.FILE_SEPARATOR + volume.getName() + "-logs.tar.gz"; @@ -479,7 +487,7 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount) { - List logMessages = null; + List logMessages = null; ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { 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 2a055ee8..ed1aea75 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 @@ -161,8 +161,8 @@ public class ServerUtil { // } // } - public String getFileFromServer(String serverName, String fileName) { - return executeOnServer(serverName, "get_file " + fileName); + public void getFileFromServer(String serverName, String remoteFileName, String localDirName) { + sshUtil.getFile(serverName, remoteFileName, localDirName); } /** 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 1cc51d23..a4728d21 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 @@ -80,6 +80,17 @@ public class SshUtil { } } + public void getFile(String serverName, String remoteFile, String localDir) { + try { + Connection conn = getConnection(serverName); + SCPClient scpClient = new SCPClient(conn); + scpClient.get(remoteFile, localDir); + } catch (IOException e) { + throw new GlusterRuntimeException("Error while fetching file [" + remoteFile + "] from server [" + + serverName + "]", e); + } + } + public synchronized void installPublicKey(String serverName) { Connection conn = getConnectionWithPassword(serverName); SCPClient scpClient = new SCPClient(conn); -- cgit From 4faf44c75936c7aba6be4f153a253ffeddb20d1d Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Mon, 6 Jun 2011 16:39:59 +0530 Subject: Design changes - introducing cluster-server mapping on gateway --- build/package-server.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/package-server.sh b/build/package-server.sh index ddd6a92f..62aae70d 100755 --- a/build/package-server.sh +++ b/build/package-server.sh @@ -13,8 +13,7 @@ prepare-dist-dir() get-server-war() { cd ${WAR_NAME} - #WAR_FILE=`find -L ${SERVER_DIST_DIR} -name ${WAR_NAME}` - WAR_FILE=`find ${SERVER_DIST_DIR} -name ${WAR_NAME}` + WAR_FILE=`find -L ${SERVER_DIST_DIR} -name ${WAR_NAME}` jar xvf ${WAR_FILE} cd - } -- cgit From 3607009ba67b77a2cdbddeccd48e458d78077bcd Mon Sep 17 00:00:00 2001 From: selvam Date: Tue, 7 Jun 2011 16:55:29 +0530 Subject: Remove server / Add server issue fix Autowired modified to InjectParam in resource side --- .../management/server/resources/GlusterServersResource.java | 2 +- .../storage/management/server/resources/VolumesResource.java | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) 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 7de9015d..b96b1ddb 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 @@ -307,7 +307,7 @@ public class GlusterServersResource extends AbstractServersResource { } try { - return glusterUtil.removeServer(onlineServer.getName(), serverName); + status = glusterUtil.removeServer(onlineServer.getName(), serverName); } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = getNewOnlineServer(clusterName, serverName); 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 7ef917bd..05ea58ce 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 @@ -68,8 +68,6 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.StreamingOutput; -import org.springframework.beans.factory.annotation.Autowired; - import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; @@ -105,20 +103,20 @@ public class VolumesResource { @InjectParam private GlusterServersResource glusterServersResource; - @Autowired + @InjectParam private ServerUtil serverUtil; - @Autowired + @InjectParam private GlusterUtil glusterUtil; - @Autowired + @InjectParam private ClusterService clusterService; - private FileUtil fileUtil = new FileUtil(); - @InjectParam private VolumeOptionsDefaults volumeOptionsDefaults; + private FileUtil fileUtil = new FileUtil(); + @GET @Produces(MediaType.TEXT_XML) public VolumeListResponse getAllVolumes(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { -- cgit From ccea7d5048c969a9c53de060b6e8bc3d883b7e32 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 7 Jun 2011 21:38:15 +0530 Subject: add/remove server --- .../storage/management/core/model/Entity.java | 5 + .../gui/actions/AbstractActionDelegate.java | 10 ++ .../management/gui/actions/AddServerAction.java | 78 +++++++++++-- .../management/gui/actions/RemoveServerAction.java | 123 +++++++++++++++------ .../storage/management/gui/utils/GUIHelper.java | 34 ++++++ .../gui/views/details/GlusterServersPage.java | 17 ++- .../management/gui/views/pages/ServersPage.java | 18 ++- 7 files changed, 233 insertions(+), 52 deletions(-) diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java index e721d052..b905afc3 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java @@ -80,4 +80,9 @@ public class Entity extends PlatformObject implements Filterable { public boolean filter(String filterString, boolean caseSensitive) { return StringUtil.filterString(getName(), filterString, caseSensitive); } + + @Override + public String toString() { + return name; + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java index 1c5a3c72..859d76db 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java @@ -18,6 +18,8 @@ *******************************************************************************/ package com.gluster.storage.management.gui.actions; +import java.util.Set; + import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; @@ -26,8 +28,10 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.internal.UIPlugin; import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.gui.utils.GUIHelper; /** * All action delegates in the application should extend from this class. It provides common functionality of grabbing @@ -36,6 +40,8 @@ import com.gluster.storage.management.core.model.Entity; */ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDelegate { protected IWorkbenchWindow window; + + // the latest selected entity protected Entity selectedEntity; @Override @@ -79,6 +85,10 @@ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDe } return window.getShell(); } + + protected IWorkbenchWindow getWindow() { + return window == null ? UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() : window; + } protected void showInfoDialog(final String title, final String message) { MessageDialog.openInformation(getShell(), title, message); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java index fa48670d..8be1c672 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java @@ -18,33 +18,87 @@ *******************************************************************************/ package com.gluster.storage.management.gui.actions; +import java.util.HashSet; +import java.util.Set; + 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.GlusterServersClient; +import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.response.GlusterServerResponse; +import com.gluster.storage.management.gui.utils.GUIHelper; public class AddServerAction extends AbstractActionDelegate { @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); - GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); - GlusterServersClient glusterServersClient = new GlusterServersClient(); - Server server = (Server) selectedEntity; - GlusterServerResponse response = glusterServersClient.addServer(server); - if (response.getStatus().isSuccess()) { - modelManager.removeDiscoveredServer(server); - modelManager.addGlusterServer(response.getGlusterServer()); - showInfoDialog(actionDesc, "Server [" + server.getName() + "] added successfully!"); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + GlusterServersClient glusterServersClient = new GlusterServersClient(); + + Set selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), Server.class); + Set successServers = new HashSet(); + Set partSuccessServers = new HashSet(); + String errMsg = ""; + String partErrMsg = ""; + for (Server server : selectedServers) { + GlusterServerResponse response = glusterServersClient.addServer(server); + Status status = response.getStatus(); + if (status.isSuccess()) { + modelManager.removeDiscoveredServer(server); + modelManager.addGlusterServer(response.getGlusterServer()); + successServers.add(server); + } else if (status.isPartSuccess()) { + modelManager.removeDiscoveredServer(server); + modelManager.addGlusterServer(response.getGlusterServer()); + partSuccessServers.add(server); + partErrMsg += "[" + server.getName() + "] : " + status; + } else { + errMsg += "[" + server.getName() + "] : " + status; + } + } + + showStatusMessage(action.getDescription(), selectedServers, successServers, errMsg, partErrMsg); + } + }); + } + + private void showStatusMessage(String dialogTitle, Set selectedServers, Set successServers, + String errMsg, String partErrMsg) { + if (successServers.size() == selectedServers.size()) { + if (selectedServers.size() == 1) { + showInfoDialog(dialogTitle, "Server [" + selectedServers.iterator().next() + "] added successfully!"); + } else { + showInfoDialog(dialogTitle, "Following servers added successfully!" + CoreConstants.NEWLINE + + selectedServers); + } + return; + } + + String finalMsg = ""; + if (successServers.size() == 0) { + finalMsg = "Server Addition Failed! Error(s):" + CoreConstants.NEWLINE + errMsg; } else { - showErrorDialog(actionDesc, "Server [" + server.getName() + " could not be added to cluster! Error: [" - + response.getStatus().getMessage() + "]"); + finalMsg = "Following servers added successfully : " + + CoreConstants.NEWLINE + + successServers + + (partErrMsg.isEmpty() ? "" : CoreConstants.NEWLINE + + "Following servers were added to cluster, but with some errors: " + CoreConstants.NEWLINE + + partErrMsg) + + (errMsg.isEmpty() ? "" : CoreConstants.NEWLINE + + "Following errors occurred on other selected servers: " + CoreConstants.NEWLINE + errMsg); } + showErrorDialog(dialogTitle, finalMsg); } @Override diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java index b0b863ab..c7e437e8 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java @@ -19,57 +19,120 @@ package com.gluster.storage.management.gui.actions; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; 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.GlusterServersClient; +import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.Cluster; 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; +import com.gluster.storage.management.gui.utils.GUIHelper; public class RemoveServerAction extends AbstractActionDelegate { - - private GlusterServer server; private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final String actionDesc = action.getDescription(); - List configuredVolumes = getServerVolumeNames(server.getName()); + Set selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), + GlusterServer.class); - if (configuredVolumes.size() > 0) { - String volumes = StringUtil.ListToString(configuredVolumes, ", "); - showErrorDialog(actionDesc, "Server cannot be removed as it is being used by following volumes: [" - + volumes + "]"); - return; - } + if (!validate(action, selectedServers)) { + return; + } - boolean confirmed = showConfirmDialog(actionDesc, - "Are you sure you want to remove this server [" + server.getName() + "] ?"); - if (!confirmed) { + boolean confirmed = showConfirmDialog(actionDesc, "Are you sure you want to remove the server(s) " + + selectedServers + " ?"); + if (!confirmed) { + return; + } + + Set successServers = new HashSet(); + String errMsg = ""; + for (GlusterServer server : selectedServers) { + GlusterServersClient client = new GlusterServersClient(); + Status status = client.removeServer(server.getName()); + if (status.isSuccess()) { + GlusterServer glusterServer = (GlusterServer) server; + modelManager.removeGlusterServer(glusterServer); + successServers.add(server); + } else { + errMsg += "[" + server.getName() + "] : " + status; + } + } + + showStatusMessage(action.getDescription(), selectedServers, successServers, errMsg); + } + }); + } + + private void showStatusMessage(String dialogTitle, Set selectedServers, Set successServers, + String errMsg) { + if (successServers.size() == selectedServers.size()) { + if(selectedServers.size() == 1) { + showInfoDialog(dialogTitle, "Server [" + selectedServers.iterator().next() + "] removed successfully!"); + } else { + showInfoDialog(dialogTitle, "Following servers removed successfully: " + CoreConstants.NEWLINE + + selectedServers); + } return; } + + if (successServers.size() == 0) { + errMsg = "Server Removal Failed! Error(s):" + CoreConstants.NEWLINE + errMsg; + } else { + errMsg = "Following servers removed successfully : " + CoreConstants.NEWLINE + successServers + + CoreConstants.NEWLINE + "Following errors occurred on other selected servers: " + + CoreConstants.NEWLINE + errMsg; + } + showErrorDialog(dialogTitle, errMsg); + } - GlusterServersClient client = new GlusterServersClient(); - Status status = client.removeServer(server.getName()); + private boolean validate(IAction action, Set selectedServers) { + Map> usedServers = new HashMap>(); + for (GlusterServer server : selectedServers) { + List configuredVolumes = getServerVolumeNames(server.getName()); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Server removed successfully"); - GlusterServer glusterServer = (GlusterServer) server; - GlusterDataModelManager.getInstance().removeGlusterServer(glusterServer); - } else { - showErrorDialog(actionDesc, "Server could not be removed. Error: [" + status + "]"); + if (configuredVolumes.size() > 0) { + usedServers.put(server, configuredVolumes); + } } + + if (usedServers.size() > 0) { + if (usedServers.size() == 1) { + showErrorDialog(action.getDescription(), "Server [" + usedServers.keySet().iterator().next() + + "] cannot be removed as it is being used by volume(s): " + CoreConstants.NEWLINE + + usedServers.values().iterator().next() + "]"); + } else { + String serverList = ""; + for (Entry> entry : usedServers.entrySet()) { + serverList += entry.getKey() + " -> " + entry.getValue() + CoreConstants.NEWLINE; + } + showErrorDialog(action.getDescription(), + "Following servers cannot be removed as they are being used by volume(s): " + + CoreConstants.NEWLINE + serverList + "]"); + } + return false; + } + return true; } private List getServerVolumeNames(String serverName) { - Cluster cluster = GlusterDataModelManager.getInstance().getModel().getCluster(); + Cluster cluster = modelManager.getModel().getCluster(); List volumeNames = new ArrayList(); for (Volume volume : cluster.getVolumes()) { for (String brick : volume.getDisks()) { @@ -82,16 +145,6 @@ public class RemoveServerAction extends AbstractActionDelegate { return volumeNames; } - @Override public void dispose() { - System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); - } - - @Override - public void selectionChanged(IAction action, ISelection selection) { - super.selectionChanged(action, selection); - if (selectedEntity instanceof GlusterServer) { - server = (GlusterServer) selectedEntity; - } } } 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 09bd40d6..d08030be 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 @@ -18,7 +18,9 @@ *******************************************************************************/ package com.gluster.storage.management.gui.utils; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; @@ -355,10 +357,12 @@ public class GUIHelper { * Type of the selected object to look for * @return The selected object of given type if found, else null */ + @SuppressWarnings("rawtypes") public Object getSelectedEntity(IWorkbenchSite site, Class expectedType) { return getSelectedEntity(site.getWorkbenchWindow(), expectedType); } + @SuppressWarnings({ "unchecked", "rawtypes" }) public Object getSelectedEntity(IWorkbenchWindow window, Class expectedType) { ISelection selection = window.getSelectionService().getSelection(NavigationView.ID); if (selection instanceof IStructuredSelection) { @@ -372,6 +376,36 @@ public class GUIHelper { } return null; } + + /** + * Fetches the currently selected objects from the workbench site and returns those of given type. If none of the + * selected objects are of given type, returns null + * + * @param site + * The workbench site + * @param expectedType + * Type of the selected objects to look for + * @return The selected objects of given type if found, else null + */ + public Set getSelectedEntities(IWorkbenchSite site, Class expectedType) { + return getSelectedEntities(site.getWorkbenchWindow(), expectedType); + } + + @SuppressWarnings("unchecked") + public Set getSelectedEntities(IWorkbenchWindow window, Class expectedType) { + Set selectedEntities = new HashSet(); + ISelection selection = window.getSelectionService().getSelection(); + if (selection instanceof IStructuredSelection) { + Iterator iter = ((IStructuredSelection) selection).iterator(); + while (iter.hasNext()) { + Object selectedObj = iter.next(); + if (selectedObj.getClass() == expectedType) { + selectedEntities.add((T) selectedObj); + } + } + } + return selectedEntities; + } public void showProgressView() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java index ef104fe2..c9fab9e0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java @@ -19,9 +19,12 @@ package com.gluster.storage.management.gui.views.details; import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -47,7 +50,7 @@ import com.gluster.storage.management.gui.utils.GUIHelper; public class GlusterServersPage extends Composite { private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); - private TableViewer tableViewer; + private CheckboxTableViewer tableViewer; private GUIHelper guiHelper = GUIHelper.getInstance(); public enum GLUSTER_SERVER_TABLE_COLUMN_INDICES { @@ -90,6 +93,14 @@ public class GlusterServersPage extends Composite { parent.layout(); } }); + + tableViewer.addCheckStateListener(new ICheckStateListener() { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + }); } public void addDoubleClickListener(IDoubleClickListener listener) { @@ -122,8 +133,8 @@ public class GlusterServersPage extends Composite { //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90); } - private TableViewer createServerTableViewer(Composite parent) { - TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + private CheckboxTableViewer createServerTableViewer(Composite parent) { + CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); //TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.setLabelProvider(new GlusterServerTableLabelProvider()); tableViewer.setContentProvider(new EntityGroupContentProvider()); 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 6be3e78c..5a6a9d40 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 @@ -18,10 +18,16 @@ *******************************************************************************/ package com.gluster.storage.management.gui.views.pages; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -39,6 +45,7 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.widgets.FormToolkit; +import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.gui.EntityGroupContentProvider; @@ -129,13 +136,20 @@ public class ServersPage extends Composite { } private TableViewer createServerTableViewer(Composite parent) { - TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + final CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.setLabelProvider(new ServerTableLabelProvider()); tableViewer.setContentProvider(new EntityGroupContentProvider()); setupServerTable(parent, tableViewer.getTable()); - + + tableViewer.addCheckStateListener(new ICheckStateListener() { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + }); return tableViewer; } -- cgit From feeb2bf9ce16c9e6ac4268cae4d9c5e94d805fd2 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 7 Jun 2011 21:38:15 +0530 Subject: add/remove server --- .../storage/management/client/UsersClient.java | 19 ++-- .../storage/management/core/model/Entity.java | 5 + .../gui/actions/AbstractActionDelegate.java | 10 ++ .../management/gui/actions/AddServerAction.java | 78 +++++++++++-- .../management/gui/actions/RemoveServerAction.java | 123 +++++++++++++++------ .../management/gui/dialogs/LoginDialog.java | 5 +- .../storage/management/gui/utils/GUIHelper.java | 34 ++++++ .../gui/views/details/GlusterServersPage.java | 17 ++- .../management/gui/views/pages/ServersPage.java | 18 ++- .../server/resources/GlusterServersResource.java | 6 +- 10 files changed, 253 insertions(+), 62 deletions(-) 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 864418a7..25ba6b10 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 @@ -18,6 +18,8 @@ *******************************************************************************/ package com.gluster.storage.management.client; +import java.net.ConnectException; + import javax.ws.rs.core.Response; import com.gluster.storage.management.core.model.Status; @@ -42,22 +44,25 @@ public class UsersClient extends AbstractClient { setSecurityToken(generateSecurityToken(user, password)); try { Status authStatus = (Status) fetchSubResource(user, Status.class); - if(!authStatus.isSuccess()) { + if (!authStatus.isSuccess()) { // authentication failed. clear security token. setSecurityToken(null); } return authStatus; - } catch (Exception e) { - if (e instanceof UniformInterfaceException - && ((UniformInterfaceException) e).getResponse().getStatus() == Response.Status.UNAUTHORIZED - .getStatusCode()) { + } 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 { - return new Status(Status.STATUS_CODE_FAILURE, "Exception during authentication: [" + e.getMessage() - + "]"); + throw e; + } + } catch (Exception e) { + Throwable cause = e.getCause(); + if(cause != null && cause instanceof ConnectException) { + return new Status(Status.STATUS_CODE_FAILURE, "Couldn't connect to Gluster Management Gateway!"); } + return new Status(Status.STATUS_CODE_FAILURE, "Exception during authentication: [" + e.getMessage() + "]"); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java index e721d052..b905afc3 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java @@ -80,4 +80,9 @@ public class Entity extends PlatformObject implements Filterable { public boolean filter(String filterString, boolean caseSensitive) { return StringUtil.filterString(getName(), filterString, caseSensitive); } + + @Override + public String toString() { + return name; + } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java index 1c5a3c72..859d76db 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java @@ -18,6 +18,8 @@ *******************************************************************************/ package com.gluster.storage.management.gui.actions; +import java.util.Set; + import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; @@ -26,8 +28,10 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.internal.UIPlugin; import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.gui.utils.GUIHelper; /** * All action delegates in the application should extend from this class. It provides common functionality of grabbing @@ -36,6 +40,8 @@ import com.gluster.storage.management.core.model.Entity; */ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDelegate { protected IWorkbenchWindow window; + + // the latest selected entity protected Entity selectedEntity; @Override @@ -79,6 +85,10 @@ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDe } return window.getShell(); } + + protected IWorkbenchWindow getWindow() { + return window == null ? UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() : window; + } protected void showInfoDialog(final String title, final String message) { MessageDialog.openInformation(getShell(), title, message); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java index fa48670d..8be1c672 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java @@ -18,33 +18,87 @@ *******************************************************************************/ package com.gluster.storage.management.gui.actions; +import java.util.HashSet; +import java.util.Set; + 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.GlusterServersClient; +import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.response.GlusterServerResponse; +import com.gluster.storage.management.gui.utils.GUIHelper; public class AddServerAction extends AbstractActionDelegate { @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); - GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); - GlusterServersClient glusterServersClient = new GlusterServersClient(); - Server server = (Server) selectedEntity; - GlusterServerResponse response = glusterServersClient.addServer(server); - if (response.getStatus().isSuccess()) { - modelManager.removeDiscoveredServer(server); - modelManager.addGlusterServer(response.getGlusterServer()); - showInfoDialog(actionDesc, "Server [" + server.getName() + "] added successfully!"); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + GlusterServersClient glusterServersClient = new GlusterServersClient(); + + Set selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), Server.class); + Set successServers = new HashSet(); + Set partSuccessServers = new HashSet(); + String errMsg = ""; + String partErrMsg = ""; + for (Server server : selectedServers) { + GlusterServerResponse response = glusterServersClient.addServer(server); + Status status = response.getStatus(); + if (status.isSuccess()) { + modelManager.removeDiscoveredServer(server); + modelManager.addGlusterServer(response.getGlusterServer()); + successServers.add(server); + } else if (status.isPartSuccess()) { + modelManager.removeDiscoveredServer(server); + modelManager.addGlusterServer(response.getGlusterServer()); + partSuccessServers.add(server); + partErrMsg += "[" + server.getName() + "] : " + status; + } else { + errMsg += "[" + server.getName() + "] : " + status; + } + } + + showStatusMessage(action.getDescription(), selectedServers, successServers, errMsg, partErrMsg); + } + }); + } + + private void showStatusMessage(String dialogTitle, Set selectedServers, Set successServers, + String errMsg, String partErrMsg) { + if (successServers.size() == selectedServers.size()) { + if (selectedServers.size() == 1) { + showInfoDialog(dialogTitle, "Server [" + selectedServers.iterator().next() + "] added successfully!"); + } else { + showInfoDialog(dialogTitle, "Following servers added successfully!" + CoreConstants.NEWLINE + + selectedServers); + } + return; + } + + String finalMsg = ""; + if (successServers.size() == 0) { + finalMsg = "Server Addition Failed! Error(s):" + CoreConstants.NEWLINE + errMsg; } else { - showErrorDialog(actionDesc, "Server [" + server.getName() + " could not be added to cluster! Error: [" - + response.getStatus().getMessage() + "]"); + finalMsg = "Following servers added successfully : " + + CoreConstants.NEWLINE + + successServers + + (partErrMsg.isEmpty() ? "" : CoreConstants.NEWLINE + + "Following servers were added to cluster, but with some errors: " + CoreConstants.NEWLINE + + partErrMsg) + + (errMsg.isEmpty() ? "" : CoreConstants.NEWLINE + + "Following errors occurred on other selected servers: " + CoreConstants.NEWLINE + errMsg); } + showErrorDialog(dialogTitle, finalMsg); } @Override diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java index b0b863ab..c7e437e8 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java @@ -19,57 +19,120 @@ package com.gluster.storage.management.gui.actions; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; 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.GlusterServersClient; +import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.model.Cluster; 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; +import com.gluster.storage.management.gui.utils.GUIHelper; public class RemoveServerAction extends AbstractActionDelegate { - - private GlusterServer server; private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + final String actionDesc = action.getDescription(); - List configuredVolumes = getServerVolumeNames(server.getName()); + Set selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), + GlusterServer.class); - if (configuredVolumes.size() > 0) { - String volumes = StringUtil.ListToString(configuredVolumes, ", "); - showErrorDialog(actionDesc, "Server cannot be removed as it is being used by following volumes: [" - + volumes + "]"); - return; - } + if (!validate(action, selectedServers)) { + return; + } - boolean confirmed = showConfirmDialog(actionDesc, - "Are you sure you want to remove this server [" + server.getName() + "] ?"); - if (!confirmed) { + boolean confirmed = showConfirmDialog(actionDesc, "Are you sure you want to remove the server(s) " + + selectedServers + " ?"); + if (!confirmed) { + return; + } + + Set successServers = new HashSet(); + String errMsg = ""; + for (GlusterServer server : selectedServers) { + GlusterServersClient client = new GlusterServersClient(); + Status status = client.removeServer(server.getName()); + if (status.isSuccess()) { + GlusterServer glusterServer = (GlusterServer) server; + modelManager.removeGlusterServer(glusterServer); + successServers.add(server); + } else { + errMsg += "[" + server.getName() + "] : " + status; + } + } + + showStatusMessage(action.getDescription(), selectedServers, successServers, errMsg); + } + }); + } + + private void showStatusMessage(String dialogTitle, Set selectedServers, Set successServers, + String errMsg) { + if (successServers.size() == selectedServers.size()) { + if(selectedServers.size() == 1) { + showInfoDialog(dialogTitle, "Server [" + selectedServers.iterator().next() + "] removed successfully!"); + } else { + showInfoDialog(dialogTitle, "Following servers removed successfully: " + CoreConstants.NEWLINE + + selectedServers); + } return; } + + if (successServers.size() == 0) { + errMsg = "Server Removal Failed! Error(s):" + CoreConstants.NEWLINE + errMsg; + } else { + errMsg = "Following servers removed successfully : " + CoreConstants.NEWLINE + successServers + + CoreConstants.NEWLINE + "Following errors occurred on other selected servers: " + + CoreConstants.NEWLINE + errMsg; + } + showErrorDialog(dialogTitle, errMsg); + } - GlusterServersClient client = new GlusterServersClient(); - Status status = client.removeServer(server.getName()); + private boolean validate(IAction action, Set selectedServers) { + Map> usedServers = new HashMap>(); + for (GlusterServer server : selectedServers) { + List configuredVolumes = getServerVolumeNames(server.getName()); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Server removed successfully"); - GlusterServer glusterServer = (GlusterServer) server; - GlusterDataModelManager.getInstance().removeGlusterServer(glusterServer); - } else { - showErrorDialog(actionDesc, "Server could not be removed. Error: [" + status + "]"); + if (configuredVolumes.size() > 0) { + usedServers.put(server, configuredVolumes); + } } + + if (usedServers.size() > 0) { + if (usedServers.size() == 1) { + showErrorDialog(action.getDescription(), "Server [" + usedServers.keySet().iterator().next() + + "] cannot be removed as it is being used by volume(s): " + CoreConstants.NEWLINE + + usedServers.values().iterator().next() + "]"); + } else { + String serverList = ""; + for (Entry> entry : usedServers.entrySet()) { + serverList += entry.getKey() + " -> " + entry.getValue() + CoreConstants.NEWLINE; + } + showErrorDialog(action.getDescription(), + "Following servers cannot be removed as they are being used by volume(s): " + + CoreConstants.NEWLINE + serverList + "]"); + } + return false; + } + return true; } private List getServerVolumeNames(String serverName) { - Cluster cluster = GlusterDataModelManager.getInstance().getModel().getCluster(); + Cluster cluster = modelManager.getModel().getCluster(); List volumeNames = new ArrayList(); for (Volume volume : cluster.getVolumes()) { for (String brick : volume.getDisks()) { @@ -82,16 +145,6 @@ public class RemoveServerAction extends AbstractActionDelegate { return volumeNames; } - @Override public void dispose() { - System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); - } - - @Override - public void selectionChanged(IAction action, ISelection selection) { - super.selectionChanged(action, selection); - if (selectedEntity instanceof GlusterServer) { - server = (GlusterServer) selectedEntity; - } } } 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 d480e503..9db0f0e8 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 @@ -200,7 +200,8 @@ public class LoginDialog extends Dialog { String password = connectionDetails.getPassword(); UsersClient usersClient = new UsersClient(); - if (usersClient.authenticate(user, password).isSuccess()) { + Status loginStatus = usersClient.authenticate(user, password); + if (loginStatus.isSuccess()) { close(); ClustersClient clustersClient = new ClustersClient(usersClient.getSecurityToken()); List clusterNames = getClusterNames(clustersClient); @@ -250,7 +251,7 @@ public class LoginDialog extends Dialog { close(); } } else { - MessageDialog.openError(getShell(), "Authentication Failed", "Invalid User ID or password"); + MessageDialog.openError(getShell(), "Authentication Failed", loginStatus.getMessage()); } } 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 09bd40d6..d08030be 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 @@ -18,7 +18,9 @@ *******************************************************************************/ package com.gluster.storage.management.gui.utils; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; @@ -355,10 +357,12 @@ public class GUIHelper { * Type of the selected object to look for * @return The selected object of given type if found, else null */ + @SuppressWarnings("rawtypes") public Object getSelectedEntity(IWorkbenchSite site, Class expectedType) { return getSelectedEntity(site.getWorkbenchWindow(), expectedType); } + @SuppressWarnings({ "unchecked", "rawtypes" }) public Object getSelectedEntity(IWorkbenchWindow window, Class expectedType) { ISelection selection = window.getSelectionService().getSelection(NavigationView.ID); if (selection instanceof IStructuredSelection) { @@ -372,6 +376,36 @@ public class GUIHelper { } return null; } + + /** + * Fetches the currently selected objects from the workbench site and returns those of given type. If none of the + * selected objects are of given type, returns null + * + * @param site + * The workbench site + * @param expectedType + * Type of the selected objects to look for + * @return The selected objects of given type if found, else null + */ + public Set getSelectedEntities(IWorkbenchSite site, Class expectedType) { + return getSelectedEntities(site.getWorkbenchWindow(), expectedType); + } + + @SuppressWarnings("unchecked") + public Set getSelectedEntities(IWorkbenchWindow window, Class expectedType) { + Set selectedEntities = new HashSet(); + ISelection selection = window.getSelectionService().getSelection(); + if (selection instanceof IStructuredSelection) { + Iterator iter = ((IStructuredSelection) selection).iterator(); + while (iter.hasNext()) { + Object selectedObj = iter.next(); + if (selectedObj.getClass() == expectedType) { + selectedEntities.add((T) selectedObj); + } + } + } + return selectedEntities; + } public void showProgressView() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java index ef104fe2..c9fab9e0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java @@ -19,9 +19,12 @@ package com.gluster.storage.management.gui.views.details; import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -47,7 +50,7 @@ import com.gluster.storage.management.gui.utils.GUIHelper; public class GlusterServersPage extends Composite { private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); - private TableViewer tableViewer; + private CheckboxTableViewer tableViewer; private GUIHelper guiHelper = GUIHelper.getInstance(); public enum GLUSTER_SERVER_TABLE_COLUMN_INDICES { @@ -90,6 +93,14 @@ public class GlusterServersPage extends Composite { parent.layout(); } }); + + tableViewer.addCheckStateListener(new ICheckStateListener() { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + }); } public void addDoubleClickListener(IDoubleClickListener listener) { @@ -122,8 +133,8 @@ public class GlusterServersPage extends Composite { //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90); } - private TableViewer createServerTableViewer(Composite parent) { - TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + private CheckboxTableViewer createServerTableViewer(Composite parent) { + CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); //TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.setLabelProvider(new GlusterServerTableLabelProvider()); tableViewer.setContentProvider(new EntityGroupContentProvider()); 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 6be3e78c..5a6a9d40 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 @@ -18,10 +18,16 @@ *******************************************************************************/ package com.gluster.storage.management.gui.views.pages; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -39,6 +45,7 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.widgets.FormToolkit; +import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.gui.EntityGroupContentProvider; @@ -129,13 +136,20 @@ public class ServersPage extends Composite { } private TableViewer createServerTableViewer(Composite parent) { - TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + final CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.setLabelProvider(new ServerTableLabelProvider()); tableViewer.setContentProvider(new EntityGroupContentProvider()); setupServerTable(parent, tableViewer.getTable()); - + + tableViewer.addCheckStateListener(new ICheckStateListener() { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + }); return tableViewer; } 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 b96b1ddb..728da2dc 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 @@ -206,7 +206,11 @@ public class GlusterServersResource extends AbstractServersResource { Status status; try { - status = glusterUtil.addServer(serverName, onlineServer.getName()); + status = glusterUtil.addServer(onlineServer.getName(), serverName); + if(status.isSuccess()) { + // other peer probe to ensure that host names appear in peer probe on both sides + status = glusterUtil.addServer(serverName, onlineServer.getName()); + } } catch(ConnectionException e) { onlineServer = getNewOnlineServer(clusterName); if(onlineServer == null) { -- cgit From b7116e8ac18641215337d5691cb50b6706f0e91f Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 8 Jun 2011 11:59:15 +0530 Subject: Bug 2881 - "Add" button should get disabled once all the Volume options are selected --- .../gui/views/details/VolumeOptionsPage.java | 148 ++++++++++++++------- 1 file changed, 103 insertions(+), 45 deletions(-) diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java index 3e8e8baa..cc37270b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java @@ -18,6 +18,7 @@ *******************************************************************************/ package com.gluster.storage.management.gui.views.details; +import java.util.List; import java.util.Map.Entry; import org.apache.commons.lang.WordUtils; @@ -68,19 +69,22 @@ public class VolumeOptionsPage extends Composite { private Volume volume; private DefaultClusterListener clusterListener; private Text filterText; + private List defaultVolumeOptions = GlusterDataModelManager.getInstance() + .getVolumeOptionsDefaults(); public enum OPTIONS_TABLE_COLUMN_INDICES { OPTION_KEY, OPTION_VALUE }; private static final String[] OPTIONS_TABLE_COLUMN_NAMES = new String[] { "Option Key", "Option Value" }; - private Button addButton; + private Button addTopButton; + private Button addBottomButton; private TableViewerColumn keyColumn; private OptionKeyEditingSupport keyEditingSupport; public VolumeOptionsPage(final Composite parent, int style, Volume volume) { super(parent, style); - + this.volume = volume; toolkit.adapt(this); @@ -88,52 +92,102 @@ public class VolumeOptionsPage extends Composite { setupPageLayout(); filterText = guiHelper.createFilterText(toolkit, this); - createAddButton(); - setupOptionsTableViewer(filterText); - createAddButton(); + createAddButtonOnTop(); + setupOptionsTableViewer(filterText); + + createAddButtonOnBottom(); + + if (defaultVolumeOptions.size() == volume.getOptions().size()) { + enableOrDisableButtons(false); + } tableViewer.setInput(volume.getOptions().entrySet()); - + parent.layout(); // Important - this actually paints the table registerListeners(parent); } - private void createAddButton() { - addButton = toolkit.createButton(this, "&Add", SWT.FLAT); - addButton.addSelectionListener(new SelectionAdapter() { + private void createAddButtonOnTop() { + addTopButton = toolkit.createButton(this, "&Add", SWT.FLAT); + addTopButton.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 - + keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry + // disable the add button AND search filter textbox till user fills up the new option - addButton.setEnabled(false); + enableOrDisableButtons(false); filterText.setEnabled(false); } private Entry getEntry(String key) { - for(Entry entry : volume.getOptions().entrySet()) { - if(entry.getKey().equals(key)) { + for (Entry entry : volume.getOptions().entrySet()) { + if (entry.getKey().equals(key)) { return entry; } } return null; } }); - + + // Make sure that add button is enabled only when search filter textbox is empty + filterText.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (filterText.getText().length() > 0) { + enableOrDisableButtons(false); + } else { + enableOrDisableButtons(true); + } + } + }); + } + + private void enableOrDisableButtons(boolean flag) { + addTopButton.setEnabled(flag); + addBottomButton.setEnabled(flag); + } + + private void createAddButtonOnBottom() { + addBottomButton = toolkit.createButton(this, "&Add", SWT.FLAT); + addBottomButton.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 + enableOrDisableButtons(false); + filterText.setEnabled(false); + } + + private Entry getEntry(String key) { + for (Entry entry : volume.getOptions().entrySet()) { + if (entry.getKey().equals(key)) { + return entry; + } + } + return null; + } + }); + // Make sure that add button is enabled only when search filter textbox is empty filterText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { - if(filterText.getText().length() > 0) { - addButton.setEnabled(false); + if (filterText.getText().length() > 0) { + enableOrDisableButtons(false); } else { - addButton.setEnabled(true); + enableOrDisableButtons(true); } } }); @@ -142,7 +196,7 @@ public class VolumeOptionsPage extends Composite { private void registerListeners(final Composite parent) { addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { - if(!addButton.isEnabled()) { + if (!(addTopButton.isEnabled() || addBottomButton.isEnabled())) { // user has selected key, but not added value. Since this is not a valid entry, // remove the last option (without value) from the volume volume.getOptions().remove(keyEditingSupport.getEntryBeingAdded().getKey()); @@ -164,12 +218,12 @@ public class VolumeOptionsPage extends Composite { parent.layout(); } }); - + parent.addDisposeListener(new DisposeListener() { - + @Override public void widgetDisposed(DisposeEvent e) { - if(!addButton.isEnabled()) { + if (!(addTopButton.isEnabled() || addBottomButton.isEnabled())) { // user has selected key, but not added value. Since this is not a valid entry, // remove the last option (without value) from the volume Entry entryBeingAdded = keyEditingSupport.getEntryBeingAdded(); @@ -178,27 +232,31 @@ public class VolumeOptionsPage extends Composite { } }); - clusterListener = new DefaultClusterListener() { @SuppressWarnings("unchecked") @Override public void volumeChanged(Volume volume, Event event) { super.volumeChanged(volume, event); - if(event.getEventType() == EVENT_TYPE.VOLUME_OPTIONS_RESET) { - if(!tableViewer.getControl().isDisposed()) { + if (event.getEventType() == EVENT_TYPE.VOLUME_OPTIONS_RESET) { + if (!tableViewer.getControl().isDisposed()) { tableViewer.refresh(); } } - - if(event.getEventType() == EVENT_TYPE.VOLUME_OPTION_SET) { - Entry eventEntry = (Entry)event.getEventData(); + + if (event.getEventType() == EVENT_TYPE.VOLUME_OPTION_SET) { + Entry eventEntry = (Entry) event.getEventData(); if (isNewOption(volume, eventEntry.getKey())) { - // option has been set successfully by the user. re-enable the add button and search filter textbox - addButton.setEnabled(true); + // option has been set successfully by the user. re-enable the add button and search filter + // textbox + enableOrDisableButtons(true); filterText.setEnabled(true); } - if(tableViewer.getTable().getItemCount() < volume.getOptions().size()) { + if (defaultVolumeOptions.size() == volume.getOptions().size()) { + enableOrDisableButtons(false); + } + + if (tableViewer.getTable().getItemCount() < volume.getOptions().size()) { // new volume set from outside this page. refresh the viewer. tableViewer.refresh(); } else { @@ -209,14 +267,14 @@ public class VolumeOptionsPage extends Composite { } private boolean isNewOption(Volume volume, String optionKey) { - if(filterText.getText().length() > 0) { + if (filterText.getText().length() > 0) { // user has been filtering the contents. adding new option is allowed only when contents are NOT // filtered. Thus it's impossible that this is a newly added option return false; } - + // if this is the last option in the volume options, it must be the new option - return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size()-1]); + return optionKey.equals(volume.getOptions().keySet().toArray()[volume.getOptions().size() - 1]); } }; GlusterDataModelManager.getInstance().addClusterListener(clusterListener); @@ -240,7 +298,7 @@ public class VolumeOptionsPage extends Composite { setColumnProperties(table, OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY, SWT.CENTER, 100); setColumnProperties(table, OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE, SWT.CENTER, 100); } - + private TableColumnLayout createTableColumnLayout() { TableColumnLayout tableColumnLayout = new TableColumnLayout(); ColumnLayoutData defaultColumnLayoutData = new ColumnWeightData(100); @@ -250,7 +308,7 @@ public class VolumeOptionsPage extends Composite { return tableColumnLayout; } - + private TableColumn createValueColumn() { TableViewerColumn valueColumn = new TableViewerColumn(tableViewer, SWT.NONE); valueColumn.getColumn() @@ -262,10 +320,10 @@ public class VolumeOptionsPage extends Composite { return ((Entry) element).getValue(); } }); - + // User can edit value of a volume option valueColumn.setEditingSupport(new OptionValueEditingSupport(valueColumn.getViewer(), volume)); - + return valueColumn.getColumn(); } @@ -278,26 +336,26 @@ public class VolumeOptionsPage extends Composite { public String getText(Object element) { return ((Entry) element).getKey(); } - + @SuppressWarnings("unchecked") @Override public String getToolTipText(Object element) { String key = ((Entry) element).getKey(); - if(key.isEmpty()) { + if (key.isEmpty()) { return "Click to select a volume option key"; } - + VolumeOptionInfo optionInfo = GlusterDataModelManager.getInstance().getVolumeOptionInfo(key); - // Wrap the description before adding to tooltip so that long descriptions are displayed properly + // Wrap the description before adding to tooltip so that long descriptions are displayed properly return WordUtils.wrap(optionInfo.getDescription(), 60) + CoreConstants.NEWLINE + "Default value: " + optionInfo.getDefaultValue(); } }); - + // Editing support required when adding new key keyEditingSupport = new OptionKeyEditingSupport(keyColumn.getViewer(), volume); keyColumn.setEditingSupport(keyEditingSupport); - + return keyColumn.getColumn(); } -- cgit From 6fa7628e95c0aa634a56c543dcd6b18798918b58 Mon Sep 17 00:00:00 2001 From: selvam Date: Wed, 8 Jun 2011 14:15:40 +0530 Subject: Bug #2877 Using short cut key for resetting volume options selects irrelevant volume - fix --- .../gui/actions/ResetVolumeOptionsAction.java | 48 +++++++++++++--------- .../storage/management/gui/utils/GUIHelper.java | 4 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java index 5182d25f..1ef35352 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java @@ -2,6 +2,7 @@ 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 org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; @@ -10,6 +11,7 @@ import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.utils.GUIHelper; public class ResetVolumeOptionsAction extends AbstractActionDelegate { private Volume volume; @@ -22,23 +24,29 @@ public class ResetVolumeOptionsAction extends AbstractActionDelegate { } @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { - boolean confirmed = showConfirmDialog(actionDesc, - "Are you sure you want to reset all options of the volume [" + volume.getName() + "] ?"); - if (!confirmed) { - return; - } + @Override + public void run() { + final String actionDesc = action.getDescription(); - final Status status = resetVolumeOptions(); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Volume options for [" + volume.getName() + "] reset successfully!"); - modelManager.resetVolumeOptions(volume); - } else { - showErrorDialog(actionDesc, "Volume options for [" + volume.getName() + "] could not be reset! Error: [" + status - + "]"); - } + boolean confirmed = showConfirmDialog(actionDesc, + "Are you sure you want to reset all options of the volume [" + volume.getName() + "] ?"); + if (!confirmed) { + return; + } + + final Status status = resetVolumeOptions(); + if (status.isSuccess()) { + showInfoDialog(actionDesc, "Volume options for [" + volume.getName() + "] reset successfully!"); + modelManager.resetVolumeOptions(volume); + } else { + showErrorDialog(actionDesc, "Volume options for [" + volume.getName() + + "] could not be reset! Error: [" + status + "]"); + } + } + }); } private Status resetVolumeOptions() { @@ -54,11 +62,13 @@ public class ResetVolumeOptionsAction extends AbstractActionDelegate { */ @Override public void selectionChanged(IAction action, ISelection selection) { - super.selectionChanged(action, selection); - - if (selectedEntity instanceof Volume) { - volume = (Volume) selectedEntity; + volume = GUIHelper.getInstance().getSelectedEntity(getWindow(), Volume.class); + + if (volume instanceof Volume) { + //showInfoDialog("Debug", volume.getName()); action.setEnabled(volume.getOptions().size() > 0); + } else { + action.setEnabled(false); } } } 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 d08030be..56a6c94b 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 @@ -363,14 +363,14 @@ public class GUIHelper { } @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object getSelectedEntity(IWorkbenchWindow window, Class expectedType) { + public T getSelectedEntity(IWorkbenchWindow window, Class expectedType) { ISelection selection = window.getSelectionService().getSelection(NavigationView.ID); if (selection instanceof IStructuredSelection) { Iterator iter = ((IStructuredSelection) selection).iterator(); while (iter.hasNext()) { Object selectedObj = iter.next(); if (selectedObj.getClass() == expectedType) { - return selectedObj; + return (T)selectedObj; } } } -- cgit From 86a37b3225bff6da8ddfeaf62278503f7e8124ae Mon Sep 17 00:00:00 2001 From: selvam Date: Wed, 8 Jun 2011 14:15:40 +0530 Subject: Bug #2877 Using short cut key for resetting volume options selects irrelevant volume - fix --- .../gui/actions/ResetVolumeOptionsAction.java | 47 +++++++++++++--------- .../storage/management/gui/utils/GUIHelper.java | 4 +- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java index 5182d25f..f23f3b15 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java @@ -2,6 +2,7 @@ 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 org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; @@ -10,6 +11,7 @@ import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.utils.GUIHelper; public class ResetVolumeOptionsAction extends AbstractActionDelegate { private Volume volume; @@ -22,23 +24,29 @@ public class ResetVolumeOptionsAction extends AbstractActionDelegate { } @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { - boolean confirmed = showConfirmDialog(actionDesc, - "Are you sure you want to reset all options of the volume [" + volume.getName() + "] ?"); - if (!confirmed) { - return; - } + @Override + public void run() { + final String actionDesc = action.getDescription(); - final Status status = resetVolumeOptions(); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Volume options for [" + volume.getName() + "] reset successfully!"); - modelManager.resetVolumeOptions(volume); - } else { - showErrorDialog(actionDesc, "Volume options for [" + volume.getName() + "] could not be reset! Error: [" + status - + "]"); - } + boolean confirmed = showConfirmDialog(actionDesc, + "Are you sure you want to reset all options of the volume [" + volume.getName() + "] ?"); + if (!confirmed) { + return; + } + + final Status status = resetVolumeOptions(); + if (status.isSuccess()) { + showInfoDialog(actionDesc, "Volume options for [" + volume.getName() + "] reset successfully!"); + modelManager.resetVolumeOptions(volume); + } else { + showErrorDialog(actionDesc, "Volume options for [" + volume.getName() + + "] could not be reset! Error: [" + status + "]"); + } + } + }); } private Status resetVolumeOptions() { @@ -54,11 +62,12 @@ public class ResetVolumeOptionsAction extends AbstractActionDelegate { */ @Override public void selectionChanged(IAction action, ISelection selection) { - super.selectionChanged(action, selection); - - if (selectedEntity instanceof Volume) { - volume = (Volume) selectedEntity; + volume = GUIHelper.getInstance().getSelectedEntity(getWindow(), Volume.class); + + if (volume instanceof Volume) { action.setEnabled(volume.getOptions().size() > 0); + } else { + action.setEnabled(false); } } } 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 d08030be..56a6c94b 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 @@ -363,14 +363,14 @@ public class GUIHelper { } @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object getSelectedEntity(IWorkbenchWindow window, Class expectedType) { + public T getSelectedEntity(IWorkbenchWindow window, Class expectedType) { ISelection selection = window.getSelectionService().getSelection(NavigationView.ID); if (selection instanceof IStructuredSelection) { Iterator iter = ((IStructuredSelection) selection).iterator(); while (iter.hasNext()) { Object selectedObj = iter.next(); if (selectedObj.getClass() == expectedType) { - return selectedObj; + return (T)selectedObj; } } } -- cgit From 7c69863cac6e72e29265d3bca8429a5f6af1d120 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 8 Jun 2011 15:02:39 +0530 Subject: Bug 2838 - Stop Volume popup by default focused on "Yes" button --- .../management/gui/actions/DeleteVolumeAction.java | 91 ++++++++++++---------- .../management/gui/actions/RemoveDiskAction.java | 70 ++++++++++------- .../management/gui/actions/StopVolumeAction.java | 50 +++++++----- 3 files changed, 121 insertions(+), 90 deletions(-) diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java index 41ebbca7..9222c6c7 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java @@ -21,6 +21,7 @@ package com.gluster.storage.management.gui.actions; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; 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.VolumesClient; @@ -35,53 +36,61 @@ public class DeleteVolumeAction extends AbstractActionDelegate { private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); + protected void performAction(final IAction action) { - String warningMessage; - if (volume.getStatus() == VOLUME_STATUS.OFFLINE) { - warningMessage = "Are you sure to delete the Volume[" + volume.getName() + "] ?"; - } else { - warningMessage = "Volume [" + volume.getName() + "] is online, \nAre you sure to continue?"; - } + Display.getDefault().asyncExec(new Runnable() { - Integer deleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance().getImage( - IImageKeys.VOLUME), warningMessage, MessageDialog.QUESTION, new String[] { "Cancel", - "Delete volume and data", "Delete volume, keep data" }, 2).open(); - if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) - return; - } + @Override + public void run() { - VolumesClient client = new VolumesClient(); + final String actionDesc = action.getDescription(); - Status status; - if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // To stop the volume service, if running - status = client.stopVolume(volume.getName()); - if (!status.isSuccess()) { - showErrorDialog(actionDesc, "Volume [" + volume.getName() + "] could not be stopped! Error: [" + status - + "]"); - return; - } - } - - boolean confirmDelete = false; - if (deleteOption == 1) { - confirmDelete = true; - } + String warningMessage; + if (volume.getStatus() == VOLUME_STATUS.OFFLINE) { + warningMessage = "Are you sure to delete the Volume[" + volume.getName() + "] ?"; + } else { + warningMessage = "Volume [" + volume.getName() + "] is online, \nAre you sure to continue?"; + } - status = client.deleteVolume(volume, confirmDelete); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] deleted successfully!"); - modelManager.deleteVolume(volume); - } else { - if (status.isPartSuccess()) { - showWarningDialog(actionDesc, "Volume deleted, but following error(s) occured: " + status); - modelManager.deleteVolume(volume); - } else { - showErrorDialog(actionDesc, - "Volume [" + volume.getName() + "] could not be deleted! Error: [" + status + "]"); + Integer deleteOption = new MessageDialog(getShell(), "Delete Volume", GUIHelper.getInstance().getImage( + IImageKeys.VOLUME), warningMessage, MessageDialog.QUESTION, new String[] { "Cancel", + "Delete volume and data", "Delete volume, keep data" }, -1).open(); + if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) + return; + } + + VolumesClient client = new VolumesClient(); + + Status status; + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { // To stop the volume service, if running + status = client.stopVolume(volume.getName()); + if (!status.isSuccess()) { + showErrorDialog(actionDesc, "Volume [" + volume.getName() + "] could not be stopped! Error: [" + + status + "]"); + return; + } + } + + boolean confirmDelete = false; + if (deleteOption == 1) { + confirmDelete = true; + } + + status = client.deleteVolume(volume, confirmDelete); + if (status.isSuccess()) { + showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] deleted successfully!"); + modelManager.deleteVolume(volume); + } else { + if (status.isPartSuccess()) { + showWarningDialog(actionDesc, "Volume deleted, but following error(s) occured: " + status); + modelManager.deleteVolume(volume); + } else { + showErrorDialog(actionDesc, "Volume [" + volume.getName() + "] could not be deleted! Error: [" + + status + "]"); + } + } } - } + }); } @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 8c5d8405..ffe2469d 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 @@ -30,39 +30,49 @@ public class RemoveDiskAction extends AbstractActionDelegate { boolean confirmDelete = false; @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); - List brickList = getBrickList(bricks); - Integer deleteOption = new MessageDialog(getShell(), "Remove Bricks(s)", GUIHelper.getInstance().getImage( - IImageKeys.VOLUME), "Are you sure you want to remove following bricks from volume [" + volume.getName() - + "] ? \n" + StringUtil.ListToString(brickList, ", "), MessageDialog.QUESTION, new String[] { "Cancel", - "Remove bricks, delete data", "Remove bricks, keep data" }, 2).open(); - if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) - return; - } + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { - if (deleteOption == 1) { - confirmDelete = true; - } - BusyIndicator.showWhile(Display.getDefault(), new Runnable() { + @Override public void run() { - VolumesClient client = new VolumesClient(); - Status status = client.removeBricks(volume.getName(), bricks, confirmDelete); - - if (status.isSuccess()) { - - // Remove the bricks from the volume object - for (Brick brick : bricks) { - volume.removeBrick(brick); - } - // Update model with removed bricks in the volume - modelManager.removeBricks(volume, bricks); - - showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] bricks(s) removed successfully!"); - } else { - showErrorDialog(actionDesc, "Volume [" + volume.getName() - + "] bricks(s) could not be removed! Error: [" + status + "]"); + + final String actionDesc = action.getDescription(); + List brickList = getBrickList(bricks); + Integer deleteOption = new MessageDialog(getShell(), "Remove Bricks(s)", GUIHelper.getInstance() + .getImage(IImageKeys.VOLUME), "Are you sure you want to remove following bricks from volume [" + + volume.getName() + "] ? \n" + StringUtil.ListToString(brickList, ", "), + MessageDialog.QUESTION, new String[] { "Cancel", "Remove bricks, delete data", + "Remove bricks, keep data" }, -1).open(); + if (deleteOption <= 0) { // By Cancel button(0) or Escape key(-1) + return; + } + + if (deleteOption == 1) { + confirmDelete = true; } + BusyIndicator.showWhile(Display.getDefault(), new Runnable() { + public void run() { + VolumesClient client = new VolumesClient(); + Status status = client.removeBricks(volume.getName(), bricks, confirmDelete); + + if (status.isSuccess()) { + + // Remove the bricks from the volume object + for (Brick brick : bricks) { + volume.removeBrick(brick); + } + // Update model with removed bricks in the volume + modelManager.removeBricks(volume, bricks); + + showInfoDialog(actionDesc, "Volume [" + volume.getName() + + "] bricks(s) removed successfully!"); + } else { + showErrorDialog(actionDesc, "Volume [" + volume.getName() + + "] bricks(s) could not be removed! Error: [" + status + "]"); + } + } + }); + } }); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java index 33d12ce3..68623aaf 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java @@ -19,40 +19,52 @@ package com.gluster.storage.management.gui.actions; import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; 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.VolumesClient; import com.gluster.storage.management.core.model.Status; 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; +import com.gluster.storage.management.gui.utils.GUIHelper; public class StopVolumeAction extends AbstractActionDelegate { private Volume volume; private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); @Override - protected void performAction(IAction action) { - final String actionDesc = action.getDescription(); - if (volume.getStatus() == VOLUME_STATUS.OFFLINE) { - showWarningDialog(actionDesc, "Volume [" + volume.getName() + "] is already offline!"); - return; // Volume already offline. Don't do anything. - } + protected void performAction(final IAction action) { + Display.getDefault().asyncExec(new Runnable() { - boolean confirmed = showConfirmDialog(actionDesc, - "Are you sure you want to stop the volume [" + volume.getName() + "] ?"); - if (!confirmed) { - return; - } + @Override + public void run() { + final String actionDesc = action.getDescription(); + if (volume.getStatus() == VOLUME_STATUS.OFFLINE) { + showWarningDialog(actionDesc, "Volume [" + volume.getName() + "] is already offline!"); + return; // Volume already offline. Don't do anything. + } - final Status status = stopVolume(); - if (status.isSuccess()) { - showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] stopped successfully!"); - modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); - } else { - showErrorDialog(actionDesc, "Volume [" + volume.getName() + "] could not be stopped! Error: [" + status - + "]"); - } + Integer deleteOption = new MessageDialog(getShell(), "Stop Volume", GUIHelper.getInstance().getImage( + IImageKeys.VOLUME), "Are you sure you want to stop the volume [" + volume.getName() + "] ?", + MessageDialog.QUESTION, new String[] { "No", "Yes" }, -1).open(); + + if (deleteOption <= 0) { + return; + } + + final Status status = stopVolume(); + if (status.isSuccess()) { + showInfoDialog(actionDesc, "Volume [" + volume.getName() + "] stopped successfully!"); + modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); + } else { + showErrorDialog(actionDesc, "Volume [" + volume.getName() + "] could not be stopped! Error: [" + + status + "]"); + } + } + }); } private Status stopVolume() { -- cgit From c604f66c85de5fcda8ce36be22b34be06ad34704 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Wed, 8 Jun 2011 16:47:11 +0530 Subject: add/remove servers --- .../storage/management/client/UsersClient.java | 3 ++ .../storage/management/core/utils/JavaUtil.java | 41 +++++++++++++++ src/com.gluster.storage.management.gui/plugin.xml | 43 +++------------- .../management/gui/actions/AddServerAction.java | 14 ++--- .../management/gui/actions/RemoveServerAction.java | 12 +++++ .../storage/management/gui/utils/GUIHelper.java | 34 +++++++++++- .../management/gui/views/GlusterServersView.java | 2 +- .../gui/views/details/GlusterServersPage.java | 59 ++++++++++++++------- .../management/gui/views/pages/ServersPage.java | 60 +++++++++++++++------- .../server/resources/GlusterServersResource.java | 19 +++++++ 10 files changed, 202 insertions(+), 85 deletions(-) create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/JavaUtil.java 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 25ba6b10..3d2310ac 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 @@ -58,6 +58,9 @@ public class UsersClient extends AbstractClient { 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!"); diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/JavaUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/JavaUtil.java new file mode 100644 index 00000000..fe2fc860 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/JavaUtil.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.utils; + +import java.util.List; + +/** + * + */ +public class JavaUtil { + @SuppressWarnings("rawtypes") + public static boolean listsDiffer(List list1, List list2) { + if(list1.size() != list2.size()) { + return true; + } + + for(Object obj : list1) { + if(!list2.contains(obj)) { + return true; + } + } + + return false; + } +} diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index 82b7f3e0..89b2460b 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -666,22 +666,6 @@ toolbarPath="Normal" tooltip="Create a new Volume"> - - @@ -711,22 +695,6 @@ toolbarPath="Normal" tooltip="Remove Server(s)"> - - selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), Server.class); + if (selectedServers == null || selectedServers.isEmpty()) { + action.setEnabled(false); + } else { action.setEnabled(true); - if (selectedEntity instanceof EntityGroup && ((EntityGroup) selectedEntity).getEntityType() == Volume.class) { - action.setEnabled(false); - } } } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java index c7e437e8..0ca5627c 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java @@ -27,6 +27,7 @@ import java.util.Map.Entry; import java.util.Set; 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; @@ -147,4 +148,15 @@ public class RemoveServerAction extends AbstractActionDelegate { public void dispose() { } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + Set selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), + GlusterServer.class); + if(selectedServers == null || selectedServers.isEmpty()) { + action.setEnabled(false); + } else { + action.setEnabled(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 56a6c94b..a38c6b38 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 @@ -18,8 +18,10 @@ *******************************************************************************/ package com.gluster.storage.management.gui.utils; +import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; import org.eclipse.jface.action.Action; @@ -30,11 +32,17 @@ import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnLayoutData; import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; @@ -72,6 +80,7 @@ import org.eclipse.ui.progress.IProgressConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Disk; +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; @@ -406,7 +415,30 @@ public class GUIHelper { } return selectedEntities; } - + + public void configureCheckboxTableViewer(final CheckboxTableViewer tableViewer) { + tableViewer.addCheckStateListener(new ICheckStateListener() { + + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + }); + + tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @SuppressWarnings("unchecked") + @Override + public void selectionChanged(SelectionChangedEvent event) { + List checkedElements = Arrays.asList(tableViewer.getCheckedElements()); + List selectedElements = ((IStructuredSelection)event.getSelection()).toList(); + + if (JavaUtil.listsDiffer(checkedElements, selectedElements)) { + tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + } + } + }); + } public void showProgressView() { try { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java index 06b1e282..fa9c2e7f 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java @@ -52,7 +52,7 @@ public class GlusterServersView extends ViewPart implements IDoubleClickListener servers = (EntityGroup)guiHelper.getSelectedEntity(getSite(), EntityGroup.class); } - page = new GlusterServersPage(parent, SWT.NONE, servers); + page = new GlusterServersPage(getSite(), parent, SWT.NONE, servers); page.addDoubleClickListener(this); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java index c9fab9e0..36f60998 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java @@ -19,13 +19,9 @@ package com.gluster.storage.management.gui.views.details; import org.eclipse.jface.layout.TableColumnLayout; -import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -39,9 +35,14 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.widgets.FormToolkit; +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.gui.EntityGroupContentProvider; import com.gluster.storage.management.gui.GlusterServerTableLabelProvider; @@ -60,28 +61,23 @@ public class GlusterServersPage extends Composite { private static final String[] GLUSTER_SERVER_TABLE_COLUMN_NAMES = new String[] { "Name", "IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Space (GB)", "Space\nAvailable (GB)", "Status" }; // Removed "Preferred\nNetwork", - public GlusterServersPage(Composite parent, int style) { + public GlusterServersPage(IWorkbenchSite site, final Composite parent, int style, EntityGroup servers) { super(parent, style); - addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - toolkit.dispose(); - } - }); toolkit.adapt(this); toolkit.paintBordersFor(this); setupPageLayout(); Text filterText = guiHelper.createFilterText(toolkit, this); - setupServerTableViewer(filterText); - } - - public GlusterServersPage(final Composite parent, int style, EntityGroup servers) { - this(parent, style); + setupServerTableViewer(site, filterText); tableViewer.setInput(servers); parent.layout(); // Important - this actually paints the table + createListeners(parent); + } + + private void createListeners(final Composite parent) { /** * Ideally not required. However the table viewer is not getting laid out properly on performing * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window @@ -94,11 +90,31 @@ public class GlusterServersPage extends Composite { } }); - tableViewer.addCheckStateListener(new ICheckStateListener() { + final ClusterListener clusterListener = new DefaultClusterListener() { + + @Override + public void serverAdded(GlusterServer server) { + tableViewer.refresh(); + } @Override - public void checkStateChanged(CheckStateChangedEvent event) { - tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); + public void serverRemoved(GlusterServer server) { + tableViewer.refresh(); + } + + @Override + public void serverChanged(GlusterServer server, Event event) { + tableViewer.update(server, null); + } + }; + + final GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + modelManager.addClusterListener(clusterListener); + + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + modelManager.removeClusterListener(clusterListener); } }); } @@ -151,9 +167,14 @@ public class GlusterServersPage extends Composite { return tableViewerComposite; } - private void setupServerTableViewer(final Text filterText) { + private void setupServerTableViewer(IWorkbenchSite site, final Text filterText) { Composite tableViewerComposite = createTableViewerComposite(); tableViewer = createServerTableViewer(tableViewerComposite); + site.setSelectionProvider(tableViewer); + + // make sure that table selection is driven by checkbox selection + guiHelper.configureCheckboxTableViewer(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/ServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java index 5a6a9d40..20c3cbd4 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 @@ -1,4 +1,4 @@ -/******************************************************************************* + /******************************************************************************* * Copyright (c) 2011 Gluster, Inc. * This file is part of Gluster Management Console. * @@ -18,17 +18,10 @@ *******************************************************************************/ package com.gluster.storage.management.gui.views.pages; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.jface.layout.TableColumnLayout; -import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.ICheckStateListener; 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; @@ -45,7 +38,9 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.widgets.FormToolkit; -import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.gui.EntityGroupContentProvider; @@ -55,7 +50,7 @@ import com.gluster.storage.management.gui.utils.GUIHelper; public class ServersPage extends Composite { private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); - private TableViewer tableViewer; + private CheckboxTableViewer tableViewer; private GUIHelper guiHelper = GUIHelper.getInstance(); public enum SERVER_TABLE_COLUMN_INDICES { @@ -88,6 +83,10 @@ public class ServersPage extends Composite { setupPage(site, servers); parent.layout(); // Important - this actually paints the table + createListeners(parent); + } + + private void createListeners(final Composite parent) { /** * Ideally not required. However the table viewer is not getting laid out properly on performing * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window @@ -99,6 +98,33 @@ public class ServersPage extends Composite { parent.layout(); } }); + + final ClusterListener clusterListener = new DefaultClusterListener() { + @Override + public void discoveredServerRemoved(Server server) { + refreshViewer(); + } + + @Override + public void discoveredServerAdded(Server server) { + refreshViewer(); + } + + private void refreshViewer() { + tableViewer.refresh(); + parent.update(); + } + }; + + final GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + modelManager.addClusterListener(clusterListener); + addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + modelManager.removeClusterListener(clusterListener); + } + }); } public void setInput(EntityGroup servers) { @@ -135,21 +161,17 @@ public class ServersPage extends Composite { // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90); } - private TableViewer createServerTableViewer(Composite parent) { + private CheckboxTableViewer createServerTableViewer(Composite parent) { final CheckboxTableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.setLabelProvider(new ServerTableLabelProvider()); tableViewer.setContentProvider(new EntityGroupContentProvider()); setupServerTable(parent, tableViewer.getTable()); - - tableViewer.addCheckStateListener(new ICheckStateListener() { - - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - tableViewer.setSelection(new StructuredSelection(tableViewer.getCheckedElements())); - } - }); + + // make sure that table selection is driven by checkbox selection + guiHelper.configureCheckboxTableViewer(tableViewer); + return tableViewer; } 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 728da2dc..27f0829b 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 @@ -227,6 +227,16 @@ public class GlusterServersResource extends AbstractServersResource { @Produces(MediaType.TEXT_XML) public GlusterServerResponse addServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @FormParam(FORM_PARAM_SERVER_NAME) String serverName) { + if(clusterName.isEmpty()) { + return new GlusterServerResponse( + new Status(Status.STATUS_CODE_FAILURE, "Cluster name should not be empty!"), null); + } + + if(serverName == null || serverName.isEmpty()) { + return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, "Form parameter [" + + FORM_PARAM_SERVER_NAME + "] is mandatory!"), null); + } + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName @@ -287,6 +297,15 @@ public class GlusterServersResource extends AbstractServersResource { @Path("{" + PATH_PARAM_SERVER_NAME + "}") public Status removeServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { + if (clusterName.isEmpty()) { + return new Status(Status.STATUS_CODE_FAILURE, "Cluster name should not be empty!"); + } + + if(serverName == null || serverName.isEmpty()) { + return new Status(Status.STATUS_CODE_FAILURE, "Form parameter [" + FORM_PARAM_SERVER_NAME + + "] is mandatory!"); + } + ClusterInfo cluster = clusterService.getCluster(clusterName); if(cluster == null) { return new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"); -- cgit From c6456f7b7e3b617ae5ac66cd43f9e29ed49f9eb8 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Wed, 8 Jun 2011 18:17:45 +0530 Subject: Bug 2885 - "Add" button gets disabled after resetting volume options with any option without value --- .../gluster/storage/management/gui/views/details/VolumeOptionsPage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java index 1386b037..22d38e50 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java @@ -205,6 +205,7 @@ public class VolumeOptionsPage extends Composite { if (event.getEventType() == EVENT_TYPE.VOLUME_OPTIONS_RESET) { if (!tableViewer.getControl().isDisposed()) { tableViewer.refresh(); + setAddButtonsEnabled(true); } } -- cgit From 5f1c439181a2445e505243ea0feedbc1bb7e3460 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Thu, 9 Jun 2011 16:01:03 +0530 Subject: Bug 2990 - Create volume operation throws error message --- .../storage/management/core/utils/StringUtil.java | 19 +- .../server/resources/VolumesResource.java | 195 +++++++++++---------- .../management/server/utils/GlusterUtil.java | 2 +- 3 files changed, 121 insertions(+), 95 deletions(-) diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/StringUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/StringUtil.java index 556c12de..1b7335ee 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/StringUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/StringUtil.java @@ -32,12 +32,15 @@ public class StringUtil { } public static String ListToString(List list, String delimiter) { + if (list.size() == 0) { + return ""; + } StringBuilder output = new StringBuilder(); for (String element : list) { output.append(element).append(delimiter); } String outputStr = output.toString(); - int endIndex = (list.size() > 1) ? outputStr.length() - (delimiter.length() + 1) : outputStr.length() - delimiter.length(); + int endIndex = outputStr.length() - delimiter.length(); return outputStr.substring(0, endIndex); } @@ -48,4 +51,18 @@ public class StringUtil { } return enumAsArray; } + + public static void main(String args[]) { + + //Test case for "ListToString" + List string = new ArrayList(); + // Empty list + System.out.println(StringUtil.ListToString(string, ", ")); + // Only one + string.add("test"); + System.out.println(StringUtil.ListToString(string, ",:")); + // Multiple + string.add("welcome to java"); + System.out.println(StringUtil.ListToString(string, "")); + } } 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 d6c41475..fe6de156 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 @@ -102,14 +102,14 @@ public class VolumesResource { private static final String VOLUME_BRICK_LOG_SCRIPT = "get_volume_brick_log.py"; @InjectParam - private GlusterServersResource glusterServersResource; - + private GlusterServersResource glusterServersResource; + @InjectParam private ServerUtil serverUtil; @InjectParam private GlusterUtil glusterUtil; - + @InjectParam private ClusterService clusterService; @@ -117,24 +117,24 @@ public class VolumesResource { private VolumeOptionsDefaults volumeOptionsDefaults; private FileUtil fileUtil = new FileUtil(); - + @GET @Produces(MediaType.TEXT_XML) public VolumeListResponse getAllVolumes(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new VolumeListResponse(Status.STATUS_SUCCESS, new ArrayList()); } - + try { return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName())); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new VolumeListResponse(Status.STATUS_SUCCESS, new ArrayList()); } - + return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName())); } } @@ -146,18 +146,19 @@ public class VolumesResource { List brickDirectories = GlusterCoreUtil.getQualifiedBrickList(volume.getBricks()); GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } - + Status status = null; try { status = glusterUtil.createVolume(volume, brickDirectories, onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } status = glusterUtil.createVolume(volume, brickDirectories, onlineServer.getName()); } @@ -171,20 +172,24 @@ public class VolumesResource { public GenericResponse getVolume(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { - return new GenericResponse(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null); + if (onlineServer == null) { + return new GenericResponse(new Status(Status.STATUS_CODE_FAILURE, + "No online servers found in cluster [" + clusterName + "]"), null); } - + try { - return new GenericResponse(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName())); - } catch(ConnectionException e) { + return new GenericResponse(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, + onlineServer.getName())); + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new GenericResponse(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null); + if (onlineServer == null) { + return new GenericResponse(new Status(Status.STATUS_CODE_FAILURE, + "No online servers found in cluster [" + clusterName + "]"), null); } - - return new GenericResponse(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName())); + + return new GenericResponse(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, + onlineServer.getName())); } } @@ -194,7 +199,7 @@ public class VolumesResource { public Status performOperation(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_OPERATION) String operation) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } @@ -203,8 +208,9 @@ public class VolumesResource { } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } return performOperation(volumeName, operation, onlineServer); } @@ -227,27 +233,27 @@ public class VolumesResource { @QueryParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } - + Volume volume = null; try { volume = glusterUtil.getVolume(volumeName, onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } volume = glusterUtil.getVolume(volumeName, onlineServer.getName()); } - + List bricks = volume.getBricks(); Status status = glusterUtil.deleteVolume(volumeName, onlineServer.getName()); if (status.isSuccess()) { - List disks = volume.getDisks(); - Status postDeleteStatus = postDelete(volumeName, disks, deleteFlag); + Status postDeleteStatus = postDelete(volumeName, bricks, deleteFlag); if (!postDeleteStatus.isSuccess()) { status.setCode(Status.STATUS_CODE_PART_SUCCESS); @@ -261,23 +267,25 @@ public class VolumesResource { @Path("{" + QUERY_PARAM_VOLUME_NAME + "}/" + RESOURCE_DISKS) @Produces(MediaType.TEXT_XML) public Status removeBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, - @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICKS) String bricks, + @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICKS) String bricks, @QueryParam(QUERY_PARAM_DELETE_OPTION) boolean deleteFlag) { - List brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query parameter) + List brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query + // parameter) GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } Status status = null; try { status = glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } status = glusterUtil.removeBricks(volumeName, brickList, onlineServer.getName()); } @@ -292,15 +300,14 @@ public class VolumesResource { return status; } - private Status postDelete(String volumeName, List disks, boolean deleteFlag) { - String serverName, diskName, diskInfo[]; + private Status postDelete(String volumeName, List bricks, boolean deleteFlag) { Status result; - for (int i = 0; i < disks.size(); i++) { - diskInfo = disks.get(i).split(":"); - serverName = diskInfo[0]; - diskName = diskInfo[1]; - result = (Status) serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " " - + diskName + " " + volumeName + (deleteFlag ? " -d" : ""), Status.class); + for (Brick brick : bricks) { + String brickDirectory = brick.getBrickDirectory(); + String mountPoint = brickDirectory.substring(0, brickDirectory.lastIndexOf("/")); + + result = (Status) serverUtil.executeOnServer(true, brick.getServerName(), VOLUME_DIRECTORY_CLEANUP_SCRIPT + + " " + mountPoint + " " + volumeName + (deleteFlag ? " -d" : ""), Status.class); if (!result.isSuccess()) { return result; } @@ -316,17 +323,18 @@ public class VolumesResource { @FormParam(RESTConstants.FORM_PARAM_OPTION_KEY) String key, @FormParam(RESTConstants.FORM_PARAM_OPTION_VALUE) String value) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } try { return glusterUtil.setOption(volumeName, key, value, onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } return glusterUtil.setOption(volumeName, key, value, onlineServer.getName()); } @@ -374,7 +382,7 @@ public class VolumesResource { diskName = diskInfo[1]; Object response = serverUtil.executeOnServer(true, serverName, VOLUME_DIRECTORY_CLEANUP_SCRIPT + " " - + diskName + " " + volumeName + " " + (deleteFlag ? "-d" : ""), GenericResponse.class); + + diskName + " " + volumeName + " " + (deleteFlag ? "-d" : ""), GenericResponse.class); if (response instanceof GenericResponse) { result = ((GenericResponse) response).getStatus(); if (!result.isSuccess()) { @@ -428,16 +436,16 @@ public class VolumesResource { public StreamingOutput downloadLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) final String clusterName, @PathParam(PATH_PARAM_VOLUME_NAME) final String volumeName) { final ClusterInfo cluster = clusterService.getCluster(clusterName); - if(cluster == null) { + if (cluster == null) { throw new GlusterRuntimeException("Cluster [" + clusterName + "] doesn't exist!"); } - final Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); - if(volume == null) { + final Volume volume = (Volume) getVolume(clusterName, volumeName).getData(); + if (volume == null) { throw new GlusterRuntimeException("Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + "]!"); } - + return new StreamingOutput() { @Override @@ -460,7 +468,8 @@ public class VolumesResource { String tempDirPath = tempDir.getPath(); for (Brick brick : volume.getBricks()) { - String logDir = glusterUtil.getLogLocation(volume.getName(), brick.getBrickDirectory(), brick.getServerName()); + String logDir = glusterUtil.getLogLocation(volume.getName(), brick.getBrickDirectory(), + brick.getServerName()); String logFileName = glusterUtil.getLogFileNameForBrickDir(brick.getBrickDirectory()); String logFilePath = logDir + CoreConstants.FILE_SEPARATOR + logFileName; @@ -479,34 +488,32 @@ public class VolumesResource { @GET @Path("{" + PATH_PARAM_VOLUME_NAME + "}/" + RESOURCE_LOGS) public LogMessageListResponse getLogs(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, - @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, - @QueryParam(QUERY_PARAM_BRICK_NAME) String brickName, + @PathParam(PATH_PARAM_VOLUME_NAME) String volumeName, @QueryParam(QUERY_PARAM_BRICK_NAME) String brickName, @QueryParam(QUERY_PARAM_LOG_SEVERITY) String severity, @QueryParam(QUERY_PARAM_FROM_TIMESTAMP) String fromTimestamp, @QueryParam(QUERY_PARAM_TO_TIMESTAMP) String toTimestamp, - @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, - @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { + @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) { List logMessages = null; ClusterInfo cluster = clusterService.getCluster(clusterName); - if(cluster == null) { + if (cluster == null) { return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Cluster [" + clusterName + "] doesn't exist!"), null); } try { - Volume volume = (Volume)getVolume(clusterName, volumeName).getData(); - if(volume == null) { + Volume volume = (Volume) getVolume(clusterName, volumeName).getData(); + if (volume == null) { return new LogMessageListResponse(new Status(Status.STATUS_CODE_FAILURE, "Volume [" + volumeName + "] doesn't exist in cluster [" + clusterName + "]!"), null); } - + if (brickName == null || brickName.isEmpty() || brickName.equals(CoreConstants.ALL)) { logMessages = getLogsForAllBricks(volume, lineCount); } else { // fetch logs for given brick of the volume - for(Brick brick : volume.getBricks()) { - if(brick.getQualifiedName().equals(brickName)) { + for (Brick brick : volume.getBricks()) { + if (brick.getQualifiedName().equals(brickName)) { logMessages = getBrickLogs(volume, brick, lineCount); break; } @@ -585,17 +592,18 @@ public class VolumesResource { public Status addBricks(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_BRICKS) String bricks) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } try { return glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } return glusterUtil.addBricks(volumeName, Arrays.asList(bricks.split(",")), onlineServer.getName()); } @@ -607,17 +615,18 @@ public class VolumesResource { @PathParam(QUERY_PARAM_VOLUME_NAME) String volumeName, @FormParam(FORM_PARAM_SOURCE) String diskFrom, @FormParam(FORM_PARAM_TARGET) String diskTo, @FormParam(FORM_PARAM_OPERATION) String operation) { GlusterServer onlineServer = glusterServersResource.getOnlineServer(clusterName); - if(onlineServer == null) { + if (onlineServer == null) { return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); } - + try { return glusterUtil.migrateDisk(volumeName, diskFrom, diskTo, operation, onlineServer.getName()); - } catch(ConnectionException e) { + } catch (ConnectionException e) { // online server has gone offline! try with a different one. onlineServer = glusterServersResource.getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"); + if (onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + + "]"); } return glusterUtil.migrateDisk(volumeName, diskFrom, diskTo, operation, onlineServer.getName()); } @@ -630,22 +639,22 @@ public class VolumesResource { // System.out.println("\nName:" + volume.getName() + "\nType: " + volume.getVolumeTypeStr() + "\nStatus: " // + volume.getStatusStr()); // } -// Volume volume = new Volume(); -// volume.setName("vol3"); -// volume.setTransportType(TRANSPORT_TYPE.ETHERNET); -// List disks = new ArrayList(); -// disks.add("192.168.1.210:sdb"); -// volume.addDisks(disks); -// volume.setAccessControlList("192.168.*"); -// // Status status = vr.createVolume(volume); -// // System.out.println(status.getMessage()); -// Form form = new Form(); -// form.add("volumeName", volume.getName()); -// form.add(RESTConstants.FORM_PARAM_DELETE_OPTION, 1); -// Status status = vr.deleteVolume("Vol2", true); -// System.out.println("Code : " + status.getCode()); -// System.out.println("Message " + status.getMessage()); - + // Volume volume = new Volume(); + // volume.setName("vol3"); + // volume.setTransportType(TRANSPORT_TYPE.ETHERNET); + // List disks = new ArrayList(); + // disks.add("192.168.1.210:sdb"); + // volume.addDisks(disks); + // volume.setAccessControlList("192.168.*"); + // // Status status = vr.createVolume(volume); + // // System.out.println(status.getMessage()); + // Form form = new Form(); + // form.add("volumeName", volume.getName()); + // form.add(RESTConstants.FORM_PARAM_DELETE_OPTION, 1); + // Status status = vr.deleteVolume("Vol2", true); + // System.out.println("Code : " + status.getCode()); + // System.out.println("Message " + status.getMessage()); + Status status1 = vr.removeBricks("testCluster", "test", "192.168.1.210:sdb", true); System.out.println("Code : " + status1.getCode()); System.out.println("Message " + status1.getMessage()); 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 7f2afc3f..fe725d17 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 @@ -258,7 +258,7 @@ public class GlusterUtil { public Status setOption(String volumeName, String key, String value, String knownServer) { return new Status(sshUtil.executeRemote(knownServer, "gluster volume set " + volumeName + " " + key + " " - + value)); + + "\"" + value + "\"")); } public Status deleteVolume(String volumeName, String knownServer) { -- cgit