Shireesh Anjal has uploaded a new change for review.

Change subject: engine: [WIP] Refresh gluster data periodically
......................................................................

engine: [WIP] Refresh gluster data periodically

Introducing GlusterManager, which will be initialized when application comes up.
It fetches Gluster related data periodically and updates the database with it.
Lightweight data (like volume properties) that doesn't add serious overhead on
gluster processes is fetched more frequently (GlusterRefreshRateLight), and the
data (like brick status) that adds significant overhead of Gluster processes is
fetched less frequently (GlusterRefreshRateHeavy).

TODO: Will send another patch-set with test cases.

Note: Support for refreshing brick statuses and gluster servers will be added in
separate patch(es)

Change-Id: I6b61eb6e93105e46e2706eac1d94bc10717224c2
Signed-off-by: Shireesh Anjal <[email protected]>
---
M backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterManager.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/GlusterUtils.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterBrickEntity.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeEntity.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/gluster/GlusterCoreUtil.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/gluster/GlusterVolumesListVDSParameters.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDao.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDaoDbFacadeImpl.java
M 
backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListReturnForXmlRpc.java
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListVDSCommand.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
19 files changed, 734 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/88/7288/1

diff --git a/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql 
b/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql
index dbe2bb3..3e2e8dd 100644
--- a/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql
+++ b/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql
@@ -454,6 +454,9 @@
 select 
fn_db_add_config_value('NetworkConnectivityCheckTimeoutInSeconds','120','general');
 -- AutoRecoveryConfiguration
 select fn_db_add_config_value('AutoRecoveryAllowedTypes','{\"storage 
domains\":\"false\",\"hosts\":\"false\"}','general');
+-- Gluster refresh rates (in seconds)
+select fn_db_add_config_value('GlusterRefreshRateLight', '5', 'general');
+select fn_db_add_config_value('GlusterRefreshRateHeavy', '300', 'general');
 
 
------------------------------------------------------------------------------------
 --                  Update with override section
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java
index 7152106..86fe569 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/InitBackendServicesOnStartupBean.java
@@ -7,6 +7,7 @@
 import javax.ejb.Singleton;
 import javax.ejb.Startup;
 
+import org.ovirt.engine.core.bll.gluster.GlusterManager;
 import org.ovirt.engine.core.bll.storage.StoragePoolStatusHandler;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
@@ -30,6 +31,7 @@
      * This method is called upon the bean creation as part
      * of the management Service bean life cycle.
      */
+    @Override
     @PostConstruct
     public void create() {
         log.infoFormat("InitResourceManager: {0}", new Date());
@@ -52,6 +54,8 @@
         });
         StoragePoolStatusHandler.Init();
 
+        GlusterManager.getInstance().init();
+        log.infoFormat("GlusterManager: {0}", new Date());
     }
 
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterManager.java
new file mode 100644
index 0000000..980507e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterManager.java
@@ -0,0 +1,380 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.ovirt.engine.core.bll.utils.ClusterUtils;
+import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.VDSGroup;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickStatus;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeOptionEntity;
+import org.ovirt.engine.core.common.businessentities.gluster.TransportType;
+import org.ovirt.engine.core.common.config.Config;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.common.utils.gluster.GlusterCoreUtil;
+import 
org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumesListVDSParameters;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
+import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;
+import org.ovirt.engine.core.dao.VdsGroupDAO;
+import org.ovirt.engine.core.dao.gluster.GlusterBrickDao;
+import org.ovirt.engine.core.dao.gluster.GlusterOptionDao;
+import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation;
+import org.ovirt.engine.core.utils.timer.SchedulerUtil;
+import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl;
+import org.ovirt.engine.core.vdsbroker.gluster.GlusterVolumesListVDSCommand;
+
+/**
+ * This class is responsible for keeping the Gluster related data of engine in 
sync with the actual data retrieved from
+ * GlusterFS. This helps to make sure that any changes done on Gluster servers 
using the Gluster CLI are propagated to
+ * engine as well.
+ */
+public class GlusterManager {
+    private static GlusterManager instance = new GlusterManager();
+    private static Log log = LogFactory.getLog(GlusterManager.class);
+    private static final int GLUSTER_REFRESH_RATE_LIGHT =
+            Config.<Integer> GetValue(ConfigValues.GlusterRefreshRateLight);
+    private static final int GLUSTER_REFRESH_RATE_HEAVY =
+            Config.<Integer> GetValue(ConfigValues.GlusterRefreshRateHeavy);
+    private static final VdsGroupDAO clusterDao = 
DbFacade.getInstance().getVdsGroupDAO();
+    private static final GlusterVolumeDao volumeDao = 
DbFacade.getInstance().getGlusterVolumeDao();
+    private static final GlusterOptionDao optionDao = 
DbFacade.getInstance().getGlusterOptionDao();
+    private static final GlusterBrickDao brickDao = 
DbFacade.getInstance().getGlusterBrickDao();
+
+    public static GlusterManager getInstance() {
+        return instance;
+    }
+
+    public void init() {
+        log.debug("Initializing Gluster Manager");
+
+        SchedulerUtil scheduler = SchedulerUtilQuartzImpl.getInstance();
+
+        scheduler.scheduleAFixedDelayJob(this,
+                "refreshLightWeightData",
+                new Class[0],
+                new Object[0],
+                GLUSTER_REFRESH_RATE_LIGHT,
+                GLUSTER_REFRESH_RATE_LIGHT,
+                TimeUnit.SECONDS);
+
+        scheduler.scheduleAFixedDelayJob(this,
+                "refreshHeavyWeightData",
+                new Class[0],
+                new Object[0],
+                GLUSTER_REFRESH_RATE_HEAVY,
+                GLUSTER_REFRESH_RATE_HEAVY,
+                TimeUnit.SECONDS);
+    }
+
+    /**
+     * Refreshes details of all volume across all clusters being managed in 
the engine. It can end up doing the
+     * following in engine DB to make sure that the volume details in engine 
DB are in sync with GlusterFS:<br>
+     * <li>Insert volumes</li><li>Delete volumes</li><li>Update properties of 
volume e.g. status, volume type</li><li>
+     * Add / remove bricks to / from volumes</li><li>Set / Unset volume 
options</li><br>
+     * These are all fetched using the 'volume info' command on gluster CLI, 
which is relatively lightweight, and hence
+     * this method is scheduled more frequently as compared to the other 
method <code>refreshHeavyWeightData</code>,
+     * which uses 'volume status' to fetch and update status of volume bricks.
+     */
+    @OnTimerMethodAnnotation("refreshLightWeightData")
+    public void refreshLightWeightData() {
+        log.info("Refreshing Gluster Data [lightweight]");
+        List<VDSGroup> clusters = clusterDao.getAll();
+
+        for (VDSGroup cluster : clusters) {
+            log.debugFormat("Refreshing Gluter Data for cluster {0}", 
cluster.getname());
+            refreshClusterData(cluster);
+        }
+    }
+
+    private void refreshClusterData(VDSGroup cluster) {
+        VDS upServer = getClusterUtils().getUpServer(cluster.getId());
+        if (upServer == null) {
+            log.warnFormat("No server UP in cluster {0}. Can't refresh it's 
data at this point.", cluster.getname());
+            return;
+        }
+
+        refreshVolumeData(cluster, upServer);
+        refreshServerData(cluster, upServer);
+    }
+
+    private void refreshServerData(VDSGroup cluster, VDS upServer) {
+        /*
+         * TODO: Fetch all servers from the gluster cluster, compare with 
servers of the cluster from engine DB, remove
+         * any servers that have been removed directly using gluster CLI. If 
any servers have been added using gluster
+         * CLI, mark the cluster so that such servers can be displayed to user 
in GUI and adder after approval. This
+         * code will be added after the VDS command for fetching servers of a 
gluster cluster is available. (It is being
+         * developed as part of a different feature)
+         */
+    }
+
+    private void refreshVolumeData(VDSGroup cluster, VDS upServer) {
+        GlusterVolumesListVDSCommand<GlusterVolumesListVDSParameters> 
volumesListCommand =
+                new 
GlusterVolumesListVDSCommand<GlusterVolumesListVDSParameters>(new 
GlusterVolumesListVDSParameters(upServer.getId(),
+                        upServer.getvds_group_id()));
+
+        @SuppressWarnings("unchecked")
+        Map<String, GlusterVolumeEntity> volumesMap =
+                (Map<String, GlusterVolumeEntity>) 
volumesListCommand.ExecuteWithReturnValue();
+
+        updateExistingAndNewVolumes(cluster.getId(), volumesMap);
+        removeDeletedVolumes(cluster.getId(), volumesMap);
+    }
+
+    private void removeDeletedVolumes(Guid clusterId, Map<String, 
GlusterVolumeEntity> volumesMap) {
+        for (GlusterVolumeEntity volume : volumeDao.getByClusterId(clusterId)) 
{
+            if (!volumesMap.containsKey(volume.getName())) {
+                log.debugFormat("Volume {0} has been removed directly using 
the gluster CLI. Removing it from engine as well.",
+                        volume.getName());
+                volumeDao.remove(volume.getId());
+                logVolumeMessage(volume, 
AuditLogType.GLUSTER_VOLUME_DELETED_FROM_CLI);
+            }
+        }
+    }
+
+    private void updateExistingAndNewVolumes(Guid clusterId, Map<String, 
GlusterVolumeEntity> volumesMap) {
+        for (Entry<String, GlusterVolumeEntity> entry : volumesMap.entrySet()) 
{
+            GlusterVolumeEntity volume = entry.getValue();
+            log.debugFormat("Analyzing volume {0}", volume.getName());
+
+            GlusterVolumeEntity existingVolume = 
volumeDao.getByName(clusterId, volume.getName());
+            if (existingVolume == null) {
+                log.infoFormat("Volume {0} Not present in engine. Creating the 
same.", volume.getName());
+                createVolume(volume);
+            } else {
+                log.debugFormat("Volume {0} exists in engine. Checking if it 
needs to be updated.",
+                        existingVolume.getName());
+                updateVolume(existingVolume, volume);
+            }
+        }
+    }
+
+    /**
+     * Creates a new volume in engine
+     *
+     * @param volume
+     */
+    private void createVolume(final GlusterVolumeEntity volume) {
+        for (GlusterBrickEntity brick : volume.getBricks()) {
+            if (brick.getServerId() == null) {
+                log.warnFormat("Volume {0} contains brick(s) from unknown 
hosts. Hence will not add it to engine at this point.",
+                        volume.getName());
+                return;
+            }
+        }
+
+        log.debugFormat("Volume {0} has been created directly using the 
gluster CLI. Creating it in engine as well.",
+                volume.getName());
+        volumeDao.save(volume);
+        logVolumeMessage(volume, AuditLogType.GLUSTER_VOLUME_CREATED_FROM_CLI);
+    }
+
+    @SuppressWarnings("serial")
+    private void logVolumeMessage(final GlusterVolumeEntity volume, final 
AuditLogType logType) {
+        AuditLogDirector.log(new AuditLogableBase() {
+            @Override
+            protected GlusterVolumeEntity getGlusterVolume() {
+                return volume;
+            }
+
+            @Override
+            public AuditLogType getAuditLogTypeValue() {
+                return logType;
+            }
+        });
+    }
+
+    private void updateVolume(GlusterVolumeEntity existingVolume, 
GlusterVolumeEntity fetchedVolume) {
+        updateVolumeProperties(existingVolume, fetchedVolume);
+        updateBricks(existingVolume, fetchedVolume);
+        updateOptions(existingVolume, fetchedVolume);
+        updateTransportTypes(existingVolume, fetchedVolume);
+    }
+
+    private void updateTransportTypes(GlusterVolumeEntity existingVolume, 
GlusterVolumeEntity fetchedVolume) {
+        Set<TransportType> existingTransportTypes = 
existingVolume.getTransportTypes();
+        Set<TransportType> fetchedTransportTypes = 
fetchedVolume.getTransportTypes();
+        if (GlusterCoreUtil.listsEqual(existingTransportTypes, 
fetchedTransportTypes)) {
+            // transport types not changed. return without updating DB.
+            return;
+        }
+
+        Collection<TransportType> addedTransportTypes =
+                GlusterCoreUtil.getAddedElements(existingTransportTypes, 
fetchedTransportTypes);
+        if (!addedTransportTypes.isEmpty()) {
+            log.infoFormat("Adding transport type(s) {0} to volume {1}",
+                    addedTransportTypes,
+                    existingVolume.getName());
+            volumeDao.addTransportTypes(existingVolume.getId(), 
addedTransportTypes);
+        }
+
+        Collection<TransportType> removedTransportTypes =
+                GlusterCoreUtil.getAddedElements(fetchedTransportTypes, 
existingTransportTypes);
+        if (!removedTransportTypes.isEmpty()) {
+            log.infoFormat("Removing transport type(s) {0} from volume {1}",
+                    removedTransportTypes,
+                    existingVolume.getName());
+            volumeDao.removeTransportTypes(existingVolume.getId(), 
removedTransportTypes);
+        }
+    }
+
+    private void updateBricks(GlusterVolumeEntity existingVolume, 
GlusterVolumeEntity fetchedVolume) {
+        List<GlusterBrickEntity> fetchedBricks = fetchedVolume.getBricks();
+
+        updateExistingAndNewBricks(existingVolume, fetchedBricks);
+        removeDeletedBricks(existingVolume, fetchedBricks);
+    }
+
+    private void removeDeletedBricks(GlusterVolumeEntity existingVolume, 
List<GlusterBrickEntity> fetchedBricks) {
+        for (GlusterBrickEntity existingBrick : existingVolume.getBricks()) {
+            if (!GlusterCoreUtil.containsBrick(fetchedBricks, existingBrick)) {
+                log.infoFormat("Brick {0} removed from volume {1} from CLI. 
Removing it from engine DB as well.",
+                        existingBrick.getQualifiedName(),
+                        existingVolume.getName());
+                brickDao.removeBrick(existingBrick.getId());
+                logVolumeMessage(existingVolume, 
AuditLogType.GLUSTER_VOLUME_BRICK_REMOVED_FROM_CLI);
+            }
+        }
+    }
+
+    private void updateExistingAndNewBricks(GlusterVolumeEntity 
existingVolume, List<GlusterBrickEntity> fetchedBricks) {
+        for (GlusterBrickEntity fetchedBrick : fetchedBricks) {
+            GlusterBrickEntity existingBrick = 
GlusterCoreUtil.findBrick(existingVolume.getBricks(), fetchedBrick);
+            if (existingBrick == null) {
+                // server id could be null if the new brick resides on a 
server that is not yet added in the engine
+                // adding such servers to engine required manual approval by 
user, and hence can't be automated.
+                if (fetchedBrick.getServerId() != null) {
+                    log.infoFormat("New brick {0} added to volume {1} from 
gluster CLI. Updating engine DB accordingly.",
+                            fetchedBrick.getQualifiedName(),
+                            existingVolume.getName());
+                    fetchedBrick.setStatus(existingVolume.isOnline() ? 
GlusterBrickStatus.UP : GlusterBrickStatus.DOWN);
+                    brickDao.save(fetchedBrick);
+                    logVolumeMessage(existingVolume, 
AuditLogType.GLUSTER_VOLUME_BRICK_ADDED_FROM_CLI);
+                }
+            } else {
+                // brick found. update it if required. Only property that 
could be different is the brick order
+                if (existingBrick.getBrickOrder() != 
fetchedBrick.getBrickOrder()) {
+                    log.infoFormat("Brick order for brick {0} changed from {1} 
to {2} because of direct CLI operations. Updating engine DB accordingly.",
+                            existingBrick.getQualifiedName(),
+                            existingBrick.getBrickOrder(),
+                            fetchedBrick.getBrickOrder());
+                    brickDao.updateBrickOrder(existingBrick.getId(), 
fetchedBrick.getBrickOrder());
+                }
+            }
+        }
+    }
+
+    private void updateOptions(GlusterVolumeEntity existingVolume, 
GlusterVolumeEntity fetchedVolume) {
+        Collection<GlusterVolumeOptionEntity> existingOptions = 
existingVolume.getOptions();
+        Collection<GlusterVolumeOptionEntity> fetchedOptions = 
fetchedVolume.getOptions();
+
+        updateExistingAndNewOptions(existingVolume, fetchedOptions);
+        removeDeletedOptions(fetchedVolume, existingOptions);
+    }
+
+    private void removeDeletedOptions(GlusterVolumeEntity fetchedVolume,
+            Collection<GlusterVolumeOptionEntity> existingOptions) {
+        for (GlusterVolumeOptionEntity existingOption : existingOptions) {
+            if (fetchedVolume.getOption(existingOption.getKey()) == null) {
+                log.infoFormat("Option {0} unset on volume {1} from CLI. 
Removing it from engine DB as well.",
+                        existingOption.getKey(),
+                        fetchedVolume.getName());
+                optionDao.removeVolumeOption(existingOption.getId());
+                logVolumeMessage(fetchedVolume, 
AuditLogType.GLUSTER_VOLUME_OPTION_RESET_FROM_CLI);
+            }
+        }
+    }
+
+    private void updateExistingAndNewOptions(GlusterVolumeEntity 
existingVolume,
+            Collection<GlusterVolumeOptionEntity> fetchedOptions) {
+        for (GlusterVolumeOptionEntity fetchedOption : fetchedOptions) {
+            GlusterVolumeOptionEntity existingOption = 
existingVolume.getOption(fetchedOption.getKey());
+            if (existingOption == null) {
+                log.infoFormat("New option {0}={1} set on volume {2} from 
gluster CLI. Updating engine DB accordingly.",
+                        fetchedOption.getKey(),
+                        fetchedOption.getValue(),
+                        existingVolume.getName());
+                optionDao.save(fetchedOption);
+                logVolumeMessage(existingVolume, 
AuditLogType.GLUSTER_VOLUME_OPTION_SET_FROM_CLI);
+            } else if 
(!existingOption.getValue().equals(fetchedOption.getValue())) {
+                log.infoFormat("Value of option {0} changed from {1} to {2} 
from CLI. Updating engine DB accordingly.",
+                        fetchedOption.getKey(),
+                        fetchedOption.getValue(),
+                        existingOption.getValue());
+                logVolumeMessage(existingVolume, 
AuditLogType.GLUSTER_VOLUME_OPTION_SET_FROM_CLI);
+            }
+        }
+    }
+
+    /**
+     * Updates basic properties of the volume. Does not include bricks, 
options, and transport types
+     *
+     * @param existingVolume
+     *            Volume that is to be updated
+     * @param fetchedVolume
+     *            Volume fetched from GlusterFS, containing latest properties
+     */
+    @SuppressWarnings("incomplete-switch")
+    public void updateVolumeProperties(GlusterVolumeEntity existingVolume, 
GlusterVolumeEntity fetchedVolume) {
+        boolean changed = false;
+
+        if (existingVolume.getVolumeType() != fetchedVolume.getVolumeType()) {
+            existingVolume.setVolumeType(fetchedVolume.getVolumeType());
+            changed = true;
+        }
+
+        switch (existingVolume.getVolumeType()) {
+        case REPLICATE:
+        case DISTRIBUTED_REPLICATE:
+            if (existingVolume.getReplicaCount() != 
fetchedVolume.getReplicaCount()) {
+                
existingVolume.setReplicaCount(fetchedVolume.getReplicaCount());
+                changed = true;
+            }
+            break;
+        case STRIPE:
+        case DISTRIBUTED_STRIPE:
+            if (existingVolume.getStripeCount() != 
fetchedVolume.getStripeCount()) {
+                existingVolume.setStripeCount(fetchedVolume.getStripeCount());
+                changed = true;
+            }
+            break;
+        }
+
+        if (existingVolume.getStatus() != fetchedVolume.getStatus()) {
+            existingVolume.setStatus(fetchedVolume.getStatus());
+            changed = true;
+        }
+
+        if (changed) {
+            log.infoFormat("Updating volume {0} with fetched properties.", 
existingVolume.getName());
+            volumeDao.updateGlusterVolume(existingVolume);
+            logVolumeMessage(existingVolume, 
AuditLogType.GLUSTER_VOLUME_PROPERTIES_CHANGED_FROM_CLI);
+        }
+    }
+
+    /**
+     * Refreshes the brick statuses from GlusterFS. This method is scheduled 
less frequently as it uses the 'volume
+     * status' command, that adds significant overhead on Gluster processes, 
and hence should not be invoked too
+     * frequently.
+     */
+    @OnTimerMethodAnnotation("refreshHeavyWeightData")
+    public void refreshHeavyWeightData() {
+        log.debug("Refreshing Gluster Data [heavyweight]");
+        // TODO: Fetch and update brick statuses
+    }
+
+    private ClusterUtils getClusterUtils() {
+        return ClusterUtils.getInstance();
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/GlusterUtils.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/GlusterUtils.java
index c27d248..f9df0f7 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/GlusterUtils.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/utils/GlusterUtils.java
@@ -5,10 +5,13 @@
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.dao.gluster.GlusterBrickDao;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
 
 @Singleton
 public class GlusterUtils {
     private static GlusterUtils instance = null;
+    private static Log log = LogFactory.getLog(GlusterUtils.class);
 
     public static GlusterUtils getInstance() {
         if (instance == null) {
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
index 038b117..7993eb1 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
@@ -200,6 +200,13 @@
     GLUSTER_VOLUME_ADD_BRICK(4019),
     GLUSTER_VOLUME_ADD_BRICK_FAILED(4020),
     GLUSTER_HOST_REMOVE_FAILED(4021),
+    GLUSTER_VOLUME_CREATED_FROM_CLI(4022),
+    GLUSTER_VOLUME_DELETED_FROM_CLI(4023),
+    GLUSTER_VOLUME_OPTION_SET_FROM_CLI(4024),
+    GLUSTER_VOLUME_OPTION_RESET_FROM_CLI(4025),
+    GLUSTER_VOLUME_PROPERTIES_CHANGED_FROM_CLI(4026),
+    GLUSTER_VOLUME_BRICK_ADDED_FROM_CLI(4027),
+    GLUSTER_VOLUME_BRICK_REMOVED_FROM_CLI(4028),
     GLUSTER_HOST_ADD_FAILED(4404),
 
 
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterBrickEntity.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterBrickEntity.java
index b292d10..414aa80 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterBrickEntity.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterBrickEntity.java
@@ -125,9 +125,10 @@
 
         GlusterBrickEntity brick = (GlusterBrickEntity) obj;
         return (getId().equals(brick.getId())
-                && (GlusterCoreUtil.objectsEqual(volumeId, 
brick.getVolumeId()))
-                && (GlusterCoreUtil.objectsEqual(serverId, 
brick.getServerId()))
-                && (GlusterCoreUtil.objectsEqual(brickDirectory, 
brick.getBrickDirectory()))
+                && GlusterCoreUtil.objectsEqual(volumeId, brick.getVolumeId())
+                && GlusterCoreUtil.objectsEqual(serverId, brick.getServerId())
+                && GlusterCoreUtil.objectsEqual(brickDirectory, 
brick.getBrickDirectory())
+                && GlusterCoreUtil.objectsEqual(brickOrder, 
brick.getBrickOrder())
                 && status == brick.getStatus());
     }
 
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeEntity.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeEntity.java
index 1df99da..092bff9 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeEntity.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterVolumeEntity.java
@@ -376,8 +376,8 @@
         if (!(name.equals(volume.getName())
                 && volumeType == volume.getVolumeType()
                 && status == volume.getStatus()
-                && equalIntegers(replicaCount, volume.getReplicaCount())
-                && equalIntegers(stripeCount, volume.getStripeCount()))) {
+                && GlusterCoreUtil.objectsEqual(replicaCount, 
volume.getReplicaCount())
+                && GlusterCoreUtil.objectsEqual(stripeCount, 
volume.getStripeCount()))) {
             return false;
         }
 
@@ -407,14 +407,6 @@
             }
         }
         return null;
-    }
-
-    private boolean equalIntegers(Integer int1, Integer int2) {
-        if(int1 == null) {
-            return int2 == null;
-        } else {
-            return int1.equals(int2);
-        }
     }
 
     @Override
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
index 6998a43..011420c 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
@@ -1405,6 +1405,22 @@
     )
     BootstrapNodeIDCommand(372),
 
+    /**
+     * Refresh rate (in seconds) for light-weight gluster data i.e. data that 
can be fetched without much of an overhead
+     * on the GlusterFS processes
+     */
+    @TypeConverterAttribute(Integer.class)
+    @DefaultValueAttribute("5")
+    GlusterRefreshRateLight(373),
+
+    /**
+     * Refresh rate (in seconds) for heavy-weight gluster data i.e. commands 
to fetch such data adds a considerable
+     * overhead on the GlusterFS processes.
+     */
+    @TypeConverterAttribute(Integer.class)
+    @DefaultValueAttribute("300")
+    GlusterRefreshRateHeavy(374),
+
     Invalid(65535);
 
     private int intValue;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/gluster/GlusterCoreUtil.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/gluster/GlusterCoreUtil.java
index 990e3ac..3913819 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/gluster/GlusterCoreUtil.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/gluster/GlusterCoreUtil.java
@@ -30,6 +30,24 @@
     }
 
     /**
+     * Returns a collection of elements that are not present in 
<code>oldList</code>, but present in
+     * <code>newList</code>
+     *
+     * @param oldList
+     * @param newList
+     * @return collection of elements that are not present in 
<code>oldList</code>, but present in <code>newList</code>
+     */
+    public static <T> Collection<T> getAddedElements(Collection<T> oldList, 
Collection<T> newList) {
+        List<T> addedElements = new ArrayList<T>();
+        for (T element : newList) {
+            if (!oldList.contains(element)) {
+                addedElements.add(element);
+            }
+        }
+        return addedElements;
+    }
+
+    /**
      * Compares if two objects are equal, handling the cases where one of both 
of them may be null
      * @param obj1
      * @param obj2
@@ -59,4 +77,34 @@
         }
         return qualifiedBricks;
     }
+
+    /**
+     * Checks if given brick <code>searchBrick</code> exists in the given 
collection of bricks. Note that this method
+     * checks only two (and most important) attributes of the brick: server id 
and brick directory
+     *
+     * @param bricks
+     * @param searchBrick
+     * @return true of the given <code>searchBrick</code> exists in the given 
collection of bricks, else false
+     */
+    public static boolean containsBrick(Collection<GlusterBrickEntity> bricks, 
GlusterBrickEntity searchBrick) {
+        return (findBrick(bricks, searchBrick) != null);
+    }
+
+    /**
+     * Checks if given brick <code>searchBrick</code> exists in the given 
collection of bricks, and returns it if found. Note that this method
+     * checks only two (and most important) attributes of the brick: server id 
and brick directory.
+     *
+     * @param bricks
+     * @param searchBrick
+     * @return the brick if found in the <code>bricks</code> collection, else 
null.
+     */
+    public static GlusterBrickEntity findBrick(Collection<GlusterBrickEntity> 
bricks, GlusterBrickEntity searchBrick) {
+        for (GlusterBrickEntity brick : bricks) {
+            if (brick.getServerId().equals(searchBrick.getServerId())
+                    && 
brick.getBrickDirectory().equals(searchBrick.getBrickDirectory())) {
+                return brick;
+            }
+        }
+        return null;
+    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java
index a770eff..1c583b1 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java
@@ -135,7 +135,8 @@
     AddBricksToGlusterVolume("org.ovirt.engine.core.vdsbroker.gluster"),
     ReplaceGlusterVolumeBrick("org.ovirt.engine.core.vdsbroker.gluster"),
     GlusterHostRemove("org.ovirt.engine.core.vdsbroker.gluster"),
-    GlusterHostAdd("org.ovirt.engine.core.vdsbroker.gluster");
+    GlusterHostAdd("org.ovirt.engine.core.vdsbroker.gluster"),
+    GlusterVolumesList("org.ovirt.engine.core.vdsbroker.gluster")
     ;
 
     String packageName;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/gluster/GlusterVolumesListVDSParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/gluster/GlusterVolumesListVDSParameters.java
new file mode 100644
index 0000000..a660979
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/gluster/GlusterVolumesListVDSParameters.java
@@ -0,0 +1,21 @@
+package org.ovirt.engine.core.common.vdscommands.gluster;
+
+import org.ovirt.engine.core.common.vdscommands.VdsIdVDSCommandParametersBase;
+import org.ovirt.engine.core.compat.Guid;
+
+/**
+ * VDS parameters class with Server ID and Cluster ID as parameters, Used by 
the "Gluster Volumes List" command.
+ */
+public class GlusterVolumesListVDSParameters extends 
VdsIdVDSCommandParametersBase {
+
+    private Guid clusterId;
+
+    public GlusterVolumesListVDSParameters(Guid serverId, Guid clusterId) {
+        super(serverId);
+        this.clusterId = clusterId;
+    }
+
+    public Guid getClusterId() {
+        return clusterId;
+    }
+}
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDao.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDao.java
index 2fac4b2..bcf2c6c 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDao.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDao.java
@@ -1,5 +1,6 @@
 package org.ovirt.engine.core.dao.gluster;
 
+import java.util.Collection;
 import java.util.List;
 
 import org.ovirt.engine.core.common.businessentities.gluster.AccessProtocol;
@@ -40,8 +41,12 @@
 
     public void addTransportType(Guid volumeId, TransportType transportType);
 
+    public void addTransportTypes(Guid volumeId, Collection<TransportType> 
transportTypes);
+
     public void removeTransportType(Guid volumeId, TransportType 
transportType);
 
+    public void removeTransportTypes(Guid volumeId, Collection<TransportType> 
transportTypes);
+
     public void updateReplicaCount(Guid volumeId, int replicaCount);
 
     public void updateStripeCount(Guid volumeId, int stripeCount);
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDaoDbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDaoDbFacadeImpl.java
index b52c16f..d56a8c9 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDaoDbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/gluster/GlusterVolumeDaoDbFacadeImpl.java
@@ -289,4 +289,18 @@
                         .addValue("replica_count", volume.getReplicaCount())
                         .addValue("stripe_count", volume.getStripeCount()));
     }
+
+    @Override
+    public void addTransportTypes(Guid volumeId, Collection<TransportType> 
transportTypes) {
+        for (TransportType transportType : transportTypes) {
+            addTransportType(volumeId, transportType);
+        }
+    }
+
+    @Override
+    public void removeTransportTypes(Guid volumeId, Collection<TransportType> 
transportTypes) {
+        for (TransportType transportType : transportTypes) {
+            removeTransportType(volumeId, transportType);
+        }
+    }
 }
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
index ee5b2ea..326df69 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
@@ -540,5 +540,12 @@
 GLUSTER_VOLUME_ADD_BRICK_FAILED=Gluster Volume ${glusterVolumeName} add brick 
failed.
 GLUSTER_HOST_ADD_FAILED=Failed to add gluster server ${VdsName} into Cluster 
${VdsGroupName}.
 GLUSTER_HOST_REMOVE_FAILED=Failed to remove gluster server ${VdsName} from 
Cluster ${VdsGroupName}.
+GLUSTER_VOLUME_CREATED_FROM_CLI=Gluster Volume ${glusterVolumeName} was 
created from gluster CLI. Now added to engine DB as well.
+GLUSTER_VOLUME_DELETED_FROM_CLI=Gluster Volume ${glusterVolumeName} was 
deleted from gluster CLI. Now deleted from engine DB as well.
+GLUSTER_VOLUME_OPTION_SET_FROM_CLI=Gluster Volume ${glusterVolumeName} option 
was set from gluster CLI. Now set in engine DB as well.
+GLUSTER_VOLUME_OPTION_RESET_FROM_CLI=Gluster Volume ${glusterVolumeName} 
option was reset from gluster CLI. Now reset in engine DB as well.
+GLUSTER_VOLUME_PROPERTIES_CHANGED_FROM_CLI=Gluster Volume ${glusterVolumeName} 
properties were changed from CLI. Now updated in engine DB as well.
+GLUSTER_VOLUME_BRICK_ADDED_FROM_CLI=Gluster Volume ${glusterVolumeName} brick 
was added from gluster CLI. Now added in engine DB as well.
+GLUSTER_VOLUME_BRICK_REMOVED_FROM_CLI=Gluster Volume ${glusterVolumeName} 
brick was removed from gluster CLI. Now removed in engine DB as well.
 HA_VM_FAILED=Highly Available VM ${VmName} failed. It will be restarted 
automatically.
 HA_VM_RESTART_FAILED=Restart of the Highly Available VM ${VmName} failed.
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListReturnForXmlRpc.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListReturnForXmlRpc.java
new file mode 100644
index 0000000..dd676d1
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListReturnForXmlRpc.java
@@ -0,0 +1,176 @@
+package org.ovirt.engine.core.vdsbroker.gluster;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.ovirt.engine.core.common.businessentities.VDS;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeStatus;
+import org.ovirt.engine.core.common.businessentities.gluster.TransportType;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dao.VdsDAO;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+import org.ovirt.engine.core.vdsbroker.irsbroker.StatusReturnForXmlRpc;
+
+/**
+ * The XmlRpc return type to receive a list of gluster volumes. The 
constructor takes cluster id as well, so that
+ * correct host can be identified when populating the bricks of a volume
+ */
+public final class GlusterVolumesListReturnForXmlRpc extends 
StatusReturnForXmlRpc {
+    private static final String VOLUMES = "volumes";
+    private static final String VOLUME_NAME = "volumeName";
+    private static final String UUID = "uuid";
+    private static final String VOLUME_TYPE = "volumeType";
+    private static final String TRANSPORT_TYPE = "transportType";
+    private static final String VOLUME_STATUS = "volumeStatus";
+    private static final String BRICKS = "bricks";
+    private static final String OPTIONS = "options";
+    private static final String VOLUME_STATUS_ONLINE = "ONLINE";
+    private static final String REPLICA_COUNT = "replicaCount";
+    private static final String STRIPE_COUNT = "stripeCount";
+
+    private Guid clusterId;
+    private Map<String, GlusterVolumeEntity> volumes = new HashMap<String, 
GlusterVolumeEntity>();
+    private static Log log = 
LogFactory.getLog(GlusterVolumesListReturnForXmlRpc.class);
+
+    @SuppressWarnings("unchecked")
+    public GlusterVolumesListReturnForXmlRpc(Guid clusterId, Map<String, 
Object> innerMap) {
+        super(innerMap);
+        this.clusterId = clusterId;
+        Map<String, Object> volumesMap = (Map<String, Object>) 
innerMap.get(VOLUMES);
+
+        for (Entry<String, Object> entry : volumesMap.entrySet()) {
+            log.debugFormat("received volume {0}", entry.getKey());
+
+            volumes.put(entry.getKey(), getVolume((Map<String, 
Object>)entry.getValue()));
+        }
+    }
+
+    @SuppressWarnings({ "unchecked", "incomplete-switch" })
+    private GlusterVolumeEntity getVolume(Map<String, Object> map) {
+        GlusterVolumeEntity volume = new GlusterVolumeEntity();
+
+        volume.setClusterId(clusterId);
+        volume.setId(Guid.createGuidFromString((String)map.get(UUID)));
+        volume.setName((String)map.get(VOLUME_NAME));
+        volume.setVolumeType((String)map.get(VOLUME_TYPE));
+
+        switch (volume.getVolumeType()) {
+        case REPLICATE:
+        case DISTRIBUTED_REPLICATE:
+            volume.setReplicaCount(Integer.valueOf((String) 
map.get(REPLICA_COUNT)));
+            break;
+        case STRIPE:
+        case DISTRIBUTED_STRIPE:
+            volume.setStripeCount(Integer.valueOf((String) 
map.get(STRIPE_COUNT)));
+            break;
+        }
+
+        for(Object transportType : (Object[])map.get(TRANSPORT_TYPE)) {
+            
volume.addTransportType(TransportType.valueOf((String)transportType));
+        }
+
+        String volStatus = (String)map.get(VOLUME_STATUS);
+        if(volStatus.toUpperCase().equals(VOLUME_STATUS_ONLINE)) {
+            volume.setStatus(GlusterVolumeStatus.UP);
+        } else {
+            volume.setStatus(GlusterVolumeStatus.DOWN);
+        }
+
+        try {
+            volume.setBricks(getBricks(volume.getId(), 
(Object[])map.get(BRICKS)));
+        } catch (Exception e) {
+            log.errorFormat("Could not populate bricks of volume {0} on 
cluster {1}.", volume.getName(), clusterId, e);
+        }
+        volume.setOptions(getOptions((Map<String, Object>)map.get(OPTIONS)));
+
+        return volume;
+    }
+
+    private Map<String, String> getOptions(Map<String, Object> map) {
+        Map<String, String> options = new HashMap<String, String>();
+        for(Entry<String, Object> entry : map.entrySet()) {
+            options.put(entry.getKey(), (String)entry.getValue());
+        }
+        return options;
+    }
+
+    private List<GlusterBrickEntity> getBricks(Guid volumeId, Object[] 
brickList) throws Exception {
+        List<GlusterBrickEntity> bricks = new ArrayList<GlusterBrickEntity>();
+
+        int brickOrder = 0;
+        for(Object brick : brickList) {
+            bricks.add(getBrick(clusterId, volumeId, (String)brick, 
brickOrder++));
+        }
+
+        return bricks;
+    }
+
+    /**
+     * Returns a brick object for given cluster and brick representation of 
the form hostnameOrIp:brickDir
+     * @param clusterId ID of the Cluster to which the brick belongs
+     * @param volumeId ID of the Volume to which the brick belongs
+     * @param brickInfo brick representation of the form hostnameOrIp:brickDir
+     * @param brickOrder Order number of the brick
+     * @return The brick object if representation passed is valid
+     */
+    private GlusterBrickEntity getBrick(Guid clusterId, Guid volumeId, String 
brickInfo, int brickOrder) {
+        String[] brickParts = brickInfo.split(":", -1);
+        if(brickParts.length != 2) {
+            throw new RuntimeException("Invalid brick representation [" + 
brickInfo + "]");
+        }
+
+        String hostnameOrIp = brickParts[0];
+        String brickDir = brickParts[1];
+
+        GlusterBrickEntity brick = new GlusterBrickEntity();
+        brick.setVolumeId(volumeId);
+        brick.setBrickOrder(brickOrder);
+        brick.setBrickDirectory(brickDir);
+
+        VDS server = getServer(clusterId, hostnameOrIp);
+        if(server == null) {
+            log.warnFormat("Could not find server {0} in cluster {1}", 
hostnameOrIp, clusterId);
+        } else {
+            brick.setServerId(server.getId());
+        }
+        return brick;
+    }
+
+    private VdsDAO getVdsDao() {
+        return DbFacade.getInstance().getVdsDAO();
+    }
+
+    private VDS getServer(Guid clusterId, String hostnameOrIp) {
+        List<VDS> servers = getVdsDao().getAllWithIpAddress(hostnameOrIp);
+        if(servers.size() > 0) {
+            return getServerOfCluster(clusterId, servers);
+        }
+
+        servers = getVdsDao().getAllForHostname(hostnameOrIp);
+        if(servers.size() > 0) {
+            return getServerOfCluster(clusterId, servers);
+        }
+
+        return null;
+    }
+
+    private VDS getServerOfCluster(Guid clusterId, List<VDS> servers) {
+        for(VDS server : servers) {
+            if(server.getvds_group_id().equals(clusterId)) {
+                return server;
+            }
+        }
+        return null;
+    }
+
+    public Map<String, GlusterVolumeEntity> getVolumes() {
+        return volumes;
+    }
+}
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListVDSCommand.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListVDSCommand.java
new file mode 100644
index 0000000..2187a1a
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/GlusterVolumesListVDSCommand.java
@@ -0,0 +1,24 @@
+package org.ovirt.engine.core.vdsbroker.gluster;
+
+import 
org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumesListVDSParameters;
+import org.ovirt.engine.core.vdsbroker.vdsbroker.StatusForXmlRpc;
+
+public class GlusterVolumesListVDSCommand<P extends 
GlusterVolumesListVDSParameters> extends AbstractGlusterBrokerCommand<P> {
+    private GlusterVolumesListReturnForXmlRpc result;
+
+    public GlusterVolumesListVDSCommand(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected StatusForXmlRpc getReturnStatus() {
+        return result.mStatus;
+    }
+
+    @Override
+    protected void ExecuteVdsBrokerCommand() {
+        result = 
getBroker().glusterVolumesList(getParameters().getClusterId());
+        ProceedProxyReturnValue();
+        setReturnValue(result.getVolumes());
+    }
+}
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
index 1bc410a..32f3878 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java
@@ -4,6 +4,8 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
 
+import org.ovirt.engine.core.compat.Guid;
+import 
org.ovirt.engine.core.vdsbroker.gluster.GlusterVolumesListReturnForXmlRpc;
 import 
org.ovirt.engine.core.vdsbroker.irsbroker.GlusterVolumeOptionsInfoReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.irsbroker.IsoListReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.irsbroker.OneUuidReturnForXmlRpc;
@@ -233,4 +235,5 @@
 
     StatusOnlyReturnForXmlRpc glusterHostAdd(String hostName);
 
+    GlusterVolumesListReturnForXmlRpc glusterVolumesList(Guid clusterId);
 }
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
index d928caf..3b2aa33 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java
@@ -224,6 +224,8 @@
 
     public Map<String, Object> glusterHostAdd(String hostName);
 
+    public Map<String, Object> glusterVolumesList();
+
     public Map<String, Object> ping();
 
     @FutureCall(delegeteTo = "ping")
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
index b3cf60b..097e948 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java
@@ -6,6 +6,8 @@
 import java.util.concurrent.FutureTask;
 
 import org.apache.commons.httpclient.HttpClient;
+import org.ovirt.engine.core.compat.Guid;
+import 
org.ovirt.engine.core.vdsbroker.gluster.GlusterVolumesListReturnForXmlRpc;
 import 
org.ovirt.engine.core.vdsbroker.irsbroker.GlusterVolumeOptionsInfoReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.irsbroker.IsoListReturnForXmlRpc;
 import org.ovirt.engine.core.vdsbroker.irsbroker.OneUuidReturnForXmlRpc;
@@ -1136,4 +1138,15 @@
             throw new XmlRpcRunTimeException(ute);
         }
     }
+
+    @Override
+    public GlusterVolumesListReturnForXmlRpc glusterVolumesList(Guid 
clusterId) {
+        try {
+            Map<String, Object> xmlRpcReturnValue = 
vdsServer.glusterVolumesList();
+            GlusterVolumesListReturnForXmlRpc wrapper = new 
GlusterVolumesListReturnForXmlRpc(clusterId, xmlRpcReturnValue);
+            return wrapper;
+        } catch (UndeclaredThrowableException ute) {
+            throw new XmlRpcRunTimeException(ute);
+        }
+    }
 }


--
To view, visit http://gerrit.ovirt.org/7288
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6b61eb6e93105e46e2706eac1d94bc10717224c2
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Shireesh Anjal <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to