From 2c4ea3418784160bdf4f186b2488e974465161e7 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 1 Jul 2011 16:15:23 +0530 Subject: [Bug 3117] New: Failing to create volume should throw error message instead of stack trace. --- .../management/client/GlusterDataModelManager.java | 49 ++- .../management/core/utils/GlusterCoreUtil.java | 39 ++ .../icons/tango/16x16/view-refresh.png | Bin 0 -> 912 bytes .../icons/tango/32x32/view-refresh.png | Bin 0 -> 2024 bytes .../icons/tango/scalable/view-refresh.svg | 393 +++++++++++++++++++++ src/com.gluster.storage.management.gui/plugin.xml | 76 ++-- .../management/gui/actions/RefreshDataAction.java | 45 +++ .../server/resources/VolumesResource.java | 25 +- 8 files changed, 585 insertions(+), 42 deletions(-) create mode 100644 src/com.gluster.storage.management.gui/icons/tango/16x16/view-refresh.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/32x32/view-refresh.png create mode 100644 src/com.gluster.storage.management.gui/icons/tango/scalable/view-refresh.svg create mode 100644 src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.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 9705501a..be7a9023 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 @@ -29,6 +29,7 @@ import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.core.model.Entity; 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; @@ -43,6 +44,7 @@ import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeOptionInfo; +import com.gluster.storage.management.core.utils.GlusterCoreUtil; public class GlusterDataModelManager { private static GlusterDataModelManager instance = new GlusterDataModelManager(); @@ -80,10 +82,14 @@ public class GlusterDataModelManager { } public void initializeModel(String securityToken, String clusterName) { - model = new GlusterDataModel("Gluster Data Model"); setSecurityToken(securityToken); setClusterName(clusterName); + model = fetchData(clusterName); + } + + public GlusterDataModel fetchData(String clusterName) { + GlusterDataModel model = new GlusterDataModel("Gluster Data Model"); Cluster cluster = new Cluster(clusterName, model); initializeGlusterServers(cluster); @@ -96,6 +102,46 @@ public class GlusterDataModelManager { initializeVolumeOptionsDefaults(); model.addCluster(cluster); + return model; + } + + public void updateModel(GlusterDataModel model) { + updateVolumes(model); + } + + private void updateVolumes(GlusterDataModel model) { + List currentVolumes = this.model.getCluster().getVolumes(); + List latestVolumes = model.getCluster().getVolumes(); + + List addedVolumes = getAddedVolumes(currentVolumes, latestVolumes); + for(ClusterListener listener : listeners) { + for(Volume addedVolume : addedVolumes) { + listener.volumeAdded(addedVolume); + } + } + + List removedVolumes = getRemovedVolumes(currentVolumes, latestVolumes); + for(ClusterListener listener : listeners) { + for(Volume removedVolume : addedVolumes) { + listener.volumeRemoved(removedVolume); + } + } + } + + private List getRemovedVolumes(List currentVolumes, List latestVolumes) { + // TODO Auto-generated method stub + return null; + } + + private List getAddedVolumes(List currentVolumes, List newVolumes) { + List addedVolumes = new ArrayList(); + for(Volume newVolume : addedVolumes) { + if(!GlusterCoreUtil.containsEntity(currentVolumes, newVolume, false)) { + // current volume list doesn't contain this volume. mark it. + addedVolumes.add(newVolume); + } + } + return addedVolumes; } private void initializeGlusterServers(Cluster cluster) { @@ -465,5 +511,4 @@ public class GlusterDataModelManager { } return volumeNames; } - } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java index 4194a642..20b652f4 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java @@ -26,6 +26,7 @@ import java.util.Set; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Entity; public class GlusterCoreUtil { @@ -45,4 +46,42 @@ public class GlusterCoreUtil { } return qualifiedBricks; } + + /** + * Compares the two entity lists and returns the list of entities present only in the second argument + * newEntities + * + * @param oldEntities + * @param newEntities + * @return List of entities that are present only in the second argument newEntities + */ + public static List getAddedEntities(List oldEntities, List newEntities) { + List addedEntities = new ArrayList(); + for(Entity newEntity : newEntities) { + if(!containsEntity(oldEntities, newEntity, false)) { + // old entity list doesn't contain this entity. mark it as new. + addedEntities.add(newEntity); + } + } + return addedEntities; + } + + public static boolean containsEntity(List entityList, Entity searchEntity, boolean caseInsensitive) { + String searchEntityName = searchEntity.getName(); + if(caseInsensitive) { + searchEntityName = searchEntityName.toUpperCase(); + } + + for(Entity entity : entityList) { + String nextEntityName = entity.getName(); + if(caseInsensitive) { + nextEntityName = nextEntityName.toUpperCase(); + } + if(nextEntityName.equals(searchEntityName)) { + return true; + } + } + + return false; + } } diff --git a/src/com.gluster.storage.management.gui/icons/tango/16x16/view-refresh.png b/src/com.gluster.storage.management.gui/icons/tango/16x16/view-refresh.png new file mode 100644 index 00000000..3fd71d6e Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/16x16/view-refresh.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/32x32/view-refresh.png b/src/com.gluster.storage.management.gui/icons/tango/32x32/view-refresh.png new file mode 100644 index 00000000..606ea9eb Binary files /dev/null and b/src/com.gluster.storage.management.gui/icons/tango/32x32/view-refresh.png differ diff --git a/src/com.gluster.storage.management.gui/icons/tango/scalable/view-refresh.svg b/src/com.gluster.storage.management.gui/icons/tango/scalable/view-refresh.svg new file mode 100644 index 00000000..565f6dad --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/tango/scalable/view-refresh.svg @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + View Refresh + + + reload + refresh + view + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index 112c8e81..5b18421f 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -391,36 +391,6 @@ - - - - - - - - + + + + + + + + + + diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java new file mode 100644 index 00000000..4a569c50 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.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.gui.actions; + +import org.eclipse.jface.action.IAction; + +/** + * + */ +public class RefreshDataAction extends AbstractActionDelegate { + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() + */ + @Override + public void dispose() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.gluster.storage.management.gui.actions.AbstractActionDelegate#performAction(org.eclipse.jface.action.IAction) + */ + @Override + protected void performAction(IAction action) { + // TODO Auto-generated method stub + + } +} diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index c9ae0fe5..d568d519 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -207,27 +207,32 @@ public class VolumesResource extends AbstractResource { return badRequestResponse("Stripe count must be a positive integer"); } + try { + createVolume(clusterName, volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, + options); + return createdResponse(volumeName); + } catch (Exception e) { + return errorResponse(e.getMessage()); + } + } + + public void performCreateVolume(String clusterName, String volumeName, String volumeType, String transportType, Integer replicaCount, + Integer stripeCount, String bricks, String accessProtocols, String options) { GlusterServer onlineServer = clusterService.getOnlineServer(clusterName); if (onlineServer == null) { - return errorResponse("No online servers found in cluster [" + clusterName + "]"); + throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } - try { + try { glusterUtil.createVolume(onlineServer.getName(), volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options); - return createdResponse(volumeName); } 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 + "]"); + throw new GlusterRuntimeException("No online servers found in cluster [" + clusterName + "]"); } - try { - glusterUtil.createVolume(onlineServer.getName(), volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options); - return createdResponse(volumeName); - } catch(Exception e1) { - return errorResponse(e1.getMessage()); - } + glusterUtil.createVolume(onlineServer.getName(), volumeName, volumeType, transportType, replicaCount, stripeCount, bricks, accessProtocols, options); } } -- cgit From 5cb94f565f49b2a952d941df18507049364a1b6d Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Fri, 1 Jul 2011 20:29:40 +0530 Subject: Task#111 - Auto-refresh of data in views --- .../management/client/GlusterDataModelManager.java | 76 +++++++++++++--------- .../management/core/utils/GlusterCoreUtil.java | 13 ++-- .../management/gui/actions/AddServerAction.java | 1 - .../management/gui/actions/RefreshDataAction.java | 5 +- .../storage/management/server/utils/SshUtil.java | 33 +++++----- 5 files changed, 73 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index be7a9023..f3feb1cb 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -105,45 +105,50 @@ public class GlusterDataModelManager { return model; } - public void updateModel(GlusterDataModel model) { + public void refreshModel() { + updateModel(fetchData(clusterName)); + } + + private void updateModel(GlusterDataModel model) { updateVolumes(model); + updateServers(model); + // TODO: Update other entities like discovered servers } - private void updateVolumes(GlusterDataModel model) { - List currentVolumes = this.model.getCluster().getVolumes(); - List latestVolumes = model.getCluster().getVolumes(); + private void updateServers(GlusterDataModel newModel) { + List oldServers = model.getCluster().getServers(); + List newServers = newModel.getCluster().getServers(); - List addedVolumes = getAddedVolumes(currentVolumes, latestVolumes); - for(ClusterListener listener : listeners) { - for(Volume addedVolume : addedVolumes) { - listener.volumeAdded(addedVolume); - } + List addedServers = GlusterCoreUtil.getAddedEntities(oldServers, newServers, true); + for (GlusterServer addedServer : addedServers) { + addGlusterServer(addedServer); } - - List removedVolumes = getRemovedVolumes(currentVolumes, latestVolumes); - for(ClusterListener listener : listeners) { - for(Volume removedVolume : addedVolumes) { - listener.volumeRemoved(removedVolume); - } + + List removedServers = GlusterCoreUtil.getAddedEntities(newServers, oldServers, true); + for (GlusterServer removedServer : removedServers) { + removeGlusterServer(removedServer); } - } - - private List getRemovedVolumes(List currentVolumes, List latestVolumes) { - // TODO Auto-generated method stub - return null; + + // TODO: Refresh "modified" servers } - private List getAddedVolumes(List currentVolumes, List newVolumes) { - List addedVolumes = new ArrayList(); - for(Volume newVolume : addedVolumes) { - if(!GlusterCoreUtil.containsEntity(currentVolumes, newVolume, false)) { - // current volume list doesn't contain this volume. mark it. - addedVolumes.add(newVolume); - } + private void updateVolumes(GlusterDataModel newModel) { + List oldVolumes = model.getCluster().getVolumes(); + List newVolumes = newModel.getCluster().getVolumes(); + + List addedVolumes = GlusterCoreUtil.getAddedEntities(oldVolumes, newVolumes, false); + for (Volume addedVolume : addedVolumes) { + addVolume(addedVolume); } - return addedVolumes; + + List removedVolumes = GlusterCoreUtil.getAddedEntities(newVolumes, oldVolumes, false); + for (Volume removedVolume : removedVolumes) { + deleteVolume(removedVolume); + } + + // TODO: Refresh "modified" volumes } - + private void initializeGlusterServers(Cluster cluster) { cluster.setServers(new GlusterServersClient().getServers()); } @@ -323,6 +328,8 @@ public class GlusterDataModelManager { for (ClusterListener listener : listeners) { listener.serverAdded(server); } + + removeDiscoveredServer(server.getName()); } public void addDiscoveredServer(Server server) { @@ -333,6 +340,17 @@ public class GlusterDataModelManager { listener.discoveredServerAdded(server);; } } + + public void removeDiscoveredServer(String serverName) { + Cluster cluster = model.getCluster(); + // TODO: Move auto-discovered servers outside the cluster + for(Server server : cluster.getAutoDiscoveredServers()) { + if(server.getName().toUpperCase().equals(serverName.toUpperCase())) { + removeDiscoveredServer(server); + break; + } + } + } public void removeDiscoveredServer(Server server) { Cluster cluster = model.getCluster(); diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java index 20b652f4..76a7fbfc 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterCoreUtil.java @@ -53,12 +53,13 @@ public class GlusterCoreUtil { * * @param oldEntities * @param newEntities + * @param caseInsensitive If true, the entity name comparison will be done in case insensitive manner * @return List of entities that are present only in the second argument newEntities */ - public static List getAddedEntities(List oldEntities, List newEntities) { - List addedEntities = new ArrayList(); - for(Entity newEntity : newEntities) { - if(!containsEntity(oldEntities, newEntity, false)) { + public static List getAddedEntities(List oldEntities, List newEntities, boolean caseInsensitive) { + List addedEntities = new ArrayList(); + for(T newEntity : newEntities) { + if(!containsEntity(oldEntities, newEntity, caseInsensitive)) { // old entity list doesn't contain this entity. mark it as new. addedEntities.add(newEntity); } @@ -66,13 +67,13 @@ public class GlusterCoreUtil { return addedEntities; } - public static boolean containsEntity(List entityList, Entity searchEntity, boolean caseInsensitive) { + public static boolean containsEntity(List entityList, Entity searchEntity, boolean caseInsensitive) { String searchEntityName = searchEntity.getName(); if(caseInsensitive) { searchEntityName = searchEntityName.toUpperCase(); } - for(Entity entity : entityList) { + for(T entity : entityList) { String nextEntityName = entity.getName(); if(caseInsensitive) { nextEntityName = nextEntityName.toUpperCase(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java index 4d1a87c9..18731632 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java @@ -55,7 +55,6 @@ public class AddServerAction extends AbstractActionDelegate { try { glusterServersClient.addServer(server); - modelManager.removeDiscoveredServer(server); modelManager.addGlusterServer(glusterServersClient.getGlusterServer(server.getName())); successServers.add(server); } catch(Exception e) { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java index 4a569c50..fe358caa 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RefreshDataAction.java @@ -20,6 +20,8 @@ package com.gluster.storage.management.gui.actions; import org.eclipse.jface.action.IAction; +import com.gluster.storage.management.client.GlusterDataModelManager; + /** * */ @@ -39,7 +41,6 @@ public class RefreshDataAction extends AbstractActionDelegate { */ @Override protected void performAction(IAction action) { - // TODO Auto-generated method stub - + GlusterDataModelManager.getInstance().refreshModel(); } } diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java index d56cd47c..4f0b04cf 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java @@ -226,6 +226,10 @@ public class SshUtil { return conn; } + private boolean wasTerminated(int condition) { + return ((condition | ChannelCondition.EXIT_SIGNAL) == condition); + } + private boolean hasErrors(int condition, Session session) { return (hasErrorStream(condition) || (exitedGracefully(condition) && exitedWithError(session))); } @@ -239,7 +243,7 @@ public class SshUtil { } private boolean exitedGracefully(int condition) { - return (condition == ChannelCondition.EXIT_STATUS); + return (condition | ChannelCondition.EXIT_STATUS) == condition; } private boolean hasErrorStream(int condition) { @@ -292,24 +296,19 @@ public class SshUtil { private ProcessResult prepareProcessResult(Session session, int condition, String output) { ProcessResult result = null; - switch(condition) { - case ChannelCondition.TIMEOUT: - result = new ProcessResult(ProcessResult.FAILURE, "Command timed out!"); - break; - case ChannelCondition.EXIT_SIGNAL: - // terminated + + if (wasTerminated(condition)) { result = new ProcessResult(ProcessResult.FAILURE, output); - break; - default: - if (hasErrors(condition, session)) { - Integer exitStatus = session.getExitStatus(); - int statusCode = (exitStatus == null ? ProcessResult.FAILURE : exitStatus); - result = new ProcessResult(statusCode, output); - } else { - result = new ProcessResult(ProcessResult.SUCCESS, output); - } - break; + } else if (timedOut(condition)) { + result = new ProcessResult(ProcessResult.FAILURE, "Command timed out!"); + } else if (hasErrors(condition, session)) { + Integer exitStatus = session.getExitStatus(); + int statusCode = (exitStatus == null ? ProcessResult.FAILURE : exitStatus); + result = new ProcessResult(statusCode, output); + } else { + result = new ProcessResult(ProcessResult.SUCCESS, output); } + return result; } -- cgit