summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTim <timothyasir@gluster.com>2011-06-09 16:24:34 +0530
committerTim <timothyasir@gluster.com>2011-06-09 16:24:34 +0530
commite7fa3154115f72e3eefdb5790acbee1223de65a4 (patch)
treec3ba5e3df455f437a49c865d46c4e321636633dc /src
parent85575ed19b0e76b4067636f007a14ef86adc906f (diff)
parent88d3c1664d867df409589911afd42277cff5a1dc (diff)
Merge remote branch 'upstream/master'
Diffstat (limited to 'src')
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/UsersClient.java22
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java16
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java2
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Alert.java4
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Entity.java5
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/GlusterDummyModel.java12
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/RunningTask.java4
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java (renamed from src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/LogMessage.java)35
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/response/LogMessageListResponse.java12
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/JavaUtil.java41
-rw-r--r--src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/StringUtil.java19
-rw-r--r--src/com.gluster.storage.management.gui/plugin.xml43
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java8
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java10
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java92
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java91
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveDiskAction.java70
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java125
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ResetVolumeOptionsAction.java47
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java50
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java8
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java5
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java70
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java4
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java2
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java6
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java64
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java38
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java116
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java46
-rwxr-xr-xsrc/com.gluster.storage.management.server.scripts/src/disable-ssh-password-auth.sh30
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/AlertsResource.java2
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/ClustersResource.java1
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java95
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/RunningTaskResource.java4
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java252
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/services/ClusterService.java87
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/GlusterUtil.java2
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java4
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java23
41 files changed, 1038 insertions, 531 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..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
@@ -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,28 @@ 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) {
+ // 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!");
}
+ return new Status(Status.STATUS_CODE_FAILURE, "Exception during authentication: [" + e.getMessage() + "]");
}
}
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..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
@@ -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<String, String> queryParams = prepareGetLogQueryParams(diskName, severity, fromTimestamp,
+ MultivaluedMap<String, String> queryParams = prepareGetLogQueryParams(brickName, severity, fromTimestamp,
toTimestamp, messageCount);
return (LogMessageListResponse) fetchSubResource(volumeName + "/" + RESTConstants.RESOURCE_LOGS,
@@ -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<Brick> BrickList, boolean deleteOption) {
@@ -169,12 +169,12 @@ public class VolumesClient extends AbstractClient {
return queryParams;
}
- private MultivaluedMap<String, String> prepareGetLogQueryParams(String diskName, String severity,
+ private MultivaluedMap<String, String> prepareGetLogQueryParams(String brickName, String severity,
Date fromTimestamp, Date toTimestamp, int messageCount) {
MultivaluedMap<String, String> 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.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/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.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<LogMessage> logMessages = new ArrayList<LogMessage>();
+ private static List<VolumeLogMessage> logMessages = new ArrayList<VolumeLogMessage>();
private static GlusterDummyModel instance = new GlusterDummyModel();
private GlusterDataModel model;
@@ -212,21 +212,21 @@ public class GlusterDummyModel {
cluster.setAutoDiscoveredServers(servers);
}
- private void addMessages(List<LogMessage> messages, Disk disk, String severity, int count) {
+ private void addMessages(List<VolumeLogMessage> 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<LogMessage> logMessages, Disk disk) {
+ private void addMessagesForDisk(List<VolumeLogMessage> 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<LogMessage> createDummyLogMessages() {
+ public List<VolumeLogMessage> createDummyLogMessages() {
addMessagesForDisk(logMessages, s1da);
addMessagesForDisk(logMessages, s1db);
addMessagesForDisk(logMessages, s2da);
@@ -239,7 +239,7 @@ public class GlusterDummyModel {
return logMessages;
}
- public static List<LogMessage> getDummyLogMessages() {
+ public static List<VolumeLogMessage> getDummyLogMessages() {
return logMessages;
}
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/LogMessage.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/VolumeLogMessage.java
index 15c758a1..a5ac1848 100644
--- 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/VolumeLogMessage.java
@@ -28,17 +28,16 @@ import com.gluster.storage.management.core.model.adapters.VolumeLogDateAdapter;
import com.gluster.storage.management.core.utils.StringUtil;
@XmlRootElement
-public class LogMessage implements Filterable {
+public class VolumeLogMessage implements Filterable {
private Date timestamp;
- // TODO: Replace disk with brick, rename class as VolumeLogMessage
- private String disk;
+ private String brick;
private String severity;
private String message;
- public LogMessage() {
+ public VolumeLogMessage() {
}
- public LogMessage(String logMessage) {
+ public VolumeLogMessage(String logMessage) {
// TODO: Parse the log message and extract fields
}
@@ -52,14 +51,6 @@ public class LogMessage implements Filterable {
this.timestamp = timestamp;
}
- public String getDisk() {
- return disk;
- }
-
- public void setDisk(String disk) {
- this.disk = disk;
- }
-
public String getSeverity() {
return severity;
}
@@ -75,17 +66,27 @@ public class LogMessage implements Filterable {
public void setMessage(String message) {
this.message = message;
}
+
+ public void setBrickDirectory(String brickDirectory) {
+ this.brick = brickDirectory;
+ }
- public LogMessage(Date timestamp, String disk, String severity, String message) {
+
+ public String getBrickDirectory() {
+ return brick;
+ }
+
+ public VolumeLogMessage(Date timestamp, 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,
+ 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<LogMessage> logMessages = new ArrayList<LogMessage>();
+ private List<VolumeLogMessage> logMessages = new ArrayList<VolumeLogMessage>();
public LogMessageListResponse() {
}
- public LogMessageListResponse(Status status, List<LogMessage> logMessages) {
+ public LogMessageListResponse(Status status, List<VolumeLogMessage> logMessages) {
setStatus(status);
setLogMessages(logMessages);
}
@XmlElementWrapper(name = "logMessages")
- @XmlElement(name = "logMessage", type = LogMessage.class)
- public List<LogMessage> getLogMessages() {
+ @XmlElement(name = "logMessage", type = VolumeLogMessage.class)
+ public List<VolumeLogMessage> getLogMessages() {
return logMessages;
}
- public void setLogMessages(List<LogMessage> logMessages) {
+ public void setLogMessages(List<VolumeLogMessage> logMessages) {
this.logMessages = logMessages;
}
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. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.core.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.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<String> 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> string = new ArrayList<String>();
+ // 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.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">
</action>
- <action
- allowLabelUpdate="false"
- class="com.gluster.storage.management.gui.actions.AddServerAction"
- definitionId="com.gluster.storage.management.gui.commands.AddServer"
- icon="icons/server-add.png"
- id="com.gluster.storage.management.gui.actions.AddServerAction"
- label="Add &amp;Server(s)"
- menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster"
- mode="FORCE_TEXT"
- pulldown="false"
- retarget="false"
- state="false"
- style="push"
- toolbarPath="Normal"
- tooltip="Add Server(s) to Cluster">
- </action>
<menu
id="com.gluster.storage.management.gui.menu.cluster"
label="&amp;Gluster">
@@ -711,22 +695,6 @@
toolbarPath="Normal"
tooltip="Remove Server(s)">
</action>
- <action
- allowLabelUpdate="false"
- class="com.gluster.storage.management.gui.actions.AddServerAction"
- definitionId="com.gluster.storage.management.gui.commands.AddServer"
- icon="icons/server-add.png"
- id="com.gluster.storage.management.gui.actions.AddServerAction"
- label="&amp;Add Server(s)"
- menubarPath="com.gluster.storage.management.gui.menu.servers/servers"
- mode="FORCE_TEXT"
- pulldown="false"
- retarget="false"
- state="false"
- style="push"
- toolbarPath="Normal"
- tooltip="Add Server(s) to Cluster">
- </action>
<menu
id="com.gluster.storage.management.gui.menu.servers"
label="&amp;Gluster"
@@ -747,7 +715,7 @@
definitionId="com.gluster.storage.management.gui.commands.RemoveServer"
icon="icons/server-remove.png"
id="com.gluster.storage.management.gui.actions.RemoveServerAction"
- label="&amp;Remove Server"
+ label="&amp;Remove Server(s)"
menubarPath="com.gluster.storage.management.gui.menu.glusterserver/glusterserver"
mode="FORCE_TEXT"
pulldown="false"
@@ -807,7 +775,7 @@
definitionId="com.gluster.storage.management.gui.commands.AddServer"
icon="icons/server-add.png"
id="com.gluster.storage.management.gui.actions.AddServerAction"
- label="&amp;Add Server"
+ label="&amp;Add Server(s)"
menubarPath="com.gluster.storage.management.gui.menu.discoveredserver/discoveredserver"
mode="FORCE_TEXT"
pulldown="false"
@@ -1101,7 +1069,7 @@
<action
class="com.gluster.storage.management.gui.actions.RemoveServerAction"
definitionId="com.gluster.storage.management.gui.commands.RemoveServer"
- enablesFor="1"
+ enablesFor="+"
icon="icons/server-remove.png"
id="com.gluster.storage.management.gui.actions.RemoveServerAction"
label="&amp;Remove Server"
@@ -1115,6 +1083,7 @@
allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.MigrateDiskAction"
definitionId="com.gluster.storage.management.gui.commands.MigrateDisk"
+ enablesFor="1"
icon="icons/disk-migrate.png"
id="com.gluster.storage.management.gui.actions.MigrateDiskAction"
label="&amp;Migrate Disk"
@@ -1131,6 +1100,7 @@
allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.DeleteVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.DeleteVolume"
+ enablesFor="1"
icon="icons/volume-delete.png"
id="com.gluster.storage.management.gui.actions.DeleteVolumeAction"
label="&amp;Delete Volume"
@@ -1147,6 +1117,7 @@
allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.RebalanceVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.RebalanceVolume"
+ enablesFor="1"
icon="icons/volume-rebalance.png"
id="com.gluster.storage.management.gui.actions.RebalanceVolumeAction"
label="&amp;Rebalance Volume"
@@ -1163,6 +1134,7 @@
allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.StopVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.StopVolume"
+ enablesFor="+"
icon="icons/volume-stop.png"
id="com.gluster.storage.management.gui.actions.StopVolumeAction"
label="S&amp;top Volume"
@@ -1179,6 +1151,7 @@
allowLabelUpdate="false"
class="com.gluster.storage.management.gui.actions.StartVolumeAction"
definitionId="com.gluster.storage.management.gui.commands.StartVolume"
+ enablesFor="+"
icon="icons/volume-start.png"
id="com.gluster.storage.management.gui.actions.StartVolumeAction"
label="&amp;Start Volume"
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/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..230bff6a 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,84 @@
*******************************************************************************/
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.model.Entity;
-import com.gluster.storage.management.core.model.EntityGroup;
+import com.gluster.storage.management.core.constants.CoreConstants;
import com.gluster.storage.management.core.model.Server;
-import com.gluster.storage.management.core.model.Volume;
+import com.gluster.storage.management.core.model.Status;
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<Server> selectedServers = GUIHelper.getInstance().getSelectedEntities(getWindow(), Server.class);
+ Set<Server> successServers = new HashSet<Server>();
+ Set<Server> partSuccessServers = new HashSet<Server>();
+ 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<Server> selectedServers, Set<Server> 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
@@ -52,16 +103,13 @@ public class AddServerAction extends AbstractActionDelegate {
System.out.println("Disposing [" + this.getClass().getSimpleName() + "]");
}
- @SuppressWarnings("rawtypes")
@Override
public void selectionChanged(IAction action, ISelection selection) {
- super.selectionChanged(action, selection);
-
- if (selectedEntity != null && selectedEntity instanceof Entity) {
+ Set<Server> 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/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<String> 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<String> 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/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java
index b0b863ab..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
@@ -19,57 +19,121 @@
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<String> configuredVolumes = getServerVolumeNames(server.getName());
+ Set<GlusterServer> 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 the server(s) "
+ + selectedServers + " ?");
+ if (!confirmed) {
+ return;
+ }
- boolean confirmed = showConfirmDialog(actionDesc,
- "Are you sure you want to remove this server [" + server.getName() + "] ?");
- if (!confirmed) {
+ Set<GlusterServer> successServers = new HashSet<GlusterServer>();
+ 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<GlusterServer> selectedServers, Set<GlusterServer> 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<GlusterServer> selectedServers) {
+ Map<GlusterServer, List<String>> usedServers = new HashMap<GlusterServer, List<String>>();
+ for (GlusterServer server : selectedServers) {
+ List<String> 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<GlusterServer, List<String>> 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<String> getServerVolumeNames(String serverName) {
- Cluster cluster = GlusterDataModelManager.getInstance().getModel().getCluster();
+ Cluster cluster = modelManager.getModel().getCluster();
List<String> volumeNames = new ArrayList<String>();
for (Volume volume : cluster.getVolumes()) {
for (String brick : volume.getDisks()) {
@@ -82,16 +146,17 @@ 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;
+ Set<GlusterServer> 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/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/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() {
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/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<String> 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..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,7 +18,11 @@
*******************************************************************************/
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;
import org.eclipse.jface.action.IAction;
@@ -28,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;
@@ -70,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;
@@ -355,24 +366,79 @@ 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);
}
- public Object getSelectedEntity(IWorkbenchWindow window, Class expectedType) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T> T getSelectedEntity(IWorkbenchWindow window, Class<T> expectedType) {
ISelection selection = window.getSelectionService().getSelection(NavigationView.ID);
if (selection instanceof IStructuredSelection) {
Iterator<Object> iter = ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
Object selectedObj = iter.next();
if (selectedObj.getClass() == expectedType) {
- return selectedObj;
+ return (T)selectedObj;
}
}
}
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 <T> Set<T> getSelectedEntities(IWorkbenchSite site, Class<T> expectedType) {
+ return getSelectedEntities(site.getWorkbenchWindow(), expectedType);
+ }
+ @SuppressWarnings("unchecked")
+ public <T> Set<T> getSelectedEntities(IWorkbenchWindow window, Class<T> expectedType) {
+ Set<T> selectedEntities = new HashSet<T>();
+ ISelection selection = window.getSelectionService().getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Iterator<Object> iter = ((IStructuredSelection) selection).iterator();
+ while (iter.hasNext()) {
+ Object selectedObj = iter.next();
+ if (selectedObj.getClass() == expectedType) {
+ selectedEntities.add((T) selectedObj);
+ }
+ }
+ }
+ 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<Object> checkedElements = Arrays.asList(tableViewer.getCheckedElements());
+ List<Object> 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/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/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<GlusterServer>)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/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<Alert> 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/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java
index ef104fe2..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
@@ -22,7 +22,6 @@ import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -36,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;
@@ -47,7 +51,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 {
@@ -57,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<GlusterServer> 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<GlusterServer> 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
@@ -90,6 +89,34 @@ public class GlusterServersPage extends Composite {
parent.layout();
}
});
+
+ final ClusterListener clusterListener = new DefaultClusterListener() {
+
+ @Override
+ public void serverAdded(GlusterServer server) {
+ tableViewer.refresh();
+ }
+
+ @Override
+ 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);
+ }
+ });
}
public void addDoubleClickListener(IDoubleClickListener listener) {
@@ -122,8 +149,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<GlusterServer>());
@@ -140,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/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java
index 811b4c5c..9eb7357e 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,12 +68,12 @@ 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 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,12 +185,12 @@ 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()) {
- List<LogMessage> logMessages = response.getLogMessages();
- tableViewer.setInput(logMessages.toArray(new LogMessage[0]));
+ List<VolumeLogMessage> logMessages = response.getLogMessages();
+ tableViewer.setInput(logMessages.toArray(new VolumeLogMessage[0]));
tableViewer.refresh();
} else {
MessageDialog.openError(getShell(), "Volume Logs", "Error while fetching volume logs: [" + status
@@ -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);
}
@@ -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.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..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
@@ -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<VolumeOptionInfo> 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,61 +92,76 @@ public class VolumeOptionsPage extends Composite {
setupPageLayout();
filterText = guiHelper.createFilterText(toolkit, this);
- createAddButton();
+
+ addTopButton = createAddButton();
setupOptionsTableViewer(filterText);
-
- createAddButton();
+
+ addBottomButton = createAddButton();
+
+ if (defaultVolumeOptions.size() == volume.getOptions().size()) {
+ setAddButtonsEnabled(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 setAddButtonsEnabled(boolean enable) {
+ addTopButton.setEnabled(enable);
+ addBottomButton.setEnabled(enable);
+ }
+
+ private Button createAddButton() {
+ Button button = toolkit.createButton(this, "&Add", SWT.FLAT);
+ button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// add an empty option to be filled up by user
volume.setOption("", "");
-
+
tableViewer.refresh();
tableViewer.setSelection(new StructuredSelection(getEntry("")));
- keyColumn.getViewer().editElement(getEntry(""), 0); // edit newly created entry
-
+ 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);
+ setAddButtonsEnabled(false);
filterText.setEnabled(false);
}
private Entry<String, String> getEntry(String key) {
- for(Entry<String, String> entry : volume.getOptions().entrySet()) {
- if(entry.getKey().equals(key)) {
+ for (Entry<String, String> entry : volume.getOptions().entrySet()) {
+ if (entry.getKey().equals(key)) {
return entry;
}
}
return null;
}
});
-
+
// Make sure that add button is enabled only when search filter textbox is empty
filterText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
- if(filterText.getText().length() > 0) {
- addButton.setEnabled(false);
+ if (filterText.getText().length() > 0) {
+ setAddButtonsEnabled(false);
} else {
- addButton.setEnabled(true);
+ if (defaultVolumeOptions.size() == volume.getOptions().size()) {
+ setAddButtonsEnabled(false);
+ } else {
+ setAddButtonsEnabled(true);
+ }
}
}
});
+ return button;
}
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 +183,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<String, String> entryBeingAdded = keyEditingSupport.getEntryBeingAdded();
@@ -178,27 +197,32 @@ 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();
+ setAddButtonsEnabled(true);
}
}
-
- if(event.getEventType() == EVENT_TYPE.VOLUME_OPTION_SET) {
- Entry<String, String> eventEntry = (Entry<String, String>)event.getEventData();
+
+ if (event.getEventType() == EVENT_TYPE.VOLUME_OPTION_SET) {
+ Entry<String, String> eventEntry = (Entry<String, String>) 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
+ setAddButtonsEnabled(true);
filterText.setEnabled(true);
}
-
- if(tableViewer.getTable().getItemCount() < volume.getOptions().size()) {
+
+ if (defaultVolumeOptions.size() == volume.getOptions().size()) {
+ setAddButtonsEnabled(false);
+ }
+
+ if (tableViewer.getTable().getItemCount() < volume.getOptions().size()) {
// new volume set from outside this page. refresh the viewer.
tableViewer.refresh();
} else {
@@ -209,14 +233,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 +264,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 +274,7 @@ public class VolumeOptionsPage extends Composite {
return tableColumnLayout;
}
-
+
private TableColumn createValueColumn() {
TableViewerColumn valueColumn = new TableViewerColumn(tableViewer, SWT.NONE);
valueColumn.getColumn()
@@ -262,10 +286,10 @@ public class VolumeOptionsPage extends Composite {
return ((Entry<String, String>) element).getValue();
}
});
-
+
// User can edit value of a volume option
valueColumn.setEditingSupport(new OptionValueEditingSupport(valueColumn.getViewer(), volume));
-
+
return valueColumn.getColumn();
}
@@ -278,26 +302,26 @@ public class VolumeOptionsPage extends Composite {
public String getText(Object element) {
return ((Entry<String, String>) element).getKey();
}
-
+
@SuppressWarnings("unchecked")
@Override
public String getToolTipText(Object element) {
String key = ((Entry<String, String>) 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();
}
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..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. <http://www.gluster.com>
* This file is part of Gluster Management Console.
*
@@ -22,7 +22,6 @@ import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -39,6 +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.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;
@@ -48,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 {
@@ -81,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
@@ -92,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<Server> servers) {
@@ -128,14 +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) {
- TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI);
+ 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<Server>());
setupServerTable(parent, tableViewer.getTable());
+ // make sure that table selection is driven by checkbox selection
+ guiHelper.configureCheckboxTableViewer(tableViewer);
+
return tableViewer;
}
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/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/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/resources/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java
index 608783a1..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
@@ -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<ClusterInfo> 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<GlusterServer> glusterServers = new ArrayList<GlusterServer>();
- 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);
@@ -209,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) {
@@ -226,7 +227,17 @@ 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);
+ 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
+ "] doesn't exist!"), null);
@@ -255,7 +266,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 +292,21 @@ 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<ServerInfo> 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<ClusterInfo> 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);
+ 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!");
}
@@ -357,7 +330,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);
@@ -379,7 +352,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/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..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
@@ -29,8 +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;
@@ -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;
@@ -87,6 +87,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;
@@ -100,36 +102,39 @@ 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;
- private FileUtil fileUtil = new FileUtil();
-
+ @InjectParam
+ private ClusterService clusterService;
+
@InjectParam
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<Volume>());
}
-
+
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<Volume>());
}
-
+
return new VolumeListResponse(Status.STATUS_SUCCESS, glusterUtil.getAllVolumes(onlineServer.getName()));
}
}
@@ -141,18 +146,19 @@ public class VolumesResource {
List<String> 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());
}
@@ -166,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<Volume>(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null);
+ if (onlineServer == null) {
+ return new GenericResponse<Volume>(new Status(Status.STATUS_CODE_FAILURE,
+ "No online servers found in cluster [" + clusterName + "]"), null);
}
-
+
try {
- return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName()));
- } catch(ConnectionException e) {
+ return new GenericResponse<Volume>(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<Volume>(new Status(Status.STATUS_CODE_FAILURE, "No online servers found in cluster [" + clusterName + "]"), null);
+ if (onlineServer == null) {
+ return new GenericResponse<Volume>(new Status(Status.STATUS_CODE_FAILURE,
+ "No online servers found in cluster [" + clusterName + "]"), null);
}
-
- return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName, onlineServer.getName()));
+
+ return new GenericResponse<Volume>(Status.STATUS_SUCCESS, glusterUtil.getVolume(volumeName,
+ onlineServer.getName()));
}
}
@@ -189,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 + "]");
}
@@ -198,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);
}
@@ -222,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<Brick> bricks = volume.getBricks();
Status status = glusterUtil.deleteVolume(volumeName, onlineServer.getName());
if (status.isSuccess()) {
- List<String> 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);
@@ -256,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<String> brickList = Arrays.asList(bricks.split(",")); // Convert from comma separated string (query parameter)
+ List<String> 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());
}
@@ -287,15 +300,14 @@ public class VolumesResource {
return status;
}
- private Status postDelete(String volumeName, List<String> disks, boolean deleteFlag) {
- String serverName, diskName, diskInfo[];
+ private Status postDelete(String volumeName, List<Brick> 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;
}
@@ -311,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());
}
@@ -369,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()) {
@@ -385,7 +398,7 @@ public class VolumesResource {
return new Status(Status.STATUS_CODE_SUCCESS, "Directories cleaned up successfully!");
}
- private List<LogMessage> getBrickLogs(Volume volume, Brick brick, Integer lineCount)
+ private List<VolumeLogMessage> 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 +421,9 @@ public class VolumesResource {
}
// populate disk and trim other fields
- List<LogMessage> logMessages = response.getLogMessages();
- for (LogMessage logMessage : logMessages) {
- logMessage.setDisk(brick.getDiskName());
+ List<VolumeLogMessage> logMessages = response.getLogMessages();
+ for (VolumeLogMessage logMessage : logMessages) {
+ logMessage.setBrickDirectory(brick.getBrickDirectory());
logMessage.setMessage(logMessage.getMessage().trim());
logMessage.setSeverity(logMessage.getSeverity().trim());
}
@@ -420,15 +433,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();
@@ -446,12 +468,12 @@ 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;
- 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";
@@ -466,24 +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_DISK_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) {
- List<LogMessage> logMessages = null;
+ @QueryParam(QUERY_PARAM_LINE_COUNT) Integer lineCount, @QueryParam(QUERY_PARAM_DOWNLOAD) Boolean download) {
+ List<VolumeLogMessage> 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();
+ 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;
}
@@ -498,7 +528,7 @@ public class VolumesResource {
return new LogMessageListResponse(Status.STATUS_SUCCESS, logMessages);
}
- private void filterLogsByTime(List<LogMessage> logMessages, String fromTimestamp, String toTimestamp) {
+ private void filterLogsByTime(List<VolumeLogMessage> logMessages, String fromTimestamp, String toTimestamp) {
Date fromTime = null, toTime = null;
if (fromTimestamp != null && !fromTimestamp.isEmpty()) {
@@ -509,8 +539,8 @@ public class VolumesResource {
toTime = DateUtil.stringToDate(toTimestamp);
}
- List<LogMessage> messagesToRemove = new ArrayList<LogMessage>();
- for (LogMessage logMessage : logMessages) {
+ List<VolumeLogMessage> messagesToRemove = new ArrayList<VolumeLogMessage>();
+ for (VolumeLogMessage logMessage : logMessages) {
Date logTimestamp = logMessage.getTimestamp();
if (fromTime != null && logTimestamp.before(fromTime)) {
messagesToRemove.add(logMessage);
@@ -524,13 +554,13 @@ public class VolumesResource {
logMessages.removeAll(messagesToRemove);
}
- private void filterLogsBySeverity(List<LogMessage> logMessages, String severity) {
+ private void filterLogsBySeverity(List<VolumeLogMessage> logMessages, String severity) {
if (severity == null || severity.isEmpty()) {
return;
}
- List<LogMessage> messagesToRemove = new ArrayList<LogMessage>();
- for (LogMessage logMessage : logMessages) {
+ List<VolumeLogMessage> messagesToRemove = new ArrayList<VolumeLogMessage>();
+ for (VolumeLogMessage logMessage : logMessages) {
if (!logMessage.getSeverity().equals(severity)) {
messagesToRemove.add(logMessage);
}
@@ -538,18 +568,18 @@ public class VolumesResource {
logMessages.removeAll(messagesToRemove);
}
- private List<LogMessage> getLogsForAllBricks(Volume volume, Integer lineCount) {
- List<LogMessage> logMessages;
- logMessages = new ArrayList<LogMessage>();
+ private List<VolumeLogMessage> getLogsForAllBricks(Volume volume, Integer lineCount) {
+ List<VolumeLogMessage> logMessages;
+ logMessages = new ArrayList<VolumeLogMessage>();
// 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<LogMessage>() {
+ Collections.sort(logMessages, new Comparator<VolumeLogMessage>() {
@Override
- public int compare(LogMessage message1, LogMessage message2) {
+ public int compare(VolumeLogMessage message1, VolumeLogMessage message2) {
return message1.getTimestamp().compareTo(message2.getTimestamp());
}
});
@@ -562,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());
}
@@ -584,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());
}
@@ -607,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<String> disks = new ArrayList<String>();
-// 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<String> disks = new ArrayList<String>();
+ // 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/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. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.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<ClusterInfo> clusterDao;
+
+ public ClusterInfo getCluster(String clusterName) {
+ List<ClusterInfo> 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<ServerInfo> 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);
+ }
+ }
+}
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) {
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 82cec63b..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
@@ -55,6 +55,7 @@ public class SshUtil {
private LRUCache<String, Connection> sshConnCache = new LRUCache<String, Connection>(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";
@@ -79,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);
@@ -89,7 +101,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 +130,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) {