From 5c791f92f77aa65fd0c744b5660336ef300248b2 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 15 Jul 2011 16:47:53 +0530 Subject: Removed subprocess.popen and used fork method to execute background tasks. --- .../src/format_device.py | 16 ++++++++++------ .../src/get_format_device_status.py | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.server.scripts/src/format_device.py b/src/com.gluster.storage.management.server.scripts/src/format_device.py index 80334d8a..061236e0 100755 --- a/src/com.gluster.storage.management.server.scripts/src/format_device.py +++ b/src/com.gluster.storage.management.server.scripts/src/format_device.py @@ -64,14 +64,18 @@ def main(): sys.exit(2) if options.fstype: - process = Utils.runCommandBG("gluster_provision_block_wrapper.py -t %s %s" % (options.fstype, device), root=True) + command = ["gluster_provision_block_wrapper.py", "-t", "%s" % (options.fstype), "%s" % (device)] else: - process = Utils.runCommandBG("gluster_provision_block_wrapper.py %s" % device, root=True) - if process: - sys.exit(0) + command = ["gluster_provision_block_wrapper.py", "%s" % (device)] - sys.stderr.write("Device format failed\n") - sys.exit(3) + try: + pid = os.fork() + except OSError, e: + Utils.log("failed to fork a child process: %s" % str(e)) + sys.exit(1) + if pid == 0: + os.execv("/usr/sbin/gluster_provision_block_wrapper.py", command) + sys.exit(0) if __name__ == "__main__": diff --git a/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py b/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py index a24cb77a..57fc0455 100755 --- a/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py +++ b/src/com.gluster.storage.management.server.scripts/src/get_format_device_status.py @@ -18,6 +18,7 @@ import os import sys +import time import Utils import DiskUtils from XmlHandler import ResponseXml @@ -33,6 +34,7 @@ def main(): deviceFormatStatusFile = Utils.getDeviceFormatStatusFile(device) deviceFormatOutputFile = Utils.getDeviceFormatOutputFile(device) + time.sleep(1) if not os.path.exists(deviceFormatLockFile): if not os.path.exists(deviceFormatStatusFile): sys.stderr.write("Device format not initiated\n") -- cgit From 194d5787da03f843a4eb81f304d6f30057bb5be2 Mon Sep 17 00:00:00 2001 From: Dhandapani Date: Fri, 15 Jul 2011 14:06:58 +0530 Subject: Disk and Partition feature added --- .../management/client/GlusterDataModelManager.java | 106 +++++--------- .../storage/management/core/model/Brick.java | 18 +-- .../storage/management/core/model/Device.java | 6 +- .../storage/management/core/model/Disk.java | 27 +++- .../storage/management/core/model/Partition.java | 15 +- .../management/gui/BrickTableLabelProvider.java | 24 +-- .../management/gui/DeviceTableLabelProvider.java | 119 +++++++++++++++ .../management/gui/DiskTableLabelProvider.java | 95 ------------ .../gui/ServerDiskTableLabelProvider.java | 40 +++-- .../management/gui/dialogs/AddBrickPage.java | 41 +++--- .../gui/dialogs/BricksSelectionPage.java | 119 +++++++-------- .../management/gui/dialogs/CreateVolumePage1.java | 21 +-- .../management/gui/dialogs/MigrateBrickPage1.java | 9 +- .../management/gui/dialogs/SelectDisksDialog.java | 20 +-- .../storage/management/gui/utils/GUIHelper.java | 4 + .../storage/management/gui/views/DisksView.java | 1 + .../management/gui/views/VolumeSummaryView.java | 2 +- .../gui/views/pages/AbstractDisksPage.java | 125 +++++++--------- .../views/pages/AbstractTableTreeViewerPage.java | 163 +++++++++++++++++++++ .../gui/views/pages/DiskTreeContentProvider.java | 123 ++++++++++++++++ .../management/gui/views/pages/DisksPage.java | 38 ++--- .../gui/views/pages/ServerDisksPage.java | 36 ++--- .../resources/v1_0/GlusterServersResource.java | 10 +- 23 files changed, 734 insertions(+), 428 deletions(-) create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DeviceTableLabelProvider.java delete mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DiskTreeContentProvider.java (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index ba5ce336..e6089360 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -31,12 +31,14 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Event; import com.gluster.storage.management.core.model.Event.EVENT_TYPE; import com.gluster.storage.management.core.model.GlusterDataModel; import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.Partition; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.TaskInfo; @@ -417,17 +419,11 @@ public class GlusterDataModelManager { return volume; } - /** - * @param serverPartition - * Qualified name of the disk to be returned (serverName:diskName) - * @return The disk object for given qualified name - */ - public Disk getDisk(String serverPartition) { - List allDisks = getReadyDisksOfAllServers(); - String diskInfo[] = serverPartition.split(":"); - for (Disk disk : allDisks) { - if (disk.getServerName().equals(diskInfo[0]) && disk.getName().equals(diskInfo[1])) { - return disk; + private Device getDevice(String serverName, String deviceName) { + List allDevices = getReadyDevicesOfAllServers(); + for (Device device : allDevices) { + if (device.getServerName().equals(serverName) && device.getName().equals(deviceName)) { + return device; } } return null; @@ -436,85 +432,51 @@ public class GlusterDataModelManager { /* * @param diskName (sda) * - * @return The disk object for given disk name + * @return The device object for given device name */ - public Disk getDiskDetails(String diskName) { - List allDisks = getReadyDisksOfAllServers(); - for (Disk disk : allDisks) { - if (disk.getName().equals(diskName)) { - return disk; + public Device getDeviceDetails(String deviceName) { + List allDevices = getReadyDevicesOfAllServers(); + for (Device device : allDevices) { + if (device.getName().equals(deviceName)) { + return device; } } return null; } - public List getReadyDisksOfVolume(Volume volume) { - /* - * TODO: review the logic - * - * List disks = new ArrayList(); for (Disk disk : volume.getDisks()) { if (disk.isReady()) { - * disks.add(disk); } } - */ - Disk disk = null; - List volumeDisks = new ArrayList(); - for (Brick brick : volume.getBricks()) { - disk = getDisk(brick.getServerName() + ":" + brick.getDiskName()); - // disk = new Disk(); - // disk.setServerName(brick.getServerName()); - // disk.setName(brick.getDiskName()); - // disk.setStatus(DISK_STATUS.READY); - // disk.setMountPoint("/export/" + disk.getName()); - // disk.setSpace(250d); - // disk.setSpaceInUse(186.39); - if (disk != null && disk.isReady()) { - volumeDisks.add(disk); - } - } - return volumeDisks; - } - - public List getOnlineBricks(Volume volume) { - List onlineBricks = new ArrayList(); + public List getReadyDevicesOfVolume(Volume volume) { + Device device = null; + List volumeDevices = new ArrayList(); for (Brick brick : volume.getBricks()) { - if (isOnlineDisk(brick.getDiskName())) { - onlineBricks.add(brick); + device = getDevice(brick.getServerName(), brick.getDeviceName()); + if (device != null && device.isReady()) { + volumeDevices.add(device); } } - return onlineBricks; - } - - public boolean isOnlineDisk(String diskName) { - for (Disk disk : getReadyDisksOfAllServers()) { - if (disk.getName().equals(diskName) && disk.isReady()) { - return true; - } - } - return false; - } - - public List getReadyDisksOfAllVolumes() { - List disks = new ArrayList(); - for (Volume volume : model.getCluster().getVolumes()) { - disks.addAll(getReadyDisksOfVolume(volume)); - } - return disks; + return volumeDevices; } - public List getReadyDisksOfAllServers() { - return getReadyDisksOfAllServersExcluding(new ArrayList()); + public List getReadyDevicesOfAllServers() { + return getReadyDevicesOfAllServersExcluding(new ArrayList()); } - public List getReadyDisksOfAllServersExcluding(List excludeDisks) { - List disks = new ArrayList(); + public List getReadyDevicesOfAllServersExcluding(List excludeDevices) { + List devices = new ArrayList(); for (Server server : model.getCluster().getServers()) { for (Disk disk : server.getDisks()) { - if (disk.isReady() && !excludeDisks.contains(disk)) { - disks.add(disk); + if(disk.hasPartitions()) { + for(Partition partition : disk.getPartitions()) { + if(partition.isReady() && !excludeDevices.contains(partition)) { + devices.add(partition); + } + } + } else if (disk.isReady() && !excludeDevices.contains(disk)) { + devices.add(disk); } } } - return disks; + return devices; } public void addClusterListener(ClusterListener listener) { @@ -721,7 +683,7 @@ public class GlusterDataModelManager { private Boolean isDiskUsed(Volume volume, Disk disk) { for (Brick brick : volume.getBricks()) { - if (disk.getName().equals(brick.getDiskName()) && disk.getServerName().equals(brick.getServerName())) { + if (disk.getName().equals(brick.getDeviceName()) && disk.getServerName().equals(brick.getServerName())) { return true; } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Brick.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Brick.java index 0b330514..52978f2a 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Brick.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Brick.java @@ -29,7 +29,7 @@ public class Brick extends Entity { private String[] BRICK_STATUS_STR = {"Online", "Offline"}; private String serverName; - private String diskName; + private String deviceName; private String brickDirectory; private BRICK_STATUS status; @@ -54,10 +54,10 @@ public class Brick extends Entity { this.status = status; } - public Brick(String serverName, BRICK_STATUS brickStatus, String diskName, String brickDirectory) { + public Brick(String serverName, BRICK_STATUS brickStatus, String deviceName, String brickDirectory) { setServerName(serverName); setStatus(brickStatus); - setDiskName(diskName); + setDeviceName(deviceName); setBrickDirectory(brickDirectory); } @@ -77,12 +77,12 @@ public class Brick extends Entity { return brickDirectory; } - public void setDiskName(String diskName) { - this.diskName = diskName; + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; } - public String getDiskName() { - return diskName; + public String getDeviceName() { + return deviceName; } public String getQualifiedName() { @@ -90,7 +90,7 @@ public class Brick extends Entity { } public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getServerName() + getBrickDirectory() + getDiskName() + getStatusStr(), filterString, + return StringUtil.filterString(getServerName() + getBrickDirectory() + getDeviceName() + getStatusStr(), filterString, caseSensitive); } @@ -116,7 +116,7 @@ public class Brick extends Entity { public void copyFrom(Brick newBrick) { setServerName(newBrick.getServerName()); setBrickDirectory(newBrick.getBrickDirectory()); - setDiskName(newBrick.getDiskName()); + setDeviceName(newBrick.getDeviceName()); setStatus(newBrick.getStatus()); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java index ebb095f1..7c1d3d54 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Device.java @@ -51,8 +51,8 @@ public class Device extends Entity { private String serverName; private String mountPoint; - private Double space; - private Double spaceInUse; + private Double space = 0.0; + private Double spaceInUse = 0.0; private DEVICE_STATUS status; public Device() { @@ -73,7 +73,7 @@ public class Device extends Entity { } public Double getFreeSpace() { - return getSpace() - getSpaceInUse(); + return (getSpace() - getSpaceInUse()); } public void setSpace(Double space) { diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java index f09f20ba..d6d3f7af 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Disk.java @@ -18,9 +18,11 @@ *******************************************************************************/ package com.gluster.storage.management.core.model; +import java.util.ArrayList; import java.util.Collection; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import com.gluster.storage.management.core.utils.GlusterCoreUtil; @@ -33,7 +35,7 @@ public class Disk extends Device { // interface = pci, raid0, raid3, etc private String diskInterface; - private Collection partitions; + private Collection partitions = new ArrayList(); // In case of a software raid, the disk will contain an array of other disks private Collection raidDisks; @@ -58,6 +60,8 @@ public class Disk extends Device { this.diskInterface = diskInterface; } + @XmlElementWrapper(name="raidDisks") + @XmlElement(name="disk", type=Disk.class) public Collection getRaidDisks() { return raidDisks; } @@ -70,9 +74,15 @@ public class Disk extends Device { this.partitions = partitions; } + @XmlElementWrapper(name="partitions") + @XmlElement(name="partition", type=Partition.class) public Collection getPartitions() { return partitions; } + + public boolean hasPartitions() { + return (partitions != null && partitions.size() > 0); + } public Disk(Server server, String name, String mountPoint, Double space, Double spaceInUse, DEVICE_STATUS status) { super(server, name, mountPoint, space, spaceInUse, status); @@ -80,8 +90,19 @@ public class Disk extends Device { @Override public boolean filter(String filterString, boolean caseSensitive) { - return StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() - + getType() + getDescription(), filterString, caseSensitive); + if (StringUtil.filterString(getServerName() + getName() + getStatusStr() + getSpace() + getFreeSpace() + + getType() + getDescription(), filterString, caseSensitive)) { + return true; + } + + // disk doesn't match. check if any of the partitions of this disk match the filter + for(Partition partition : getPartitions()) { + if(partition.filter(filterString, caseSensitive)) { + return true; + } + } + + return false; } @Override diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java index a06b1e1c..ecf4035b 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Partition.java @@ -18,9 +18,18 @@ *******************************************************************************/ package com.gluster.storage.management.core.model; -/** - * - */ +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name="partition") public class Partition extends Device { + public Partition() { + super(); + } + + public Partition(Server server, String name, String mountPoint, Double space, Double spaceInUse, + DEVICE_STATUS status) { + super(server, name, mountPoint, space, spaceInUse, status); + } + } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java index 71e6e802..4ac1db41 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/BrickTableLabelProvider.java @@ -23,8 +23,8 @@ import org.eclipse.swt.graphics.Image; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; -import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.utils.GUIHelper; import com.gluster.storage.management.gui.views.pages.BricksPage.BRICK_TABLE_COLUMN_INDICES; @@ -41,10 +41,10 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { } Brick brick = (Brick) element; - Disk disk = GlusterDataModelManager.getInstance().getDiskDetails(brick.getDiskName()); + Device device = GlusterDataModelManager.getInstance().getDeviceDetails(brick.getDeviceName()); if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DEVICE_STATUS status = disk.getStatus(); + DEVICE_STATUS status = device.getStatus(); // TODO: Use different images for all four statuses switch (status) { case INITIALIZED: @@ -63,17 +63,17 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { return null; } - private String getDiskFreeSpace(Disk disk) { - if (disk != null && disk.isReady() && disk.getFreeSpace() != null) { - return NumberUtil.formatNumber((disk.getFreeSpace() / 1024)); + private String getDeviceFreeSpace(Device device) { + if (device != null && device.isReady() && device.getFreeSpace() != null) { + return NumberUtil.formatNumber((device.getFreeSpace() / 1024)); } else { return "NA"; } } - private String getDiskSpace(Disk disk) { - if (disk.isReady() && disk.getSpace() != null && disk.getSpace() != 0.0) { - return NumberUtil.formatNumber((disk.getSpace() / 1024)); + private String getDeviceCapacity(Device device) { + if (device.isReady() && device.getSpace() != null && device.getSpace() != 0.0) { + return NumberUtil.formatNumber((device.getSpace() / 1024)); } else { return "NA"; } @@ -86,11 +86,11 @@ public class BrickTableLabelProvider extends TableLabelProviderAdapter { } Brick brick = (Brick) element; - Disk disk = GlusterDataModelManager.getInstance().getDiskDetails(brick.getDiskName()); + Device device = GlusterDataModelManager.getInstance().getDeviceDetails(brick.getDeviceName()); return (columnIndex == BRICK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? brick.getServerName() : columnIndex == BRICK_TABLE_COLUMN_INDICES.BRICK.ordinal() ? brick.getBrickDirectory() - : columnIndex == BRICK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal() ? getDiskFreeSpace(disk) - : columnIndex == BRICK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal() ? getDiskSpace(disk) + : columnIndex == BRICK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal() ? getDeviceFreeSpace(device) + : columnIndex == BRICK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal() ? getDeviceCapacity(device) : columnIndex == BRICK_TABLE_COLUMN_INDICES.STATUS.ordinal() ? brick .getStatusStr() : "Invalid"); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DeviceTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DeviceTableLabelProvider.java new file mode 100644 index 00000000..cdc2f9a8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DeviceTableLabelProvider.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Device; +import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Partition; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class DeviceTableLabelProvider extends LabelProvider implements ITableLabelProvider { + + private GUIHelper guiHelper = GUIHelper.getInstance(); + public enum DEVICE_COLUMN_INDICES { + DISK, PARTITION, FREE_SPACE, SPACE_IN_USE, STATUS + }; + + FontRegistry registry = new FontRegistry(); + + public DeviceTableLabelProvider() { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (!(element instanceof Device)) { + return null; + } + + Device device = (Device) element; + if (columnIndex == DEVICE_COLUMN_INDICES.STATUS.ordinal()) { + DEVICE_STATUS status = device.getStatus(); + + if (status == null) { + if (element instanceof Partition) { + if (columnIndex == DEVICE_COLUMN_INDICES.STATUS.ordinal()) { + status = device.getStatus(); + } + } + } + + if (status == null) { + return null; + } + + // TODO: Use different images for all four statuses + switch (status) { + case INITIALIZED: + return guiHelper.getImage(IImageKeys.STATUS_ONLINE); + case IO_ERROR: + return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); + case UNINITIALIZED: + return guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED); + case INITIALIZING: + return guiHelper.getImage(IImageKeys.WORK_IN_PROGRESS); + default: + throw new GlusterRuntimeException("Invalid disk status [" + status + "]"); + } + } + + return null; + } + + @Override + public String getText(Object element) { + return super.getText(element); + } + + public String getColumnText(Object element, int columnIndex) { + + if (element == null) { + return ""; + } + + Device device = (Device) element; + if (columnIndex == DEVICE_COLUMN_INDICES.DISK.ordinal()) { + if (device instanceof Disk) { + return device.getQualifiedName(); + } else { + return ""; + } + } else if (columnIndex == DEVICE_COLUMN_INDICES.FREE_SPACE.ordinal()) { + return "" + device.getFreeSpace(); + } else if (columnIndex == DEVICE_COLUMN_INDICES.SPACE_IN_USE.ordinal()) { + return "" + device.getSpaceInUse(); + } else if (columnIndex == DEVICE_COLUMN_INDICES.PARTITION.ordinal()) { + if (device instanceof Partition) { + return device.getQualifiedName(); + } else { + return ""; + } + } else if (columnIndex == DEVICE_COLUMN_INDICES.STATUS.ordinal()) { + return device.getStatusStr(); + } else { + return ""; + } + } +} \ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java deleted file mode 100644 index 28d7c353..00000000 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Gluster, Inc. - * This file is part of Gluster Management Console. - * - * Gluster Management Console is free software; you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Gluster Management Console is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License - * for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * . - *******************************************************************************/ -package com.gluster.storage.management.gui; - -import org.eclipse.swt.graphics.Image; - -import com.gluster.storage.management.client.GlusterDataModelManager; -import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; -import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; -import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.core.utils.NumberUtil; -import com.gluster.storage.management.gui.utils.GUIHelper; -import com.gluster.storage.management.gui.views.pages.DisksPage.DISK_TABLE_COLUMN_INDICES; - -public class DiskTableLabelProvider extends TableLabelProviderAdapter { - private GUIHelper guiHelper = GUIHelper.getInstance(); - private GlusterDataModelManager glusterDataModelManager = GlusterDataModelManager.getInstance(); - - @Override - public Image getColumnImage(Object element, int columnIndex) { - - if (!(element instanceof Disk)) { - return null; - } - - // Brick brick = (Brick) element; - // Disk disk = GlusterDataModelManager.getInstance().getDisk(brick.getDiskName()); - Disk disk = (Disk) element; - - if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { - DEVICE_STATUS status = disk.getStatus(); - // TODO: Use different images for different statuses - switch (status) { - case INITIALIZED: - return guiHelper.getImage(IImageKeys.STATUS_ONLINE); - case IO_ERROR: - return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); - case UNINITIALIZED: - return guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED); - case INITIALIZING: - return guiHelper.getImage(IImageKeys.WORK_IN_PROGRESS); - default: - throw new GlusterRuntimeException("Invalid disk status [" + status + "]"); - } - } - - return null; - } - - private String getDiskFreeSpace(Disk disk) { - if (disk.hasErrors() || disk.isUninitialized()) { - return "NA"; - } else { - return NumberUtil.formatNumber((disk.getFreeSpace() / 1024)); - } - } - - private String getTotalDiskSpace(Disk disk) { - if (disk.hasErrors() || disk.isUninitialized()) { - return "NA"; - } else { - return NumberUtil.formatNumber((disk.getSpace() / 1024)); - } - } - - @Override - public String getColumnText(Object element, int columnIndex) { - if (!(element instanceof Disk)) { - return null; - } - - Disk disk = (Disk) element; - return (columnIndex == DISK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? disk.getServerName() - : columnIndex == DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() - : columnIndex == DISK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal() ? getDiskFreeSpace(disk) - : columnIndex == DISK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal() ? getTotalDiskSpace(disk) - : columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal() ? glusterDataModelManager.getDiskStatus(disk) : "Invalid"); - } -} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java index 210436cb..732787d0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java @@ -24,9 +24,13 @@ import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Partition; import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.DeviceTableLabelProvider.DEVICE_COLUMN_INDICES; import com.gluster.storage.management.gui.utils.GUIHelper; +//import com.gluster.storage.management.gui.views.pages.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES; import com.gluster.storage.management.gui.views.pages.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES; public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { @@ -81,19 +85,29 @@ public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { } } - @Override public String getColumnText(Object element, int columnIndex) { - if (!(element instanceof Disk)) { - return null; + Device device = (Device) element; + if (columnIndex == DEVICE_COLUMN_INDICES.DISK.ordinal()) { + if (device instanceof Disk) { + return device.getName(); + } else { + return ""; + } + } else if (columnIndex == DEVICE_COLUMN_INDICES.FREE_SPACE.ordinal()) { + return "" + device.getFreeSpace(); + } else if (columnIndex == DEVICE_COLUMN_INDICES.SPACE_IN_USE.ordinal()) { + return "" + device.getSpace(); + } else if (columnIndex == DEVICE_COLUMN_INDICES.PARTITION.ordinal()) { + if (device instanceof Partition) { + return device.getName(); + } else { + return ""; + } + } else if (columnIndex == DEVICE_COLUMN_INDICES.STATUS.ordinal()) { + return device.getStatusStr(); + } else { + return ""; } - - Disk disk = (Disk) element; - String columnText = (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() - : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal() ? getDiskFreeSpace(disk) - : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal() ? getTotalDiskSpace(disk) - : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal() ? glusterDataModelManager - .getDiskStatus(disk) // disk.getStatusStr() - : "Invalid"); - return ((columnText == null || columnText.trim().equals("")) ? CoreConstants.NA : columnText); - } + } + } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/AddBrickPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/AddBrickPage.java index bd36ff7c..2856ea02 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/AddBrickPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/AddBrickPage.java @@ -31,6 +31,7 @@ import org.eclipse.swt.widgets.Composite; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; @@ -42,8 +43,8 @@ import com.richclientgui.toolbox.duallists.IRemovableContentProvider; * */ public class AddBrickPage extends WizardPage { - private List availableDisks = new ArrayList(); - private List selectedDisks = new ArrayList(); + private List availableDevices = new ArrayList(); + private List selectedDevices = new ArrayList(); private Volume volume = null; private BricksSelectionPage page = null; @@ -66,34 +67,34 @@ public class AddBrickPage extends WizardPage { } setDescription(description); - availableDisks = getAvailableDisks(volume); + availableDevices = getAvailableDevices(volume); setPageComplete(false); setErrorMessage("Please select bricks to be added to the volume [" + volume.getName() +"]"); } - private boolean isDiskUsed(Volume volume, Disk disk){ - for (Brick volumeBrick : volume.getBricks()) { // expected form of volumeBrick is "server:/export/diskName/volumeName" - if ( disk.getQualifiedBrickName(volume.getName()).equals(volumeBrick.getQualifiedName())) { + private boolean isDeviceUsed(Volume volume, Device device){ + for (Brick volumeBrick : volume.getBricks()) { + if ( device.getQualifiedBrickName(volume.getName()).equals(volumeBrick.getQualifiedName())) { return true; } } return false; } - protected List getAvailableDisks(Volume volume) { - List availableDisks = new ArrayList(); - for (Disk disk : GlusterDataModelManager.getInstance().getReadyDisksOfAllServers()) { - if ( ! isDiskUsed(volume, disk) ) { - availableDisks.add(disk); + protected List getAvailableDevices(Volume volume) { + List availableDevices = new ArrayList(); + for (Device device : GlusterDataModelManager.getInstance().getReadyDevicesOfAllServers()) { + if ( ! isDeviceUsed(volume, device) ) { + availableDevices.add(device); } } - return availableDisks; + return availableDevices; } - public Set getChosenDisks() { - return new HashSet(page.getChosenDisks()); + public Set getChosenDevices() { + return new HashSet(page.getChosenDevices()); } public Set getChosenBricks( String volumeName ) { @@ -122,16 +123,16 @@ public class AddBrickPage extends WizardPage { @Override public void createControl(Composite parent) { getShell().setText("Add Brick"); - List chosenDisks = new ArrayList(); // or volume.getDisks(); + List chosenDevices = new ArrayList(); // or volume.getDisks(); - page = new BricksSelectionPage(parent, SWT.NONE, availableDisks, chosenDisks, volume.getName()); - page.addDiskSelectionListener(new ListContentChangedListener() { + page = new BricksSelectionPage(parent, SWT.NONE, availableDevices, chosenDevices, volume.getName()); + page.addDiskSelectionListener(new ListContentChangedListener() { @Override - public void listContentChanged(IRemovableContentProvider contentProvider) { - List newChosenDisks = page.getChosenDisks(); + public void listContentChanged(IRemovableContentProvider contentProvider) { + List newChosenDevices = page.getChosenDevices(); // validate chosen disks - if(isValidDiskSelection(newChosenDisks.size())) { + if(isValidDiskSelection(newChosenDevices.size())) { clearError(); } else { setError(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/BricksSelectionPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/BricksSelectionPage.java index db963b18..4ac01d14 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/BricksSelectionPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/BricksSelectionPage.java @@ -39,6 +39,7 @@ import org.eclipse.swt.widgets.Text; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Brick.BRICK_STATUS; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.IImageKeys; @@ -60,27 +61,27 @@ public class BricksSelectionPage extends Composite { "Total Space (GB)" }; private GUIHelper guiHelper = GUIHelper.getInstance(); - private CustomTableDualListComposite dualTableViewer; + private CustomTableDualListComposite dualTableViewer; private Text filterText; // This list keeps track of the order of the disks as user changes the same by clicking on up/down arrow buttons - private List chosenDisks = new ArrayList(); + private List chosenDevices = new ArrayList(); - private IRemovableContentProvider chosenBricksContentProvider; + private IRemovableContentProvider chosenBricksContentProvider; private Button btnUp; private Button btnDown; - public BricksSelectionPage(final Composite parent, int style, List allDisks, List selectedDisks, + public BricksSelectionPage(final Composite parent, int style, List allDevices, List selectedDevices, String volumeName) { super(parent, style); - createPage(allDisks, selectedDisks, volumeName); + createPage(allDevices, selectedDevices, volumeName); parent.layout(); } - public void addDiskSelectionListener(ListContentChangedListener listener) { + public void addDiskSelectionListener(ListContentChangedListener listener) { dualTableViewer.addChosenListChangedSelectionListener(listener); } @@ -114,13 +115,13 @@ public class BricksSelectionPage extends Composite { return -1; } - private void createPage(List allDisks, List selectedDisks, String volumeName) { + private void createPage(List allDevice, List selectedDevice, String volumeName) { setupPageLayout(); filterText = guiHelper.createFilterText(this); new Label(this, SWT.NONE); - createDualTableViewer(allDisks, selectedDisks, volumeName); + createDualTableViewer(allDevice, selectedDevice, volumeName); createFilter(filterText, false); // attach filter text to the dual table viewer for auto-filtering Composite buttonContainer = new Composite(this, SWT.NONE); @@ -138,17 +139,17 @@ public class BricksSelectionPage extends Composite { @Override public void widgetSelected(SelectionEvent e) { - chosenDisks = getChosenDisks(); - List selectedDisks = getSelectedChosenDisks(); - - chosenBricksContentProvider.removeElements(chosenDisks); - for (Disk disk : selectedDisks) { - int index = chosenDisks.indexOf(disk); - Disk diskAbove = chosenDisks.get(index - 1); - chosenDisks.set(index - 1, disk); - chosenDisks.set(index, diskAbove); + chosenDevices = getChosenDevices(); + List selectedDevices = getSelectedChosenDevices(); + + chosenBricksContentProvider.removeElements(chosenDevices); + for (Device device : selectedDevices) { + int index = chosenDevices.indexOf(device); + Device deviceAbove = chosenDevices.get(index - 1); + chosenDevices.set(index - 1, device); + chosenDevices.set(index, deviceAbove); } - chosenBricksContentProvider.addElements(chosenDisks); + chosenBricksContentProvider.addElements(chosenDevices); dualTableViewer.refreshChosenViewer(); updateButtons(); } @@ -162,17 +163,17 @@ public class BricksSelectionPage extends Composite { @Override public void widgetSelected(SelectionEvent e) { - chosenDisks = getChosenDisks(); - List selectedDisks = getSelectedChosenDisks(); + chosenDevices = getChosenDevices(); + List selectedDevices = getSelectedChosenDevices(); - chosenBricksContentProvider.removeElements(chosenDisks); - for (Disk disk : selectedDisks) { - int index = chosenDisks.indexOf(disk); - Disk diskBelow = chosenDisks.get(index + 1); - chosenDisks.set(index + 1, disk); - chosenDisks.set(index, diskBelow); + chosenBricksContentProvider.removeElements(chosenDevices); + for (Device disk : selectedDevices) { + int index = chosenDevices.indexOf(disk); + Device deviceBelow = chosenDevices.get(index + 1); + chosenDevices.set(index + 1, disk); + chosenDevices.set(index, deviceBelow); } - chosenBricksContentProvider.addElements(chosenDisks); + chosenBricksContentProvider.addElements(chosenDevices); dualTableViewer.refreshChosenViewer(); updateButtons(); @@ -180,13 +181,13 @@ public class BricksSelectionPage extends Composite { }); } - private List getSelectedChosenDisks() { + private List getSelectedChosenDevices() { TableItem[] selectedItems = dualTableViewer.getChosenTable().getSelection(); - List selectedDisks = new ArrayList(); + List selectedDevices = new ArrayList(); for (TableItem item : selectedItems) { - selectedDisks.add((Disk) item.getData()); + selectedDevices.add((Device) item.getData()); } - return selectedDisks; + return selectedDevices; } private void createFilter(final Text filterText, boolean caseSensitive) { @@ -219,24 +220,24 @@ public class BricksSelectionPage extends Composite { dualTableViewer.setChosenViewerFilter(filter); } - private void createDualTableViewer(List allDisks, List selectedDisks, String volumeName) { + private void createDualTableViewer(List allDevices, List selectedDevices, String volumeName) { TableColumnData[] columnData = createColumnData(); ITableLabelProvider diskLabelProvider = getDiskLabelProvider(volumeName); - dualTableViewer = new CustomTableDualListComposite(this, SWT.NONE, columnData, columnData); + dualTableViewer = new CustomTableDualListComposite(this, SWT.NONE, columnData, columnData); dualTableViewer.setViewerLabels("Available:", "Selected:"); dualTableViewer.setAvailableTableLinesVisible(false); dualTableViewer.setAvailableTableHeaderVisible(true); - dualTableViewer.setAvailableContentProvider(new RemovableContentProvider(getAvailableDisks(allDisks, - selectedDisks))); + dualTableViewer.setAvailableContentProvider(new RemovableContentProvider(getAvailableDevice(allDevices, + selectedDevices))); dualTableViewer.setAvailableLabelProvider(diskLabelProvider); dualTableViewer.setChosenTableLinesVisible(true); dualTableViewer.setChosenTableHeaderVisible(true); - chosenBricksContentProvider = new RemovableContentProvider(selectedDisks); + chosenBricksContentProvider = new RemovableContentProvider(selectedDevices); dualTableViewer.setChosenContentProvider(chosenBricksContentProvider); dualTableViewer.setChosenLabelProvider(diskLabelProvider); @@ -256,32 +257,32 @@ public class BricksSelectionPage extends Composite { private void updateButtons() { btnUp.setEnabled(true); btnDown.setEnabled(true); - List selectedChosenDisks = getSelectedChosenDisks(); - List chosenDisks = getChosenDisks(); - for (Disk disk : selectedChosenDisks) { - int index = chosenDisks.indexOf(disk); + List selectedChosenDevices = getSelectedChosenDevices(); + List chosenDevices = getChosenDevices(); + for (Device device : selectedChosenDevices) { + int index = chosenDevices.indexOf(device); if (index == 0) { btnUp.setEnabled(false); } - if (index == chosenDisks.size() - 1) { + if (index == chosenDevices.size() - 1) { btnDown.setEnabled(false); } } } /** - * @param allDisks - * @param selectedDisks + * @param allDevices + * @param selectedDevices * @return */ - private List getAvailableDisks(List allDisks, List selectedDisks) { - List availableDisks = new ArrayList(); - for (Disk disk : allDisks) { - if (!selectedDisks.contains(disk)) { - availableDisks.add(disk); + private List getAvailableDevice(List allDevices, List selectedDevices) { + List availableDevices = new ArrayList(); + for (Device device : allDevices) { + if (!selectedDevices.contains(device)) { + availableDevices.add(device); } } - return availableDisks; + return availableDevices; } private TableColumnData[] createColumnData() { @@ -304,14 +305,14 @@ public class BricksSelectionPage extends Composite { setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); } - public List getChosenDisks() { - Object[] disksArr = (Object[]) chosenBricksContentProvider.getElements(dualTableViewer); - if (disksArr != null) { - List disks = new ArrayList(); - for (Object disk : disksArr) { - disks.add((Disk) disk); + public List getChosenDevices() { + Object[] devicesArr = (Object[]) chosenBricksContentProvider.getElements(dualTableViewer); + if (devicesArr != null) { + List devices = new ArrayList(); + for (Object device : devicesArr) { + devices.add((Device) device); } - return disks; + return devices; } return null; } @@ -321,9 +322,9 @@ public class BricksSelectionPage extends Composite { if (bricksArr != null) { Set bricks = new HashSet(); - for (Object disk : bricksArr) { - bricks.add(new Brick(((Disk) disk).getServerName(), BRICK_STATUS.ONLINE, ((Disk) disk).getName(), - ((Disk) disk).getMountPoint() + "/" + volumeName)); // Assumption mount point is not having + for (Object device : bricksArr) { + bricks.add(new Brick(((Device) device).getServerName(), BRICK_STATUS.ONLINE, ((Device) device).getName(), + ((Device) device).getMountPoint() + "/" + volumeName)); // Assumption mount point is not having // trailing "/" } return bricks; 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 e7f46a66..cd2de837 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 @@ -49,6 +49,7 @@ import org.eclipse.swt.widgets.Text; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Brick.BRICK_STATUS; @@ -63,11 +64,11 @@ public class CreateVolumePage1 extends WizardPage { private ComboViewer typeComboViewer; private Text txtAccessControl; private Volume volume = new Volume(); - private List allDisks; private Button btnNfs; private Button btnStartVolume; private Link linkCustomize; - private List selectedDisks; + private List allDevices; + private List selectedDevices; /** * Create the wizard. @@ -78,8 +79,8 @@ public class CreateVolumePage1 extends WizardPage { setDescription("Create a new Volume by choosing bricks from the cluster servers and configuring the volume properties."); // by default, we create volume with all available disks - allDisks = GlusterDataModelManager.getInstance().getReadyDisksOfAllServers(); - selectedDisks = allDisks; // volume.setDisks(allDisks); + allDevices = GlusterDataModelManager.getInstance().getReadyDevicesOfAllServers(); + selectedDevices = allDevices; // volume.setDisks(allDisks); } private List getBricks(List allDisks) { @@ -195,13 +196,13 @@ public class CreateVolumePage1 extends WizardPage { @Override public void run() { - SelectDisksDialog dialog = new SelectDisksDialog(getShell(), allDisks, selectedDisks, txtName.getText().trim()); + SelectDisksDialog dialog = new SelectDisksDialog(getShell(), allDevices, selectedDevices, txtName.getText().trim()); dialog.create(); if(dialog.open() == Window.OK) { // user has customized disks. get them from the dialog box. - selectedDisks = dialog.getSelectedDisks(); - linkCustomize.setText("" + selectedDisks.size() + " Brick(s) (customize)"); + selectedDevices = dialog.getSelectedDevices(); + linkCustomize.setText("" + selectedDevices.size() + " Brick(s) (customize)"); validateForm(); } } @@ -306,8 +307,8 @@ public class CreateVolumePage1 extends WizardPage { volume.setAccessControlList(txtAccessControl.getText()); - for(Disk disk : selectedDisks) { - Brick brick = new Brick(disk.getServerName(), BRICK_STATUS.ONLINE, disk.getName(), disk.getMountPoint() + File.separator + volume.getName()); + for(Device device : selectedDevices) { + Brick brick = new Brick(device.getServerName(), BRICK_STATUS.ONLINE, device.getName(), device.getMountPoint() + File.separator + volume.getName()); volume.addBrick(brick); } @@ -337,7 +338,7 @@ public class CreateVolumePage1 extends WizardPage { } private void validateDisks() { - int diskCount = selectedDisks.size(); + int diskCount = selectedDevices.size(); if(diskCount < 1) { setError("At least one brick must be selected!"); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateBrickPage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateBrickPage1.java index f7ce744f..f8fce5e4 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateBrickPage1.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateBrickPage1.java @@ -45,6 +45,7 @@ import org.eclipse.swt.widgets.Text; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Brick; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.utils.NumberUtil; @@ -209,15 +210,15 @@ public class MigrateBrickPage1 extends WizardPage { ITableLabelProvider diskLabelProvider = getDiskLabelProvider(volume.getName()); GlusterDataModelManager glusterDataModelManager = GlusterDataModelManager.getInstance(); - List fromBricks = glusterDataModelManager.getReadyDisksOfVolume(volume); - List toDisks = glusterDataModelManager.getReadyDisksOfAllServersExcluding( fromBricks ); + List fromBricks = glusterDataModelManager.getReadyDevicesOfVolume(volume); + List toDevices = glusterDataModelManager.getReadyDevicesOfAllServersExcluding( fromBricks ); tableViewerFrom = createTableViewer(container, diskLabelProvider, fromBricks, txtFilterFrom); if(fromBrick != null) { setFromDisk(tableViewerFrom, fromBrick); } - tableViewerTo = createTableViewer(container, diskLabelProvider, toDisks, txtFilterTo); + tableViewerTo = createTableViewer(container, diskLabelProvider, toDevices, txtFilterTo); // Auto commit selection field Composite autoCommitContainer = new Composite(container, SWT.NONE); @@ -251,7 +252,7 @@ public class MigrateBrickPage1 extends WizardPage { } private TableViewer createTableViewer(Composite container, ITableLabelProvider diskLabelProvider, - List bricks, Text txtFilterText) { + List bricks, Text txtFilterText) { Composite tableViewerComposite = createTableViewerComposite(container); TableViewer tableViewer = new TableViewer(tableViewerComposite, SWT.SINGLE); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java index e010ed5c..f939e12d 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java @@ -33,13 +33,13 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import com.gluster.storage.management.core.model.Brick; -import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Device; public class SelectDisksDialog extends Dialog { private BricksSelectionPage disksPage; - private List allDisks; - private List selectedDisks; + private List allDevices; + private List selectedDevices; private String volumeName; /** @@ -47,11 +47,11 @@ public class SelectDisksDialog extends Dialog { * * @param parentShell */ - public SelectDisksDialog(Shell parentShell, List allDisks, List selectedDisks, String volumeName) { + public SelectDisksDialog(Shell parentShell, List allDevices, List selectedDevices, String volumeName) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); - this.allDisks = allDisks; - this.selectedDisks = selectedDisks; + this.allDevices = allDevices; + this.selectedDevices = selectedDevices; this.volumeName = volumeName; } @@ -70,7 +70,7 @@ public class SelectDisksDialog extends Dialog { getShell().setText("Create Volume - Select Bricks"); - disksPage = new BricksSelectionPage(container, SWT.NONE, allDisks, selectedDisks, volumeName); + disksPage = new BricksSelectionPage(container, SWT.NONE, allDevices, selectedDevices, volumeName); return container; } @@ -101,15 +101,15 @@ public class SelectDisksDialog extends Dialog { @Override protected void okPressed() { - if (this.getSelectedDisks().size() == 0) { + if (this.getSelectedDevices().size() == 0) { MessageDialog.openError(getShell(), "Select Brick(s)", "Please select atlease one brick"); } else { super.okPressed(); } } - public List getSelectedDisks() { - return disksPage.getChosenDisks(); + public List getSelectedDevices() { + return disksPage.getChosenDevices(); } public Set getSelectedBricks(String volumeName) { 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 d6fd5d03..c4ddc31b 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 @@ -46,6 +46,7 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; @@ -249,6 +250,9 @@ public class GUIHelper { // Refresh viewer with newly filtered content viewer.refresh(true); + if(viewer instanceof TreeViewer) { + ((TreeViewer)viewer).expandAll(); + } } }); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java index 0910c080..2d4a3036 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java @@ -19,6 +19,7 @@ public class DisksView extends ViewPart { private EntityGroup servers; private DisksPage page; + @SuppressWarnings("unchecked") @Override public void createPartControl(Composite parent) { if (servers == null) { 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 d3eb7f6c..8c4d2572 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 @@ -419,7 +419,7 @@ public class VolumeSummaryView extends ViewPart { private double getTotalDiskSpace() { double diskSize = 0; for (Brick brick : volume.getBricks()) { - diskSize += getDiskSize(brick.getServerName(), brick.getDiskName()); + diskSize += getDiskSize(brick.getServerName(), brick.getDeviceName()); } return diskSize; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java index d58394e2..966f8921 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractDisksPage.java @@ -22,20 +22,18 @@ import java.net.URI; import java.util.List; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.IContentProvider; -import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.custom.TreeEditor; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; @@ -44,8 +42,7 @@ import org.eclipse.ui.forms.widgets.ImageHyperlink; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.client.TasksClient; -import com.gluster.storage.management.core.model.ClusterListener; -import com.gluster.storage.management.core.model.DefaultClusterListener; +import com.gluster.storage.management.core.model.Device; import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Entity; @@ -54,8 +51,8 @@ import com.gluster.storage.management.gui.Application; import com.gluster.storage.management.gui.IEntityListener; import com.gluster.storage.management.gui.dialogs.InitializeDiskTypeSelection; -public abstract class AbstractDisksPage extends AbstractTableViewerPage implements IEntityListener { - private List disks; +public abstract class AbstractDisksPage extends AbstractTableTreeViewerPage implements IEntityListener { + protected List disks; /** * @return Index of the "status" column in the table. Return -1 if status column is not displayed @@ -63,7 +60,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im protected abstract int getStatusColumnIndex(); public AbstractDisksPage(final Composite parent, int style, IWorkbenchSite site, List disks) { - super(site, parent, style, true, true, disks); + super(site, parent, style, false, true, disks); this.disks = disks; // creates hyperlinks for "unitialized" disks @@ -72,45 +69,30 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im Application.getApplication().addEntityListener(this); } - @Override - protected IContentProvider getContentProvider() { - return new ArrayContentProvider(); - } - - @Override - protected List getAllEntities() { - return disks; - } - - @Override - protected ClusterListener createClusterListener() { - return new DefaultClusterListener(); - } - - private void createInitializeLink(final TableItem item, final int rowNum, final Disk disk) { - final Table table = tableViewer.getTable(); - final TableEditor editor = new TableEditor(table); + private void createInitializeLink(final TreeItem item, final int rowNum, final Device device) { + final Tree tree = treeViewer.getTree(); // .getTableTree(); + final TreeEditor editor = new TreeEditor(tree); editor.grabHorizontal = true; editor.horizontalAlignment = SWT.RIGHT; - table.addPaintListener(new PaintListener() { - private TableItem myItem = item; + tree.addPaintListener(new PaintListener() { + private TreeItem myItem = item; private int myRowNum = rowNum; private ImageHyperlink myLink = null; - private TableEditor myEditor = null; + private TreeEditor myEditor = null; - private void createLinkFor(Disk disk1, TableItem item1, int rowNum1) { + private void createLinkFor(Device device, TreeItem item1, int rowNum1) { myItem = item1; myRowNum = rowNum1; - myEditor = new TableEditor(table); + myEditor = new TreeEditor(tree); myEditor.grabHorizontal = true; myEditor.horizontalAlignment = SWT.RIGHT; - myLink = toolkit.createImageHyperlink(table, SWT.NONE); + myLink = toolkit.createImageHyperlink(tree, SWT.NONE); // link.setImage(guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED)); myLink.setText("Initialize"); - myLink.addHyperlinkListener(new StatusLinkListener(myLink, myEditor, myItem, tableViewer, disk1)); + myLink.addHyperlinkListener(new StatusLinkListener(myLink, myEditor, treeViewer, device)); myEditor.setEditor(myLink, item1, getStatusColumnIndex()); @@ -125,16 +107,16 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im @Override public void paintControl(PaintEvent e) { - int itemCount = table.getItemCount(); + int itemCount = tree.getItemCount(); // Find the table item corresponding to our disk - Disk disk1 = null; + Device device1 = null; int rowNum1 = -1; - TableItem item1 = null; + TreeItem item1 = null; for (int i = 0; i < itemCount; i++) { - item1 = table.getItem(i); - disk1 = (Disk) item1.getData(); - if (disk1 != null && disk1 == disk) { + item1 = tree.getItem(i); + device1 = (Device) item1.getData(); + if (device1 != null && device1 == device) { rowNum1 = i; break; } @@ -149,14 +131,14 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im // item visible, and // either editor never created, OR // old item disposed. create the link for it - createLinkFor(disk1, item1, rowNum1); + createLinkFor(device1, item1, rowNum1); } if (rowNum1 != myRowNum) { // disk visible, but at a different row num. re-create the link myLink.dispose(); myEditor.dispose(); - createLinkFor(disk1, item1, rowNum1); + createLinkFor(device1, item1, rowNum1); } myEditor.layout(); // IMPORTANT. Without this, the link location goes for a toss on maximize + restore @@ -165,29 +147,28 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im } private void setupStatusCellEditor() { - final TableViewer viewer = tableViewer; - final Table table = viewer.getTable(); - for (int i = 0; i < table.getItemCount(); i++) { - final TableItem item = table.getItem(i); + final TreeViewer viewer = treeViewer; + final Tree tree = viewer.getTree(); + for (int i = 0; i < tree.getItemCount(); i++) { + final TreeItem item = tree.getItem(i); if (item.isDisposed() || item.getData() == null) { continue; } - final Disk disk = (Disk) item.getData(); - if (disk.isUninitialized()) { - createInitializeLink(item, i, disk); + final Device device = (Device) item.getData(); + if (device.isUninitialized()) { + createInitializeLink(item, i, device); } } } private final class StatusLinkListener extends HyperlinkAdapter { - private final Disk disk; - private final TableEditor myEditor; + private final Device device; + private final TreeEditor myEditor; private final ImageHyperlink myLink; - private final TableViewer viewer; + private final TreeViewer viewer; - private StatusLinkListener(ImageHyperlink link, TableEditor editor, TableItem item, TableViewer viewer, - Disk disk) { - this.disk = disk; + private StatusLinkListener(ImageHyperlink link, TreeEditor editor, TreeViewer viewer, Device device) { + this.device = device; this.viewer = viewer; this.myEditor = editor; this.myLink = link; @@ -198,9 +179,9 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im myLink.dispose(); myEditor.dispose(); } - disk.setStatus(status); - viewer.update(disk, new String[] { "status" }); - Application.getApplication().entityChanged(disk, new String[] { "status" }); + device.setStatus(status); + viewer.update(device, new String[] { "status" }); + Application.getApplication().entityChanged(device, new String[] { "status" }); } @Override @@ -214,7 +195,7 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im GlusterServersClient serversClient = new GlusterServersClient(); try { - URI uri = serversClient.initializeDisk(disk.getServerName(), disk.getName(), formatDialog.getFSType()); + URI uri = serversClient.initializeDisk(device.getServerName(), device.getName(), formatDialog.getFSType()); TasksClient taskClient = new TasksClient(); TaskInfo taskInfo = taskClient.getTaskInfo(uri); @@ -230,22 +211,22 @@ public abstract class AbstractDisksPage extends AbstractTableViewerPage im @Override public void entityChanged(final Entity entity, final String[] paremeters) { - if (!(entity instanceof Disk)) { + if (!(entity instanceof Device)) { return; } - final Disk disk = (Disk) entity; + final Device device = (Device) entity; Display.getDefault().syncExec(new Runnable() { public void run() { - tableViewer.update(disk, paremeters); - - if (disk.isUninitialized()) { - Table table = tableViewer.getTable(); - - for (int rowNum = 0; rowNum < table.getItemCount(); rowNum++) { - TableItem item = table.getItem(rowNum); - if (item.getData() == disk) { - createInitializeLink(item, rowNum, disk); + treeViewer.update(device, paremeters); + + if (device.isUninitialized()) { + Tree tree = treeViewer.getTree(); + + for (int rowNum = 0; rowNum < tree.getItemCount(); rowNum++) { + TreeItem item = tree.getItem(rowNum); + if (item.getData() == device) { + createInitializeLink(item, rowNum, device); } } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java new file mode 100644 index 00000000..05a74b03 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.gui.views.pages; + +import java.util.List; + +import org.eclipse.jface.layout.TreeColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.Hyperlink; + +import com.gluster.storage.management.core.model.ClusterListener; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public abstract class AbstractTableTreeViewerPage extends Composite implements ISelectionListener { + + + protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + protected TreeViewer treeViewer; + protected GUIHelper guiHelper = GUIHelper.getInstance(); + protected Composite parent; + protected IWorkbenchSite site; + + private Text filterText; + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private Composite createTreeViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + GridData layoutData = new GridData(); + layoutData.horizontalSpan=5; + layoutData.grabExcessHorizontalSpace = true; + layoutData.horizontalAlignment = SWT.FILL; + layoutData.verticalAlignment = SWT.FILL; + layoutData.grabExcessVerticalSpace = true; + tableViewerComposite.setLayoutData(layoutData); + + return tableViewerComposite; + } + + + public AbstractTableTreeViewerPage(IWorkbenchSite site, final Composite parent, int style, boolean useChechboxes, + boolean multiSelection, List allDisks) { + super(parent, style); + + setupPageLayout(); + //new FormToolkit(Display.getCurrent()).createButton(this, "test1", SWT.PUSH); + + this.parent = parent; + this.site = site; + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + parent.setLayoutData(data); + + filterText = guiHelper.createFilterText(toolkit, this); + + Composite tableViewerComposite = createTreeViewerComposite(); + createTreeViewer(allDisks, tableViewerComposite); + parent.layout(); + } + + protected abstract IBaseLabelProvider getLabelProvider(); + protected abstract IContentProvider getContentProvider(); + + private void createTreeViewer(List allDisks, Composite tableViewerComposite) { + treeViewer = new TreeViewer(tableViewerComposite); + treeViewer.getTree().setHeaderVisible(true); + treeViewer.getTree().setLinesVisible(true); + + TreeColumnLayout ad = new TreeColumnLayout(); + tableViewerComposite.setLayout(ad); + + TreeColumn column = new TreeColumn(treeViewer.getTree(),SWT.NONE); + column.setWidth(100); + column.setText("Disk"); + ad.setColumnData(column, new ColumnWeightData(50, 100)); + + column = new TreeColumn(treeViewer.getTree(),SWT.NONE); + column.setWidth(100); + column.setText("Partition"); + ad.setColumnData(column,new ColumnWeightData(50, 100)); + + column = new TreeColumn(treeViewer.getTree(),SWT.NONE); + column.setWidth(100); + column.setText("Free Space (GB)"); + ad.setColumnData(column, new ColumnWeightData(50, 100)); + + column = new TreeColumn(treeViewer.getTree(),SWT.NONE); + column.setWidth(100); + column.setText("Total Space (GB)"); + ad.setColumnData(column,new ColumnWeightData(50, 100)); + + column = new TreeColumn(treeViewer.getTree(),SWT.NONE); + column.setWidth(100); + column.setText("Status"); + ad.setColumnData(column,new ColumnWeightData(50, 100)); + + treeViewer.setLabelProvider(getLabelProvider()); + treeViewer.setContentProvider(getContentProvider()); + treeViewer.setInput(allDisks); + + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(treeViewer, filterText, false); + + treeViewer.expandAll(); + } + + + /* (non-Javadoc) + * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + } + + protected ClusterListener createClusterListener() { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DiskTreeContentProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DiskTreeContentProvider.java new file mode 100644 index 00000000..c5158087 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DiskTreeContentProvider.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.gui.views.pages; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Partition; + +public class DiskTreeContentProvider implements ITreeContentProvider { + + private List disks = new ArrayList(); + + public DiskTreeContentProvider(List disks) { + this.disks = disks; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return ((List) inputElement).toArray(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parentElement) { + if(parentElement instanceof Disk) { + return ((Disk)parentElement).getPartitions().toArray(); + } else { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == null) { + return null; + } + + if(element instanceof Partition) { + // find the disk of this partition and return + return getDiskForPartition((Partition)element); + } else { + return null; + } + } + + private Disk getDiskForPartition(Partition partition) { + for(Disk disk : disks) { + for(Partition diskPartition : disk.getPartitions()) { + if(partition.getName().equals(diskPartition.getName())) { + return disk; + } + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if(element instanceof Disk && ((Disk)element).getPartitions().size() > 0) { + return true; + } else { + return false; + } + } + + + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java index bd14607e..c8cf8028 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/DisksPage.java @@ -20,49 +20,51 @@ package com.gluster.storage.management.gui.views.pages; import java.util.List; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.swt.SWT; +import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; import org.eclipse.ui.IWorkbenchSite; import com.gluster.storage.management.core.model.Disk; -import com.gluster.storage.management.gui.DiskTableLabelProvider; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.gui.DeviceTableLabelProvider; public class DisksPage extends AbstractDisksPage { public enum DISK_TABLE_COLUMN_INDICES { - SERVER, DISK, FREE_SPACE, TOTAL_SPACE, STATUS + DISK, PARTITION, FREE_SPACE, TOTAL_SPACE, STATUS }; - private static final String[] DISK_TABLE_COLUMN_NAMES = new String[] { "Server", "Disk", "Free Space (GB)", + private static final String[] DISK_TABLE_COLUMN_NAMES = new String[] { "Disk", "Partition", "Free Space (GB)", "Total Space (GB)", "Status" }; public DisksPage(final Composite parent, int style, IWorkbenchSite site, List disks) { super(parent, style, site, disks); } - @Override - protected String[] getColumnNames() { - return DISK_TABLE_COLUMN_NAMES; + private String getDiskTableColumnDesc(DISK_TABLE_COLUMN_INDICES idx) { + return DISK_TABLE_COLUMN_NAMES[idx.ordinal()]; } - + @Override - protected void setColumnProperties(Table table) { - guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SERVER.ordinal(), SWT.CENTER, 100); - guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.DISK.ordinal(), SWT.CENTER, 100); - guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal(), SWT.CENTER, 90); - guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal(), SWT.CENTER, 90); - // guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal(), SWT.CENTER, 90); + protected DeviceTableLabelProvider getLabelProvider() { + return new DeviceTableLabelProvider(); } + @Override - protected IBaseLabelProvider getLabelProvider() { - return new DiskTableLabelProvider(); + protected IContentProvider getContentProvider() { + return new DiskTreeContentProvider(disks); } @Override protected int getStatusColumnIndex() { return DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(); } + + @Override + public void entityChanged(Entity entity, String[] paremeters) { + // TODO Auto-generated method stub + + } + } \ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java index b993f73e..2428a1a0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServerDisksPage.java @@ -20,47 +20,47 @@ package com.gluster.storage.management.gui.views.pages; import java.util.List; -import org.eclipse.jface.viewers.IBaseLabelProvider; -import org.eclipse.swt.SWT; +import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; import org.eclipse.ui.IWorkbenchSite; import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Entity; import com.gluster.storage.management.gui.ServerDiskTableLabelProvider; -public class ServerDisksPage extends AbstractDisksPage { +public class ServerDisksPage extends AbstractDisksPage { + public ServerDisksPage(Composite parent, int style, IWorkbenchSite site, List disks) { super(parent, style, site, disks); } public enum SERVER_DISK_TABLE_COLUMN_INDICES { - DISK, FREE_SPACE, TOTAL_SPACE, STATUS + DISK, PARTITION, FREE_SPACE, TOTAL_SPACE, STATUS }; - private static final String[] SERVER_DISK_TABLE_COLUMN_NAMES = new String[] { "Disk", "Free Space (GB)", + private static final String[] SERVER_DISK_TABLE_COLUMN_NAMES = new String[] { "Disk", "Partition", "Free Space (GB)", "Total Space (GB)", "Status" }; @Override - protected String[] getColumnNames() { - return SERVER_DISK_TABLE_COLUMN_NAMES; + protected int getStatusColumnIndex() { + return SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(); } - + @Override - protected void setColumnProperties(Table table) { - guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK.ordinal(), SWT.CENTER, 100); - guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.FREE_SPACE.ordinal(), SWT.CENTER, 90); - guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.TOTAL_SPACE.ordinal(), SWT.CENTER, 90); - guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(), SWT.LEFT, 90); + protected ServerDiskTableLabelProvider getLabelProvider() { + // return new DeviceTableLabelProvider(); + return new ServerDiskTableLabelProvider(); } + @Override - protected int getStatusColumnIndex() { - return SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(); + protected IContentProvider getContentProvider() { + return new DiskTreeContentProvider(disks); } @Override - protected IBaseLabelProvider getLabelProvider() { - return new ServerDiskTableLabelProvider(); + public void entityChanged(Entity entity, String[] paremeters) { + // TODO Auto-generated method stub + } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java index 43708239..a5f366a2 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java @@ -152,12 +152,10 @@ public class GlusterServersResource extends AbstractServersResource { String errMsg = ""; for (GlusterServer server : glusterServers) { - if (server.getStatus() == SERVER_STATUS.ONLINE && !server.getName().equals(onlineServer.getName())) { - try { - fetchServerDetails(server); - } catch (Exception e) { - errMsg += CoreConstants.NEWLINE + server.getName() + " : [" + e.getMessage() + "]"; - } + try { + fetchServerDetails(server); + } catch (Exception e) { + errMsg += CoreConstants.NEWLINE + server.getName() + " : [" + e.getMessage() + "]"; } } return errMsg; -- cgit From 4290f5519fb7480df6c5919583efc1f7feebf4b3 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Tue, 12 Jul 2011 23:16:54 +0530 Subject: Story #38 - CPU Usage graph --- .../management/core/constants/RESTConstants.java | 6 + .../storage/management/core/model/ServerStats.java | 73 ++++ .../management/core/model/ServerStatsRow.java | 69 ++++ .../management/core/model/StatsMetadata.java | 84 +++++ .../rootfiles/gluster-management-console.jnlp | 5 + .../feature.xml | 4 +- .../management/gui/utils/ChartViewerComposite.java | 393 +++++++++++++++++++++ .../gui/utils/PieChartViewerComposite.java | 260 -------------- .../management/gui/views/ClusterSummaryView.java | 107 +++--- .../gui/views/GlusterServerSummaryView.java | 28 +- .../gui/views/GlusterServersSummaryView.java | 6 +- .../management/gui/views/VolumesSummaryView.java | 6 +- .../views/pages/AbstractTableTreeViewerPage.java | 2 - .../WebContent/WEB-INF/web.xml | 18 +- .../resources/v1_0/GenericExceptionMapper.java | 45 +++ .../resources/v1_0/GlusterServersResource.java | 160 ++++++--- .../resources/v1_0/ValidationExceptionMapper.java | 39 ++ .../management/server/utils/ServerUtil.java | 106 ++++++ 18 files changed, 1032 insertions(+), 379 deletions(-) create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStats.java create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStatsRow.java create mode 100644 src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/StatsMetadata.java create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ChartViewerComposite.java delete mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/PieChartViewerComposite.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GenericExceptionMapper.java create mode 100644 src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/ValidationExceptionMapper.java (limited to 'src') 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 455ecc11..d4b0e43a 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 @@ -42,6 +42,7 @@ public class RESTConstants { public static final String RESOURCE_SERVERS = "servers"; public static final String RESOURCE_TASKS = "tasks"; public static final String RESOURCE_KEYS = "keys"; + public static final String RESOURCE_STATISTICS = "statistics"; public static final String TASK_START = "start"; public static final String TASK_PAUSE = "pause"; @@ -98,6 +99,11 @@ public class RESTConstants { public static final String QUERY_PARAM_DOWNLOAD = "download"; public static final String QUERY_PARAM_SERVER_NAME = "serverName"; public static final String QUERY_PARAM_DETAILS = "details"; + public static final String QUERY_PARAM_TYPE = "type"; + + public static final String STATISTICS_TYPE_CPU = "cpu"; + public static final String STATISTICS_TYPE_NETWORK = "network"; + public static final String STATISTICS_TYPE_MEMORY = "memory"; public static final String FORMAT_XML = "xml"; public static final String FORMAT_JSON = "json"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStats.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStats.java new file mode 100644 index 00000000..042af256 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStats.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + */ +@XmlRootElement(name="xport") +public class ServerStats { + private StatsMetadata metadata; + private List rows; + + public ServerStats() { + } + + public ServerStats(ServerStats newStats) { + copyFrom(newStats); + } + + public void setRows(List rows) { + this.rows = rows; + } + + @XmlElementWrapper(name="data") + @XmlElement(name="row", type=ServerStatsRow.class) + public List getRows() { + return rows; + } + + public void setMetadata(StatsMetadata metadata) { + this.metadata = metadata; + } + + @XmlElement(name="meta") + public StatsMetadata getMetadata() { + return metadata; + } + + public void copyFrom(ServerStats newStats) { + setMetadata(newStats.getMetadata()); + + List newRows = newStats.getRows(); + int rowCount = newRows.size(); + + rows = new ArrayList(rowCount); + for(ServerStatsRow newRow : newRows) { + rows.add(new ServerStatsRow(newRow)); + } + } +} \ No newline at end of file diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStatsRow.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStatsRow.java new file mode 100644 index 00000000..0088cef6 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ServerStatsRow.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + */ +@XmlRootElement(name="row") +public class ServerStatsRow { + private Long timestamp; + private List usageData; + + public ServerStatsRow() { + } + + public ServerStatsRow(ServerStatsRow newRow) { + copyFrom(newRow); + } + + private void copyFrom(ServerStatsRow newRow) { + setTimestamp(newRow.getTimestamp()); + + List myData = new ArrayList(newRow.getUsageData().size()); + for(Double dataElement : newRow.getUsageData()) { + myData.add(dataElement); + } + setUsageData(myData); + } + + @XmlElement(name="t") + public Long getTimestamp() { + return timestamp; + } + + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } + + public void setUsageData(List usageData) { + this.usageData = usageData; + } + + @XmlElement(name="v") + public List getUsageData() { + return usageData; + } +} diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/StatsMetadata.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/StatsMetadata.java new file mode 100644 index 00000000..22b42671 --- /dev/null +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/StatsMetadata.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.core.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + */ +@XmlRootElement(name="meta") +public class StatsMetadata { + private Long startTimestamp; + private Long endTimestamp; + private Integer step; + private Integer rowCount; + private List legend = new ArrayList(); + + @XmlElement(name="start") + public Long getStartTimestamp() { + return startTimestamp; + } + + public void setStartTimestamp(Long startTimestamp) { + this.startTimestamp = startTimestamp; + } + + @XmlElement(name="end") + public Long getEndTimestamp() { + return endTimestamp; + } + + public void setEndTimestamp(Long endTimestamp) { + this.endTimestamp = endTimestamp; + } + + @XmlElement(name="step") + public Integer getStep() { + return step; + } + + public void setStep(Integer step) { + this.step = step; + } + + @XmlElement(name="rows") + public Integer getRowCount() { + return rowCount; + } + + public void setRowCount(Integer rowCount) { + this.rowCount = rowCount; + } + + @XmlElementWrapper(name="legend") + @XmlElement(name="entry", type=String.class) + public List getLegend() { + return legend; + } + + public void setLegend(List legend) { + this.legend = legend; + } +} diff --git a/src/com.gluster.storage.management.gui.feature.webstart/rootfiles/gluster-management-console.jnlp b/src/com.gluster.storage.management.gui.feature.webstart/rootfiles/gluster-management-console.jnlp index c99eece8..597adf4c 100644 --- a/src/com.gluster.storage.management.gui.feature.webstart/rootfiles/gluster-management-console.jnlp +++ b/src/com.gluster.storage.management.gui.feature.webstart/rootfiles/gluster-management-console.jnlp @@ -6,6 +6,11 @@ Gluster Management Console + + + + + diff --git a/src/com.gluster.storage.management.gui.feature/feature.xml b/src/com.gluster.storage.management.gui.feature/feature.xml index 0f0c9e8b..7f526f72 100644 --- a/src/com.gluster.storage.management.gui.feature/feature.xml +++ b/src/com.gluster.storage.management.gui.feature/feature.xml @@ -538,7 +538,7 @@ id="org.eclipse.core.net.win32.x86_64" os="win32" ws="win32" - arch="x86_64" + arch="x86_64, amd64" download-size="0" install-size="0" version="0.0.0" @@ -609,7 +609,7 @@ + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.gui.utils; + +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.birt.chart.api.ChartEngine; +import org.eclipse.birt.chart.device.IDeviceRenderer; +import org.eclipse.birt.chart.device.IUpdateNotifier; +import org.eclipse.birt.chart.exception.ChartException; +import org.eclipse.birt.chart.factory.GeneratedChartState; +import org.eclipse.birt.chart.factory.Generator; +import org.eclipse.birt.chart.model.Chart; +import org.eclipse.birt.chart.model.ChartWithAxes; +import org.eclipse.birt.chart.model.ChartWithoutAxes; +import org.eclipse.birt.chart.model.attribute.Anchor; +import org.eclipse.birt.chart.model.attribute.AxisType; +import org.eclipse.birt.chart.model.attribute.Bounds; +import org.eclipse.birt.chart.model.attribute.ChartDimension; +import org.eclipse.birt.chart.model.attribute.FontDefinition; +import org.eclipse.birt.chart.model.attribute.LineAttributes; +import org.eclipse.birt.chart.model.attribute.LineStyle; +import org.eclipse.birt.chart.model.attribute.Marker; +import org.eclipse.birt.chart.model.attribute.TickStyle; +import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl; +import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl; +import org.eclipse.birt.chart.model.attribute.impl.FontDefinitionImpl; +import org.eclipse.birt.chart.model.attribute.impl.JavaDateFormatSpecifierImpl; +import org.eclipse.birt.chart.model.attribute.impl.LineAttributesImpl; +import org.eclipse.birt.chart.model.attribute.impl.TextAlignmentImpl; +import org.eclipse.birt.chart.model.component.Axis; +import org.eclipse.birt.chart.model.component.Series; +import org.eclipse.birt.chart.model.component.impl.SeriesImpl; +import org.eclipse.birt.chart.model.data.DateTimeDataSet; +import org.eclipse.birt.chart.model.data.NumberDataSet; +import org.eclipse.birt.chart.model.data.SeriesDefinition; +import org.eclipse.birt.chart.model.data.TextDataSet; +import org.eclipse.birt.chart.model.data.impl.DateTimeDataSetImpl; +import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl; +import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl; +import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl; +import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl; +import org.eclipse.birt.chart.model.impl.ChartWithoutAxesImpl; +import org.eclipse.birt.chart.model.layout.Legend; +import org.eclipse.birt.chart.model.layout.Plot; +import org.eclipse.birt.chart.model.type.AreaSeries; +import org.eclipse.birt.chart.model.type.LineSeries; +import org.eclipse.birt.chart.model.type.PieSeries; +import org.eclipse.birt.chart.model.type.impl.AreaSeriesImpl; +import org.eclipse.birt.chart.model.type.impl.LineSeriesImpl; +import org.eclipse.birt.chart.model.type.impl.PieSeriesImpl; +import org.eclipse.birt.core.framework.PlatformConfig; +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +import com.ibm.icu.util.Calendar; + +/** + * + */ +public final class ChartViewerComposite extends Composite implements PaintListener, IUpdateNotifier { + + public enum CHART_TYPE { + PIE, LINE + }; + + private IDeviceRenderer deviceReader = null; + private Chart chart = null; + private GeneratedChartState generatedChartState = null; + private boolean needsGeneration = true; + + private static Logger logger = Logger.getLogger(ChartViewerComposite.class.getName()); + + /** + * @param parent + * Parent composite of this pie chart viewer composite + * @param style + * SWT style to be used + * @param categories + * Categories of the pie chart + * @param values + * Values of each category in the pie chart Constructs a pie + * chart viewer composite for given categories and values + */ + public ChartViewerComposite(Composite parent, int style, String[] categories, Double[] values) { + super(parent, style); + init(); + + chart = createPieChart(categories, values); + addPaintListener(this); + } + + /** + * @param parent + * Parent composite of this pie chart viewer composite + * @param style + * SWT style to be used + * @param categories + * Categories of the pie chart + * @param values + * Values of each category in the pie chart Constructs a pie + * chart viewer composite for given categories and values + */ + public ChartViewerComposite(Composite parent, int style, Calendar[] categories, Double[] values) { + super(parent, style); + init(); + + chart = createLineChart(categories, values); + addPaintListener(this); + } + + public void init() { + try { + PlatformConfig config = new PlatformConfig(); + config.setBIRTHome(Platform.getInstallLocation().getURL().getPath()); + // Get the connection with SWT device to render the graphics. + deviceReader = ChartEngine.instance(config).getRenderer("dv.SWT");//$NON-NLS-1$ + } catch (ChartException ex) { + logger.log(Level.SEVERE, "Could not create Chart Renderer for SWT", ex); + } + + addControlListener(new ControlListener() { + + public void controlMoved(ControlEvent e) { + needsGeneration = true; + } + + public void controlResized(ControlEvent e) { + needsGeneration = true; + } + }); + } + + private Chart createLineChart(Calendar[] timestamps, Double[] values) { + return createAreaChart(timestamps, new Double[][] {values}); + } + + /** + * Creates a line chart model as a reference implementation + * + * @return An instance of the simulated runtime chart model (containing + * filled datasets) + */ + public static final Chart createAreaChart(Calendar[] timestamps, Double[][] values) { + ChartWithAxes cwaLine = ChartWithAxesImpl.create(); + + // Plot + cwaLine.getBlock().setBackground(ColorDefinitionImpl.TRANSPARENT()); + Plot p = cwaLine.getPlot(); + p.getClientArea().setBackground(ColorDefinitionImpl.TRANSPARENT()); + //p.getClientArea().setBackground(ColorDefinitionImpl.TRANSPARENT()); + + + // Title + //cwaLine.getTitle().getLabel().getCaption().setValue("Line Chart");//$NON-NLS-1$ + cwaLine.getTitle().setVisible(false); + + // Legend + cwaLine.getLegend().setVisible(false); + Legend lg = cwaLine.getLegend(); + LineAttributes lia = lg.getOutline( ); + lg.getText( ).getFont( ).setSize( 16 ); + lia.setStyle( LineStyle.SOLID_LITERAL ); + lg.getInsets( ).set( 10, 5, 0, 0 ); + lg.getOutline( ).setVisible( false ); + lg.setAnchor( Anchor.NORTH_LITERAL ); + + // X-Axis + Axis xAxisPrimary = cwaLine.getPrimaryBaseAxes()[0]; + xAxisPrimary.setType(AxisType.TEXT_LITERAL); + xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL); + xAxisPrimary.getMajorGrid().setLineAttributes(LineAttributesImpl.create(ColorDefinitionImpl.GREY(), LineStyle.DOTTED_LITERAL, 1)); + xAxisPrimary.getTitle().setVisible(false); + xAxisPrimary.setInterval(4); + xAxisPrimary.getLabel().getCaption().setFont(createChartFont()); + xAxisPrimary.setFormatSpecifier( JavaDateFormatSpecifierImpl.create( "HH:mm" ) ); + + // Y-Axis + Axis yAxisPrimary = cwaLine.getPrimaryOrthogonalAxis(xAxisPrimary); + yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL); + yAxisPrimary.getMajorGrid().setLineAttributes(LineAttributesImpl.create(ColorDefinitionImpl.GREY(), LineStyle.SOLID_LITERAL, 1)); + yAxisPrimary.setInterval(2); + yAxisPrimary.getLabel().setVisible(true); + yAxisPrimary.getLabel().getCaption().setFont(createChartFont()); + + // Data Set + DateTimeDataSet categoryValues = DateTimeDataSetImpl.create(timestamps); + + // X-Series + Series seCategory = SeriesImpl.create(); + seCategory.setDataSet(categoryValues); + SeriesDefinition sdX = SeriesDefinitionImpl.create(); + + xAxisPrimary.getSeriesDefinitions().add(sdX); + sdX.getSeries().add(seCategory); + + SeriesDefinition sdY = SeriesDefinitionImpl.create(); + sdY.getSeriesPalette().shift(-3); + yAxisPrimary.getSeriesDefinitions().add(sdY); + + for (int i = 0; i < values.length; i++) { + // Y-Sereis + AreaSeries ls = (AreaSeries) AreaSeriesImpl.create(); + // LineSeries ls = (LineSeries) LineSeriesImpl.create(); + + NumberDataSet orthoValues = NumberDataSetImpl.create(values[i]); + ls.setDataSet(orthoValues); + ls.getLineAttributes().setColor(ColorDefinitionImpl.create(50, 50, 255)); + for (int j = 0; j < ls.getMarkers().size(); j++) { + // ( (Marker) ls.getMarkers( ).get( j ) ).setType( MarkerType.CIRCLE_LITERAL); + ((Marker) ls.getMarkers().get(j)).setVisible(false); + } + ls.setTranslucent(true); + // don't show values on each point on the line chart + ls.getLabel().setVisible(false); + sdY.getSeries().add(ls); + } + return cwaLine; + } + + public static FontDefinition createChartFont() { + return FontDefinitionImpl.create("Serif", 8, false, false, false, false, false, 0d, TextAlignmentImpl.create()); + } + + /** + * @param categories + * Categories of the pie chart + * @param values + * Values of each category in the pie chart + * @return The chart object created for given categories and values + */ + public static final Chart createPieChart(String[] categories, Double[] values) { + ChartWithoutAxes pieChart = ChartWithoutAxesImpl.create(); + + // Plot + pieChart.setSeriesThickness(10); + pieChart.setDimension(ChartDimension.TWO_DIMENSIONAL_WITH_DEPTH_LITERAL); + pieChart.getBlock().setBackground(ColorDefinitionImpl.WHITE()); + Plot p = pieChart.getPlot(); + + p.getClientArea().setBackground(null); + p.getClientArea().getOutline().setVisible(false); + p.getOutline().setVisible(false); + + // Legend + Legend lg = pieChart.getLegend(); + lg.setMaxPercent(0.7); + lg.getText().getFont().setSize(9); + lg.setBackground(null); + lg.getOutline().setVisible(false); + lg.setVisible(true); + + // Title + pieChart.getTitle().getLabel().getCaption().setValue("Pie Chart");//$NON-NLS-1$ + pieChart.getTitle().getOutline().setVisible(false); + pieChart.getTitle().setVisible(false); + + TextDataSet categoryValues = TextDataSetImpl.create(categories); + NumberDataSet seriesOneValues = NumberDataSetImpl.create(values); + + // Base Series + Series seCategory = SeriesImpl.create(); + seCategory.setDataSet(categoryValues); + + SeriesDefinition sd = SeriesDefinitionImpl.create(); + pieChart.getSeriesDefinitions().add(sd); + sd.setSeriesPalette(new GlusterChartPalette()); + sd.getSeriesPalette().shift(0); + sd.getSeries().add(seCategory); + + // Orthogonal Series + PieSeries sePie = (PieSeries) PieSeriesImpl.create(); + sePie.setRatio(0.60); + sePie.setDataSet(seriesOneValues); + sePie.setSeriesIdentifier("Chart");//$NON-NLS-1$ + sePie.getTitle().setVisible(false); // no title + sePie.getLabel().setVisible(false); // no label (values) + sePie.setExplosion(0); // no gap between the pie slices + + SeriesDefinition seriesDefinition = SeriesDefinitionImpl.create(); + seriesDefinition.getQuery().setDefinition("query.definition");//$NON-NLS-1$ + sd.getSeriesDefinitions().add(seriesDefinition); + seriesDefinition.getSeries().add(sePie); + + return pieChart; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events + * .PaintEvent) + */ + public final void paintControl(PaintEvent e) { + Rectangle d = ((Composite) e.getSource()).getBounds(); + Image imgChart = new Image(this.getDisplay(), d); + GC gcImage = new GC(imgChart); + deviceReader.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, gcImage); + deviceReader.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this); + + Bounds bo = BoundsImpl.create(0, 0, d.width, d.height); + bo.scale(58d / deviceReader.getDisplayServer().getDpiResolution()); + + Generator gr = Generator.instance(); + if (needsGeneration) { + needsGeneration = false; + try { + generatedChartState = gr.build(deviceReader.getDisplayServer(), chart, bo, null, null, null); + } catch (ChartException ce) { + ce.printStackTrace(); + } + } + + try { + gr.render(deviceReader, generatedChartState); + GC gc = e.gc; + gc.drawImage(imgChart, d.x, d.y); + } catch (ChartException gex) { + logger.log(Level.SEVERE, "Exception while rendering pie chart [" + gex.getMessage() + "]", gex); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel() + */ + public Chart getDesignTimeModel() { + return chart; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel() + */ + public Chart getRunTimeModel() { + return generatedChartState.getChartModel(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance() + */ + public Object peerInstance() { + return this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart() + */ + public void regenerateChart() { + redraw(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart() + */ + public void repaintChart() { + redraw(); + } +} \ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/PieChartViewerComposite.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/PieChartViewerComposite.java deleted file mode 100644 index ad8e2fa3..00000000 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/PieChartViewerComposite.java +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Gluster, Inc. - * This file is part of Gluster Management Console. - * - * Gluster Management Console is free software; you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Gluster Management Console is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License - * for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * . - *******************************************************************************/ -package com.gluster.storage.management.gui.utils; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.eclipse.birt.chart.api.ChartEngine; -import org.eclipse.birt.chart.device.IDeviceRenderer; -import org.eclipse.birt.chart.device.IUpdateNotifier; -import org.eclipse.birt.chart.exception.ChartException; -import org.eclipse.birt.chart.factory.GeneratedChartState; -import org.eclipse.birt.chart.factory.Generator; -import org.eclipse.birt.chart.model.Chart; -import org.eclipse.birt.chart.model.ChartWithoutAxes; -import org.eclipse.birt.chart.model.attribute.Bounds; -import org.eclipse.birt.chart.model.attribute.ChartDimension; -import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl; -import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl; -import org.eclipse.birt.chart.model.component.Series; -import org.eclipse.birt.chart.model.component.impl.SeriesImpl; -import org.eclipse.birt.chart.model.data.NumberDataSet; -import org.eclipse.birt.chart.model.data.SeriesDefinition; -import org.eclipse.birt.chart.model.data.TextDataSet; -import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl; -import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl; -import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl; -import org.eclipse.birt.chart.model.impl.ChartWithoutAxesImpl; -import org.eclipse.birt.chart.model.layout.Legend; -import org.eclipse.birt.chart.model.layout.Plot; -import org.eclipse.birt.chart.model.type.PieSeries; -import org.eclipse.birt.chart.model.type.impl.PieSeriesImpl; -import org.eclipse.birt.core.framework.PlatformConfig; -import org.eclipse.core.runtime.Platform; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Composite; - - -/** - * - */ -public final class PieChartViewerComposite extends Composite implements - PaintListener, IUpdateNotifier { - - private IDeviceRenderer deviceReader = null; - private Chart chart = null; - private GeneratedChartState generatedChartState = null; - private boolean needsGeneration = true; - - private static Logger logger = Logger - .getLogger(PieChartViewerComposite.class.getName()); - - /** - * @param parent - * Parent composite of this pie chart viewer composite - * @param style - * SWT style to be used - * @param categories - * Categories of the pie chart - * @param values - * Values of each category in the pie chart Constructs a pie - * chart viewer composite for given categories and values - */ - public PieChartViewerComposite(Composite parent, int style, String[] categories, - Double[] values) { - super(parent, style); - try { - PlatformConfig config = new PlatformConfig(); - config.setBIRTHome(Platform.getInstallLocation().getURL().getPath()); - // Get the connection with SWT device to render the graphics. - deviceReader = ChartEngine.instance(config).getRenderer("dv.SWT");//$NON-NLS-1$ - } catch (ChartException ex) { - logger.log(Level.SEVERE, "Could not create Chart Renderer for SWT", - ex); - } - - addControlListener(new ControlListener() { - - public void controlMoved(ControlEvent e) { - needsGeneration = true; - } - - public void controlResized(ControlEvent e) { - needsGeneration = true; - } - }); - - chart = createPieChart(categories, values); - addPaintListener(this); - } - - /** - * @param categories - * Categories of the pie chart - * @param values - * Values of each category in the pie chart - * @return The chart object created for given categories and values - */ - public static final Chart createPieChart(String[] categories, - Double[] values) { - ChartWithoutAxes pieChart = ChartWithoutAxesImpl.create(); - - // Plot - pieChart.setSeriesThickness(10); - pieChart.setDimension(ChartDimension.TWO_DIMENSIONAL_WITH_DEPTH_LITERAL); - pieChart.getBlock().setBackground(ColorDefinitionImpl.WHITE()); - Plot p = pieChart.getPlot(); - - p.getClientArea().setBackground(null); - p.getClientArea().getOutline().setVisible(false); - p.getOutline().setVisible(false); - - // Legend - Legend lg = pieChart.getLegend(); - lg.setMaxPercent(0.7); - lg.getText().getFont().setSize(9); - lg.setBackground(null); - lg.getOutline().setVisible(false); - lg.setVisible(true); - - // Title - pieChart.getTitle().getLabel().getCaption().setValue("Pie Chart");//$NON-NLS-1$ - pieChart.getTitle().getOutline().setVisible(false); - pieChart.getTitle().setVisible(false); - - TextDataSet categoryValues = TextDataSetImpl.create(categories); - NumberDataSet seriesOneValues = NumberDataSetImpl.create(values); - - // Base Series - Series seCategory = SeriesImpl.create(); - seCategory.setDataSet(categoryValues); - - SeriesDefinition sd = SeriesDefinitionImpl.create(); - pieChart.getSeriesDefinitions().add(sd); - sd.setSeriesPalette(new GlusterChartPalette()); - sd.getSeriesPalette().shift(0); - sd.getSeries().add(seCategory); - - // Orthogonal Series - PieSeries sePie = (PieSeries) PieSeriesImpl.create(); - sePie.setRatio(0.60); - sePie.setDataSet(seriesOneValues); - sePie.setSeriesIdentifier("Chart");//$NON-NLS-1$ - sePie.getTitle().setVisible(false); // no title - sePie.getLabel().setVisible(false); // no label (values) - sePie.setExplosion(0); // no gap between the pie slices - - SeriesDefinition seriesDefinition = SeriesDefinitionImpl.create(); - seriesDefinition.getQuery().setDefinition("query.definition");//$NON-NLS-1$ - sd.getSeriesDefinitions().add(seriesDefinition); - seriesDefinition.getSeries().add(sePie); - - return pieChart; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events - * .PaintEvent) - */ - public final void paintControl(PaintEvent e) { - Rectangle d = ((Composite) e.getSource()).getBounds(); - Image imgChart = new Image(this.getDisplay(), d); - GC gcImage = new GC(imgChart); - deviceReader.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, gcImage); - deviceReader.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this); - - Bounds bo = BoundsImpl.create(0, 0, d.width, d.height); - bo.scale(58d / deviceReader.getDisplayServer().getDpiResolution()); - - Generator gr = Generator.instance(); - if (needsGeneration) { - needsGeneration = false; - try { - generatedChartState = gr.build(deviceReader.getDisplayServer(), - chart, bo, null, null, null); - } catch (ChartException ce) { - ce.printStackTrace(); - } - } - - try { - gr.render(deviceReader, generatedChartState); - GC gc = e.gc; - gc.drawImage(imgChart, d.x, d.y); - } catch (ChartException gex) { - logger.log(Level.SEVERE, "Exception while rendering pie chart [" - + gex.getMessage() + "]", gex); - } - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel() - */ - public Chart getDesignTimeModel() { - return chart; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel() - */ - public Chart getRunTimeModel() { - return generatedChartState.getChartModel(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance() - */ - public Object peerInstance() { - return this; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart() - */ - public void regenerateChart() { - redraw(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart() - */ - public void repaintChart() { - redraw(); - } -} \ No newline at end of file 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 49c55b8a..f970effd 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 @@ -20,8 +20,10 @@ */ package com.gluster.storage.management.gui.views; +import java.util.Date; import java.util.List; +import org.eclipse.birt.chart.util.CDateTime; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.graphics.Image; @@ -40,21 +42,18 @@ import org.eclipse.ui.part.ViewPart; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Alert; import com.gluster.storage.management.core.model.Cluster; -import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; -import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.GlusterDataModel; 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.Server; import com.gluster.storage.management.core.model.TaskInfo; -import com.gluster.storage.management.core.model.Volume; -import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.actions.IActionConstants; +import com.gluster.storage.management.gui.utils.ChartViewerComposite; import com.gluster.storage.management.gui.utils.GUIHelper; -import com.gluster.storage.management.gui.utils.PieChartViewerComposite; +import com.ibm.icu.util.Calendar; /** * @author root @@ -82,16 +81,6 @@ public class ClusterSummaryView extends ViewPart { createSections(parent); } - private int getVolumeCountByStatus(Cluster cluster, VOLUME_STATUS status) { - int count = 0; - for (Volume volume : cluster.getVolumes()) { - if (volume.getStatus() == status) { - count++; - } - } - return count; - } - private int getServerCountByStatus(Cluster cluster, SERVER_STATUS status) { int count = 0; for (GlusterServer server : cluster.getServers()) { @@ -102,14 +91,6 @@ public class ClusterSummaryView extends ViewPart { return count; } - private void createVolumesSection() { - Composite section = guiHelper.createSection(form, toolkit, "Volumes", null, 1, false); - - Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.ONLINE)), - Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.OFFLINE)) }; - createDiskSpaceChart(toolkit, section, values); - } - private void createServersSection() { Composite section = guiHelper.createSection(form, toolkit, "Servers", null, 2, false); @@ -135,34 +116,13 @@ public class ClusterSummaryView extends ViewPart { double totalDiskSpace = cluster.getTotalDiskSpace(); double diskSpaceInUse = cluster.getDiskSpaceInUse(); Double[] values = new Double[] { diskSpaceInUse, totalDiskSpace - diskSpaceInUse }; - createDiskSpaceChart(toolkit, section, values); - } - - private int getDiskCountByStatus(Cluster cluster, DEVICE_STATUS status) { - int diskCount = 0; - for(GlusterServer server : cluster.getServers()) { - for(Disk disk : server.getDisks()) { - if(disk.getStatus() == status) { - diskCount++; - } - } - } - return diskCount; + createDiskSpaceChart(section, values); } - private int getDiskCount(Cluster cluster) { - int diskCount = 0; - for(GlusterServer server : cluster.getServers()) { - diskCount += server.getDisks().size(); - } - return diskCount; - } - - private void createDiskSpaceChart(FormToolkit toolkit, Composite section, Double[] values) { + private void createDiskSpaceChart(Composite section, Double[] values) { String[] categories = new String[] { "Used Space: " + NumberUtil.formatNumber((values[0] / 1024)) + " GB", - "Free Space: " + NumberUtil.formatNumber((values[1] / 1024)) + " GB"}; - PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, - values); + "Free Space: " + NumberUtil.formatNumber((values[1] / 1024)) + " GB" }; + ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, categories, values); GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); data.widthHint = 400; @@ -170,6 +130,15 @@ public class ClusterSummaryView extends ViewPart { data.verticalAlignment = SWT.CENTER; chartViewerComposite.setLayoutData(data); } + + private void createLineChart(Composite section, Calendar timestamps[], Double values[]) { + ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, timestamps, values); + GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); + data.widthHint = 400; + data.heightHint = 300; + data.verticalAlignment = SWT.CENTER; + chartViewerComposite.setLayoutData(data); + } private void createAlertsSection() { Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 1, false); @@ -254,23 +223,51 @@ public class ClusterSummaryView extends ViewPart { parent.layout(); // IMP: lays out the form properly } - private void createMemoryUsageSection() { - Composite section = guiHelper.createSection(form, toolkit, "Memory Usage (aggregated)", null, 1, false); - toolkit.createLabel(section, "Historical Memory Usage graph aggregated across all servers will be displayed here."); - } - private void createCPUUsageSection() { Composite section = guiHelper.createSection(form, toolkit, "CPU Usage (aggregated)", null, 1, false); if (cluster.getServers().size() == 0) { toolkit.createLabel(section, "This section will be populated after at least\none server is added to the storage cloud."); return; } - toolkit.createLabel(section, "Historical CPU Usage graph aggregated across\nall servers will be displayed here."); + //toolkit.createLabel(section, "Historical CPU Usage graph aggregated across\nall servers will be displayed here."); + +// Date[] timestamps = new Date[] { new Date(1310468100), new Date(1310468400), new Date(1310468700), +// new Date(1310469000), new Date(1310469300), new Date(1310469600), new Date(1310469900), +// new Date(1310470200), new Date(1310470500), new Date(1310470800), new Date(1310471100), +// new Date(1310471400), new Date(1310471700), new Date(1310472000), new Date(1310472300), +// new Date(1310472600), new Date(1310472900), new Date(1310473200), new Date(1310473500), +// new Date(1310473800) }; + Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), + new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), + new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), + new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), + new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), + new CDateTime(1000l*1310473800) }; + + //String[] timestampsarr = new String[] {"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t16", "t17", "t18", "t19", "t20"}; + Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 89.31d, 57.39d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 21.43d, 16.45d, 14.86d, 15.27d }; + createLineChart(section, timestamps, values); } private void createNetworkUsageSection() { Composite section = guiHelper.createSection(form, toolkit, "Network Usage", null, 1, false); - toolkit.createLabel(section, "Historical Network Usage graph will be displayed here."); + //toolkit.createLabel(section, "Historical Network Usage graph will be displayed here."); + + Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), + new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), + new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), + new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), + new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), + new CDateTime(1000l*1310473800) }; +// Date[] timestamps = new Date[] { new Date(1310468100), new Date(1310468400), new Date(1310468700), +// new Date(1310469000), new Date(1310469300), new Date(1310469600), new Date(1310469900), +// new Date(1310470200), new Date(1310470500), new Date(1310470800), new Date(1310471100), +// new Date(1310471400), new Date(1310471700), new Date(1310472000), new Date(1310472300), +// new Date(1310472600), new Date(1310472900), new Date(1310473200), new Date(1310473500), +// new Date(1310473800) }; + String[] timestampsarr = new String[] {"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t16", "t17", "t18", "t19", "t20"}; + Double[] values = new Double[] { 32d, 31.23d, 27.92d, 48.69d, 58.62d, 49.11d, 72.43d, 69.31d, 87.39d, 78.46d, 60.44d, 56.28d, 33.51d, 27.53d, 12.21, 10d, 21.43d, 36.45d, 34.86d, 35.27d }; + createLineChart(section, timestamps, values); } private void createRunningTasksSection() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java index 30072b97..50da72ff 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java @@ -47,11 +47,12 @@ import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Event; 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.Volume; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.NetworkInterfaceTableLabelProvider; import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager; +import com.gluster.storage.management.gui.utils.ChartViewerComposite; +import com.gluster.storage.management.gui.utils.ChartViewerComposite.CHART_TYPE; import com.gluster.storage.management.gui.utils.GUIHelper; import com.richclientgui.toolbox.gauges.CoolGauge; @@ -100,12 +101,37 @@ public class GlusterServerSummaryView extends ViewPart { GlusterDataModelManager.getInstance().removeClusterListener(serverChangedListener); } + private void createLineChart(Composite section, String timestamps[], Double values[]) { + ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, timestamps, values); + GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); + data.widthHint = 450; + data.heightHint = 300; + data.verticalAlignment = SWT.CENTER; + chartViewerComposite.setLayoutData(data); + } + + private void createMemoryUsageSection() { + Composite section = guiHelper.createSection(form, toolkit, "Memory Usage (aggregated)", null, 1, false); + toolkit.createLabel(section, "Historical Memory Usage graph aggregated across all servers will be displayed here."); + } + + private void createCPUUsageSection() { + Composite section = guiHelper.createSection(form, toolkit, "CPU Usage (aggregated)", null, 1, false); + //toolkit.createLabel(section, "Historical CPU Usage graph aggregated across\nall servers will be displayed here."); + + String[] timestamps = new String[] {"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t16", "t17", "t18", "t19", "t20"}; + Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 20.31d, 19.63d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 40d, 10d, 90d, 40d }; + createLineChart(section, timestamps, values); + } + private void createSections(Composite parent) { String serverName = server.getName(); form = guiHelper.setupForm(parent, toolkit, "Server Summary [" + serverName + "]"); createServerSummarySection(server, toolkit, form); if (server.getStatus() == SERVER_STATUS.ONLINE) { + createMemoryUsageSection(); + createCPUUsageSection(); createNetworkInterfacesSection(server, toolkit, form); } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java index d80e3879..d703c9a7 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java @@ -33,8 +33,9 @@ import org.eclipse.ui.part.ViewPart; import com.gluster.storage.management.core.model.EntityGroup; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.gui.utils.ChartViewerComposite.CHART_TYPE; import com.gluster.storage.management.gui.utils.GUIHelper; -import com.gluster.storage.management.gui.utils.PieChartViewerComposite; +import com.gluster.storage.management.gui.utils.ChartViewerComposite; /** * @@ -95,7 +96,7 @@ public class GlusterServersSummaryView extends ViewPart { private void createStatusChart(Composite section, Double[] values) { String[] categories = new String[] { "Online", "Offline" }; - PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, values); + ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, categories, values); GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); data.widthHint = 300; @@ -103,7 +104,6 @@ public class GlusterServersSummaryView extends ViewPart { chartViewerComposite.setLayoutData(data); } - private void createAlertsSection() { Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 2, false); 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 a43330c4..daeecb83 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 @@ -40,8 +40,9 @@ import com.gluster.storage.management.core.model.TaskInfo.TASK_TYPE; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.ChartViewerComposite.CHART_TYPE; import com.gluster.storage.management.gui.utils.GUIHelper; -import com.gluster.storage.management.gui.utils.PieChartViewerComposite; +import com.gluster.storage.management.gui.utils.ChartViewerComposite; /** * @@ -157,8 +158,7 @@ public class VolumesSummaryView extends ViewPart { private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { String[] categories = new String[] { "Online", "Offline" }; - PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, - values); + ChartViewerComposite chartViewerComposite = new ChartViewerComposite(section, SWT.NONE, categories, values); GridData data = new GridData(SWT.FILL, SWT.FILL, false, false); data.widthHint = 300; diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java index 05a74b03..13c2ceef 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/AbstractTableTreeViewerPage.java @@ -38,7 +38,6 @@ import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.forms.widgets.FormToolkit; -import org.eclipse.ui.forms.widgets.Hyperlink; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.Disk; @@ -46,7 +45,6 @@ import com.gluster.storage.management.gui.utils.GUIHelper; public abstract class AbstractTableTreeViewerPage extends Composite implements ISelectionListener { - protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); protected TreeViewer treeViewer; protected GUIHelper guiHelper = GUIHelper.getInstance(); diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/web.xml b/src/com.gluster.storage.management.server/WebContent/WEB-INF/web.xml index 7c20d6c7..405c4e40 100644 --- a/src/com.gluster.storage.management.server/WebContent/WEB-INF/web.xml +++ b/src/com.gluster.storage.management.server/WebContent/WEB-INF/web.xml @@ -81,14 +81,14 @@ springSecurityFilterChain /* - + - - Gluster Management Gateway - /* - - - CONFIDENTIAL - - + + Gluster Management Gateway + /* + + + CONFIDENTIAL + + diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GenericExceptionMapper.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GenericExceptionMapper.java new file mode 100644 index 00000000..4cd7f4f9 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GenericExceptionMapper.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.resources.v1_0; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import com.gluster.storage.management.core.exceptions.GlusterValidationException; + +@Provider +public class GenericExceptionMapper implements ExceptionMapper { + + /* (non-Javadoc) + * @see javax.ws.rs.ext.ExceptionMapper#toResponse(java.lang.Throwable) + */ + @Override + public Response toResponse(Exception exception) { + ResponseBuilder builder; + if (exception instanceof GlusterValidationException) { + builder = Response.status(Response.Status.BAD_REQUEST); + } else { + builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR); + } + return builder.entity(exception.getMessage()).type(MediaType.TEXT_PLAIN).build(); + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java index a5f366a2..09391841 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java @@ -18,15 +18,21 @@ *******************************************************************************/ package com.gluster.storage.management.server.resources.v1_0; -import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FSTYPE; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DETAILS; +import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TYPE; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_STATISTICS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_TASKS; +import static com.gluster.storage.management.core.constants.RESTConstants.STATISTICS_TYPE_CPU; +import static com.gluster.storage.management.core.constants.RESTConstants.STATISTICS_TYPE_NETWORK; +import static com.gluster.storage.management.core.constants.RESTConstants.STATISTICS_TYPE_MEMORY; import java.util.ArrayList; import java.util.List; @@ -39,6 +45,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -49,14 +56,15 @@ import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.ServerStats; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.response.GlusterServerListResponse; +import com.gluster.storage.management.core.response.ServerNameListResponse; import com.gluster.storage.management.server.data.ClusterInfo; import com.gluster.storage.management.server.data.ServerInfo; import com.gluster.storage.management.server.services.ClusterService; import com.gluster.storage.management.server.tasks.InitializeDiskTask; -import com.gluster.storage.management.server.utils.GlusterUtil; import com.gluster.storage.management.server.utils.SshUtil; import com.sun.jersey.api.core.InjectParam; import com.sun.jersey.spi.resource.Singleton; @@ -92,17 +100,44 @@ public class GlusterServersResource extends AbstractServersResource { @GET @Produces(MediaType.APPLICATION_JSON) - public Response getGlusterServersJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { - return getGlusterServers(clusterName, MediaType.APPLICATION_JSON); + public Response getGlusterServersJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @QueryParam(QUERY_PARAM_DETAILS) Boolean details) { + return getGlusterServers(clusterName, MediaType.APPLICATION_JSON, details); } @GET @Produces(MediaType.APPLICATION_XML) - public Response getGlusterServersXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName) { - return getGlusterServers(clusterName, MediaType.APPLICATION_XML); + public Response getGlusterServersXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @QueryParam(QUERY_PARAM_DETAILS) Boolean details) { + return getGlusterServers(clusterName, MediaType.APPLICATION_XML, details); } + + private List getGlusterServers(String clusterName, boolean fetchDetails) { + List glusterServers; + GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); + if (onlineServer == null) { + throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); + } - public Response getGlusterServers(String clusterName, String mediaType) { + try { + glusterServers = getGlusterServers(clusterName, onlineServer, fetchDetails); + } catch (ConnectionException e) { + // online server has gone offline! try with a different one. + onlineServer = clusterService.getNewOnlineServer(clusterName); + if (onlineServer == null) { + throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); + } + glusterServers = getGlusterServers(clusterName, onlineServer, fetchDetails); + } + return glusterServers; + } + + private Response getGlusterServers(String clusterName, String mediaType, Boolean fetchDetails) { + if(fetchDetails == null) { + // by default, fetch the server details + fetchDetails = true; + } + List glusterServers = new ArrayList(); if (clusterName == null || clusterName.isEmpty()) { @@ -118,37 +153,30 @@ public class GlusterServersResource extends AbstractServersResource { return okResponse(new GlusterServerListResponse(glusterServers), mediaType); } - GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); - if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); - } - try { - glusterServers = getGlusterServers(clusterName, onlineServer); - } catch (ConnectionException e) { - // online server has gone offline! try with a different one. - onlineServer = clusterService.getNewOnlineServer(clusterName); - if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); - } - try { - glusterServers = getGlusterServers(clusterName, onlineServer); - } catch (Exception e1) { - return errorResponse(e1.getMessage()); - } + glusterServers = getGlusterServers(clusterName, fetchDetails); } catch (Exception e) { return errorResponse(e.getMessage()); } - - String errMsg = fetchDetailsOfServers(glusterServers, onlineServer); - if (!errMsg.isEmpty()) { - return errorResponse("Couldn't fetch details for server(s): " + errMsg); + + if(fetchDetails) { + return okResponse(new GlusterServerListResponse(glusterServers), mediaType); + } else { + // no details to be fetched. Return list of server names. + return okResponse(new ServerNameListResponse(getServerNames(glusterServers)), mediaType); } + } + - return okResponse(new GlusterServerListResponse(glusterServers), mediaType); + private List getServerNames(List glusterServers) { + List serverNames = new ArrayList(); + for(GlusterServer server : glusterServers) { + serverNames.add(server.getName()); + } + return serverNames; } - public String fetchDetailsOfServers(List glusterServers, GlusterServer onlineServer) { + private String fetchDetailsOfServers(List glusterServers, GlusterServer onlineServer) { String errMsg = ""; for (GlusterServer server : glusterServers) { @@ -161,7 +189,7 @@ public class GlusterServersResource extends AbstractServersResource { return errMsg; } - public List getGlusterServers(String clusterName, GlusterServer onlineServer) { + private List getGlusterServers(String clusterName, GlusterServer onlineServer, boolean fetchDetails) { List glusterServers; try { glusterServers = glusterUtil.getGlusterServers(onlineServer); @@ -174,11 +202,18 @@ public class GlusterServersResource extends AbstractServersResource { glusterServers = glusterUtil.getGlusterServers(onlineServer); } + + if (fetchDetails) { + String errMsg = fetchDetailsOfServers(glusterServers, onlineServer); + if (!errMsg.isEmpty()) { + throw new GlusterRuntimeException("Couldn't fetch details for server(s): " + errMsg); + } + } return glusterServers; } @GET - @Path("{serverName}") + @Path("{" + PATH_PARAM_SERVER_NAME + "}") @Produces(MediaType.APPLICATION_XML) public Response getGlusterServerXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { @@ -186,7 +221,7 @@ public class GlusterServersResource extends AbstractServersResource { } @GET - @Path("{serverName}") + @Path("{" + PATH_PARAM_SERVER_NAME + "}") @Produces(MediaType.APPLICATION_JSON) public Response getGlusterServerJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { @@ -428,20 +463,57 @@ public class GlusterServersResource extends AbstractServersResource { return errorResponse(e.getMessage()); } } + + @GET + @Produces(MediaType.APPLICATION_XML) + @Path(RESOURCE_STATISTICS) + public Response getAggregatedPerformanceDataXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @QueryParam(QUERY_PARAM_TYPE) String type) { + return getAggregaredPerformanceData(clusterName, type, MediaType.APPLICATION_XML); + } - private void setGlusterUtil(GlusterUtil glusterUtil) { - this.glusterUtil = glusterUtil; + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path(RESOURCE_STATISTICS) + public Response getAggregaredPerformanceDataJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, + @QueryParam(QUERY_PARAM_TYPE) String type) { + return getAggregaredPerformanceData(clusterName, type, MediaType.APPLICATION_JSON); } - public static void main(String[] args) { - GlusterServersResource glusterServersResource = new GlusterServersResource(); - GlusterUtil glusterUtil = new GlusterUtil(); - glusterUtil.setSshUtil(new SshUtil()); - glusterServersResource.setGlusterUtil(glusterUtil); - // System.out.println(glusterServersResource.getServerDetails("127.0.0.1").size()); + @GET + @Produces(MediaType.APPLICATION_XML) + @Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_STATISTICS) + public Response getPerformanceDataXML(@PathParam(PATH_PARAM_SERVER_NAME) String serverName, @QueryParam(QUERY_PARAM_TYPE) String type) { + return getPerformanceData(serverName, type, MediaType.APPLICATION_XML); + } - // To add a server - // GlusterServerResponse response = glusterServersResource.addServer("my-server"); - // System.out.println(response.getData().getName()); + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_STATISTICS) + public Response getPerformanceDataJSON(@PathParam(PATH_PARAM_SERVER_NAME) String serverName, @QueryParam(QUERY_PARAM_TYPE) String type) { + return getPerformanceData(serverName, type, MediaType.APPLICATION_JSON); + } + + private Response getAggregaredPerformanceData(String clusterName, String type, String mediaType) { + List serverNames = getServerNames(getGlusterServers(clusterName, false)); + if(type.equals(STATISTICS_TYPE_CPU)) { + return okResponse(serverUtil.fetchAggregatedCPUStats(serverNames), mediaType); + } else { + return badRequestResponse("Server Statistics for [" + type + "] not supported! Valid values are [" + + STATISTICS_TYPE_CPU + ", " + STATISTICS_TYPE_NETWORK + ", " + STATISTICS_TYPE_MEMORY + "]"); + } + } + + private Response getPerformanceData(String serverName, String type, String mediaType) { + if(type.equals(STATISTICS_TYPE_CPU)) { + return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType); + } else if(type.equals(STATISTICS_TYPE_NETWORK)) { + return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType); + } else if(type.equals(STATISTICS_TYPE_MEMORY)) { + return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType); + } else { + return badRequestResponse("Server Statistics for [" + type + "] not supported! Valid values are [" + + STATISTICS_TYPE_CPU + ", " + STATISTICS_TYPE_NETWORK + ", " + STATISTICS_TYPE_MEMORY + "]"); + } } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/ValidationExceptionMapper.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/ValidationExceptionMapper.java new file mode 100644 index 00000000..cab6cc62 --- /dev/null +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/ValidationExceptionMapper.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * . + *******************************************************************************/ +package com.gluster.storage.management.server.resources.v1_0; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import com.gluster.storage.management.core.exceptions.GlusterValidationException; + +@Provider +public class ValidationExceptionMapper implements ExceptionMapper { + + /* (non-Javadoc) + * @see javax.ws.rs.ext.ExceptionMapper#toResponse(java.lang.Throwable) + */ + @Override + public Response toResponse(GlusterValidationException exception) { + return Response.status(Response.Status.BAD_REQUEST).entity(exception.getMessage()) + .type(MediaType.TEXT_PLAIN).build(); + } +} 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 ae4bc919..55be59b4 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 @@ -22,6 +22,8 @@ package com.gluster.storage.management.server.utils; import java.io.ByteArrayInputStream; import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; import java.util.List; import javax.servlet.ServletContext; @@ -29,12 +31,15 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; +import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.ServerStatsRow; +import com.gluster.storage.management.core.model.ServerStats; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.response.GenericResponse; @@ -48,6 +53,8 @@ public class ServerUtil { @Autowired private SshUtil sshUtil; + + private static final Logger logger = Logger.getLogger(ServerUtil.class); private static final String SCRIPT_DIR = "scripts"; private static final String SCRIPT_COMMAND = "python"; @@ -216,4 +223,103 @@ public class ServerUtil { public Status getDiskForDir(String serverName, String brickDir) { return (Status) executeOnServer(true, serverName, REMOTE_SCRIPT_GET_DISK_FOR_DIR + " " + brickDir, Status.class); } + + public ServerStats fetchCPUUsageData(String serverName) { + String cpuUsageData = " 1310468100 300 1310471700 13 3 user system total 1310468100NaN4.3747778209e-016.6128073384e-01 13104684002.3387347338e-014.4642717442e-016.8030064780e-01 13104687005.5043873220e+006.2462376636e+001.1750624986e+01 13104690002.4350593653e+012.6214585217e+015.0565178869e+01 13104693004.0786489953e+014.6784713828e+018.7571203781e+01 13104696004.1459955508e+015.2546309044e+019.4006264551e+01 13104699004.2312286165e+015.2390588332e+019.4702874497e+01 13104702004.2603794982e+015.1598861493e+019.4202656475e+01 13104705003.8238751290e+014.5312089966e+018.3550841256e+01 13104708001.7949961224e+012.1282058418e+013.9232019642e+01 13104711001.2330371421e-014.6347832868e-015.8678204289e-01 13104714001.6313260492e-015.4088119561e-017.0401380052e-01 1310471700NaNNaNNaN "; + Object output = unmarshal(ServerStats.class, cpuUsageData, false); + if(output instanceof Status) { + throw new GlusterRuntimeException(((Status)output).toString()); + } + return (ServerStats) output; + } + + private ServerStats getFirstOnlineServerCPUStats(List serverNames, boolean removeServerOnError, boolean removeOnlineServer) { + for(String serverName : serverNames) { + try { + ServerStats stats = fetchCPUUsageData(serverName); + if(removeOnlineServer) { + serverNames.remove(serverName); + } + } catch(Exception e) { + // server might be offline - continue with next one + logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e); + if(removeServerOnError) { + serverNames.remove(serverName); + } + continue; + } + } + throw new GlusterRuntimeException("All servers offline!"); + } + + public Object fetchAggregatedCPUStats(List serverNames) { + if(serverNames == null || serverNames.size() == 0) { + throw new GlusterRuntimeException("No server names passed to fetchAggregaredCPUUsageData!"); + } + + ServerStats firstServerStats = getFirstOnlineServerCPUStats(serverNames, true, true); + + ServerStats aggregatedStats = new ServerStats(firstServerStats); + aggregateCPUStats(serverNames, aggregatedStats); + return aggregatedStats; + } + + private void aggregateCPUStats(List serverNames, ServerStats aggregatedStats) { + int[][] dataCount = new int[aggregatedStats.getMetadata().getRowCount()][aggregatedStats.getMetadata() + .getLegend().size()]; + + for (String serverName : serverNames) { + ServerStats serverStats; + try { + serverStats = fetchCPUUsageData(serverName); + } catch(Exception e) { + // server might be offline - continue with next one + logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e); + continue; + } + List serverStatsRows = addServerStats(serverStats, aggregatedStats, dataCount); + } + + List rows = aggregatedStats.getRows(); + for(int rowNum = 0; rowNum < rows.size(); rowNum++) { + List data = rows.get(rowNum).getUsageData(); + for(int columnNum = 0; columnNum < data.size(); columnNum++) { + data.set(columnNum, data.get(columnNum) / dataCount[rowNum][columnNum]); + } + } + } + + /** + * + * @param statsToBeAdded + * @param targetStats + * @param dataCount Each element of this matrix will be incremented for every valid element added + * @return + */ + private List addServerStats(ServerStats statsToBeAdded, ServerStats targetStats, int[][] dataCount) { + List serverStatsRows = statsToBeAdded.getRows(); + for (int rowNum = 0; rowNum < serverStatsRows.size() + && rowNum < targetStats.getMetadata().getRowCount(); rowNum++) { + ServerStatsRow row = serverStatsRows.get(rowNum); + List rowData = row.getUsageData(); + + List aggregatedStatsRowData = targetStats.getRows().get(rowNum).getUsageData(); + for(int i = 1; i < targetStats.getMetadata().getLegend().size(); i++) { + // Add the data + Double data = rowData.get(i); + if(!data.isNaN()) { + // data is available. add it. + aggregatedStatsRowData.set(i, aggregatedStatsRowData.get(i) + data); + // increment record count. this will be used for calculating average of aggregated data. + dataCount[rowNum][i]++; + } + } + } + return serverStatsRows; + } + + public static void main(String[] args) { + ServerStats stats = new ServerUtil().fetchCPUUsageData("s1"); + System.out.println(stats.getMetadata().getLegend()); + } } -- cgit