Sahina Bose has uploaded a new change for review.

Change subject: engine: Support for gluster asynchronous tasks(WIP)
......................................................................

engine: Support for gluster asynchronous tasks(WIP)

Gluster commands like rebalance volume, replace bricks are async tasks that
can be started from the console but are long running. These gluster tasks need 
to be
polled periodically and the status updated in the task manager UI (through job 
and
steps)

All gluster commands that create asynchronous tasks to extend
from AsyncGlusterCommandBase. This class will create a sub-step for the
executing step and associate the step with external task id (returned from 
gluster)

GlusterTaskManager periodically polls all running gluster tasks and updates
the corresponding step and job with status and description

Note:The underlying task support is not yet complete in GlusterFS and VDSM, so
the dummy class GlusterTaskStatusUtil mocks this behaviour for now.

Change-Id: I8a56785edef091bce74e2b7b0ba9a3314f1397f1
Bug-Url: https://bugzilla.redhat.com/850422
Signed-off-by: Sahina Bose <sah...@gmail.com>
---
M backend/manager/dbscripts/job_sp.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/AsyncGlusterCommandBase.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterAsyncCommandBase.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskManager.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskStatusUtil.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RebalanceGlusterVolumeCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartRebalanceGlusterVolumeCommand.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterAsyncTask.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskStatus.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/ExternalSystemType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDao.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDaoDbFacadeImpl.java
M 
backend/manager/modules/dal/src/main/resources/bundles/ExecutionMessages.properties
M 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/StartRebalanceGlusterVolumeVDSCommand.java
A 
backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GlusterTaskInfoReturnForXmlRpc.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/VdsServerWrapper.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
22 files changed, 628 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/40/11840/1

diff --git a/backend/manager/dbscripts/job_sp.sql 
b/backend/manager/dbscripts/job_sp.sql
index f10cc76..ea40ef3 100644
--- a/backend/manager/dbscripts/job_sp.sql
+++ b/backend/manager/dbscripts/job_sp.sql
@@ -489,7 +489,20 @@
         FROM   step
         WHERE  job_id = v_job_id
         AND    external_id is not null
-        AND    external_system_type = 'VDSM');
+        AND    external_system_type in ('VDSM','GLUSTER'));
 END; $procedure$
 LANGUAGE plpgsql;
 
+----------------------------------------------------
+-- Gets Step entities list from Step table by external id
+----------------------------------------------------
+Create or replace FUNCTION GetStepsByJobId(v_external_id UUID)
+RETURNS SETOF step
+AS $procedure$
+BEGIN
+    RETURN QUERY SELECT step.*
+    FROM step
+    WHERE external_id = v_external_id
+    ORDER BY parent_step_id nulls first, step_number;
+END; $procedure$
+LANGUAGE plpgsql;
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 789cf38..694ce7d 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.Startup;
 
 import org.ovirt.engine.core.bll.gluster.GlusterManager;
+import org.ovirt.engine.core.bll.gluster.GlusterTaskManager;
 import org.ovirt.engine.core.bll.network.MacPoolManager;
 import org.ovirt.engine.core.bll.storage.StoragePoolStatusHandler;
 import org.ovirt.engine.core.common.config.Config;
@@ -54,6 +55,7 @@
         StoragePoolStatusHandler.Init();
 
         GlusterManager.getInstance().init();
+        GlusterTaskManager.getInstance().init();
         try {
             log.info("Init VM custom properties utilities");
             VmPropertiesUtils.getInstance().init();
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/AsyncGlusterCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/AsyncGlusterCommandBase.java
new file mode 100644
index 0000000..1dc1da6
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/AsyncGlusterCommandBase.java
@@ -0,0 +1,59 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import org.ovirt.engine.core.common.action.VdcActionParametersBase;
+import org.ovirt.engine.core.common.businessentities.IVdsAsyncCommand;
+import org.ovirt.engine.core.compat.Guid;
+
+public class AsyncGlusterCommandBase<T extends VdcActionParametersBase> 
extends GlusterCommandBase<T> implements IVdsAsyncCommand {
+
+    private static final long serialVersionUID = 1406288236903949986L;
+
+    public AsyncGlusterCommandBase(T params) {
+        super(params);
+        // TODO Auto-generated constructor stub
+    }
+
+
+    @Override
+    public void rerun() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void runningSucceded() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public boolean getAutoStart() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Guid getAutoStartVdsId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void reportCompleted() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void onPowerringUp() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    protected void executeCommand() {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterAsyncCommandBase.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterAsyncCommandBase.java
new file mode 100644
index 0000000..f8180d3
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterAsyncCommandBase.java
@@ -0,0 +1,71 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ovirt.engine.core.bll.job.ExecutionHandler;
+import org.ovirt.engine.core.common.action.gluster.GlusterVolumeParameters;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
+import org.ovirt.engine.core.common.constants.gluster.GlusterConstants;
+import org.ovirt.engine.core.common.job.ExternalSystemType;
+import org.ovirt.engine.core.common.job.JobExecutionStatus;
+import org.ovirt.engine.core.common.job.Step;
+import org.ovirt.engine.core.common.job.StepEnum;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.job.ExecutionMessageDirector;
+
+public abstract class GlusterAsyncCommandBase<T extends 
GlusterVolumeParameters> extends GlusterVolumeCommandBase<T> {
+
+    private static final long serialVersionUID = -7411023079841571332L;
+    private Step _asyncTaskStep;
+
+
+    public GlusterAsyncCommandBase(T params) {
+        super(params);
+    }
+
+    protected Map<String, String> getStepMessageMap() {
+        Map<String, String> values = new HashMap<String, String>();
+        values.put(GlusterConstants.CLUSTER, getVdsGroupName());
+        values.put(GlusterConstants.VOLUME, getGlusterVolumeName());
+        //TODO: Define constants
+        values.put("status", "STARTED" );
+        values.put("info", " ");
+        return values;
+    }
+
+    /**
+     *
+     * @return the StepEnum associated with this command. This is used to 
start a sub step for the executing step.
+     */
+    protected abstract StepEnum getStepType();
+
+    /**
+     * Run the corresponding VDS command. The return value of the command 
should be GlusterAsyncTask.
+     * @return GlusterAsyncTask object that contains the started gluster task 
id which is used to populate
+     *          the external id of {@link Step}
+     */
+    protected abstract GlusterAsyncTask executeAndReturnTask();
+
+    @Override
+    protected void executeCommand() {
+        _asyncTaskStep = 
ExecutionHandler.addSubStep(this.getExecutionContext(), 
getExecutionContext().getJob().getStep(StepEnum.EXECUTING),
+                getStepType(),
+                
ExecutionMessageDirector.resolveStepMessage(getStepType(),getStepMessageMap()));
+
+        handleTaskReturn(executeAndReturnTask());
+    }
+
+    protected void handleTaskReturn(GlusterAsyncTask asyncTask) {
+        Guid externalTaskId = asyncTask.getTaskId();
+        // 
getExecutionContext().getStep().setCorrelationId(externalTaskId.toString());
+        _asyncTaskStep.setStatus(JobExecutionStatus.STARTED);
+        ExecutionHandler.updateStepExternalId(_asyncTaskStep,
+                externalTaskId,
+                ExternalSystemType.GLUSTER);
+        getExecutionContext().getJob().setStatus(JobExecutionStatus.STARTED);
+        GlusterTaskManager.getInstance().addTask(externalTaskId);
+    }
+
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskManager.java
new file mode 100644
index 0000000..df1c74b
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskManager.java
@@ -0,0 +1,162 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.ovirt.engine.core.bll.job.ExecutionContext;
+import org.ovirt.engine.core.bll.job.ExecutionHandler;
+import org.ovirt.engine.core.bll.job.JobRepositoryFactory;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterTaskStatus;
+import org.ovirt.engine.core.common.constants.gluster.GlusterConstants;
+import org.ovirt.engine.core.common.job.JobExecutionStatus;
+import org.ovirt.engine.core.common.job.Step;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.dal.job.ExecutionMessageDirector;
+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.SchedulerUtilQuartzImpl;
+
+public final class GlusterTaskManager {
+    private static final Log log = LogFactory.getLog(GlusterTaskManager.class);
+
+    private final List<Guid> glusterTasksList = new ArrayList<Guid>();
+
+    private static GlusterTaskManager _taskMgr = new GlusterTaskManager();
+
+    public static GlusterTaskManager getInstance() {
+        return _taskMgr;
+    }
+
+    private GlusterTaskManager() {
+        //initialize schedulers that poll for task status
+        //TODO: read config values and populate
+       SchedulerUtilQuartzImpl.getInstance().scheduleAFixedDelayJob(this,
+                "async_task_poll_event", new Class[] {}, new Class [] {}, 30,
+               30, TimeUnit.SECONDS);
+
+    }
+
+    public void init() {
+        log.info("Gluster task manager has been initialized");
+        initializeTasks();
+    }
+
+    public synchronized void addTask(Guid externalTaskId) {
+        if (!glusterTasksList.contains(externalTaskId)) {
+            glusterTasksList.add(externalTaskId);
+        }
+    }
+
+   private void removeTask(Guid externalTaskId) {
+        if (glusterTasksList.contains(externalTaskId)) {
+            glusterTasksList.remove(externalTaskId);
+        }
+    }
+
+    @OnTimerMethodAnnotation("async_task_poll_event")
+    public synchronized void updateJobStepStatusForTasks() {
+        log.info("polling for asyn gluster tasks");
+        List<Guid> toRemoveList = new ArrayList<Guid>();
+        for (Guid taskId : glusterTasksList) {
+                //get status of task from vdsm
+            GlusterAsyncTask task = 
GlusterTaskStatusUtil.getTaskStatus(taskId);
+                //get step from db for the corresponding gluster task
+            List<Step> steps = 
DbFacade.getInstance().getStepDao().getStepsByExternalId(taskId);
+            //update status in step table
+            for (Step step: steps) {
+                step.setDescription(getTaskMessage(step,task));
+                if (hasTaskCompleted(task)) {
+                    //ExecutionHandler.endTaskStep(step.getId(), 
getJobCompletedStatus(task));
+
+                    step.markStepEnded(getJobCompletedStatus(task));
+                    endStepJob(step);
+                    toRemoveList.add(taskId);
+                } else {
+                    JobRepositoryFactory.getJobRepository().updateStep(step);
+                }
+            }
+        }
+        for (Guid removeTaskId : toRemoveList) {
+            removeTask(removeTaskId);
+        }
+
+    }
+
+    public synchronized void initAndCleanupOrphanTasks() {
+        //Gluster tasks may have completed without the engine being aware of it
+        //Get all external tasks of type gluster in the database for which
+        //there are no running tasks in gluster.
+
+        //Mark job as completed (?) with status unknown for each such task
+
+        //remove from tasks list
+    }
+
+    private void endStepJob(Step step) {
+        JobRepositoryFactory.getJobRepository().updateStep(step);
+        ExecutionContext finalContext = 
ExecutionHandler.createFinalizingContext(step.getId());
+        ExecutionHandler.endTaskJob(finalContext, isTaskSuccess(step));
+    }
+
+    private boolean isTaskSuccess(Step step) {
+        switch (step.getStatus()) {
+            case ABORTED:
+            case FAILED:
+                return false;
+            case FINISHED:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private JobExecutionStatus getJobCompletedStatus(GlusterAsyncTask task) {
+        switch (task.getStatus()) {
+            case ABORTED :
+                return JobExecutionStatus.ABORTED;
+            case FAILED :
+                return JobExecutionStatus.FAILED;
+            case COMPLETED :
+                return JobExecutionStatus.FINISHED;
+            case RUNNING :
+                return JobExecutionStatus.STARTED;
+            default:
+                return JobExecutionStatus.UNKNOWN;
+        }
+
+    }
+
+    private boolean hasTaskCompleted(GlusterAsyncTask task) {
+        if (GlusterTaskStatus.ABORTED.equals(task.getStatus()) || 
GlusterTaskStatus.COMPLETED.equals(task.getStatus())
+                || GlusterTaskStatus.FAILED.equals(task.getStatus())) {
+            return true;
+        }
+        return false;
+    }
+
+    private String getTaskMessage(Step step, GlusterAsyncTask task) {
+        if (task==null) {
+            return null;
+        }
+        Map<String, String> values = new HashMap<String, String>();
+        values.put(GlusterConstants.CLUSTER, "CL");
+        values.put(GlusterConstants.VOLUME, "vol");
+        values.put("status", task.getStatus().toString());
+        values.put("info", task.getMessage());
+
+        return 
ExecutionMessageDirector.resolveStepMessage(task.getType().getStep(), values);
+    }
+
+    private void initializeTasks() {
+        //get external tasks from DB where not completed.
+        //May not be required if we use gluster Tasks list from UP server for 
each cluster
+
+        initAndCleanupOrphanTasks();
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskStatusUtil.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskStatusUtil.java
new file mode 100644
index 0000000..57626da
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterTaskStatusUtil.java
@@ -0,0 +1,21 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterTaskStatus;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterTaskType;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.utils.RandomUtils;
+
+public class GlusterTaskStatusUtil {
+
+    public static GlusterAsyncTask getTaskStatus(Guid taskId) {
+        //TODO: Call VDS command to get status. Dummy for now
+        GlusterAsyncTask task = new GlusterAsyncTask();
+        task.setTaskId(taskId);
+        task.setType(GlusterTaskType.REBALANCE);
+        task.setMessage(RandomUtils.instance().nextString(40));
+        
task.setStatus(GlusterTaskStatus.forValue(RandomUtils.instance().nextInt(0, 
4)));
+        return task;
+    }
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RebalanceGlusterVolumeCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RebalanceGlusterVolumeCommand.java
new file mode 100644
index 0000000..c97c3eb
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RebalanceGlusterVolumeCommand.java
@@ -0,0 +1,86 @@
+package org.ovirt.engine.core.bll.gluster;
+
+import org.ovirt.engine.core.bll.Backend;
+import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
+import org.ovirt.engine.core.common.AuditLogType;
+import 
org.ovirt.engine.core.common.action.gluster.GlusterVolumeRebalanceParameters;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
+import 
org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity;
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeType;
+import org.ovirt.engine.core.common.job.StepEnum;
+import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
+import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
+import 
org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumeRebalanceVDSParameters;
+import org.ovirt.engine.core.dal.VdcBllMessages;
+
+/**
+ * BLL command to Rebalance Gluster volume
+ * This command starts an asynchronous gluster task to start rebalance of 
volume.
+ * This may be a long running operation and so the returned task id is used to 
update
+ * the status of the step and the corresponding job.
+ */
+@NonTransactiveCommandAttribute
+public class RebalanceGlusterVolumeCommand extends 
GlusterAsyncCommandBase<GlusterVolumeRebalanceParameters> {
+
+    private static final long serialVersionUID = 8747137699199502912L;
+
+    public RebalanceGlusterVolumeCommand(GlusterVolumeRebalanceParameters 
params) {
+        super(params);
+    }
+
+    @Override
+    protected void setActionMessageParameters() {
+        addCanDoActionMessage(VdcBllMessages.VAR__ACTION__REBALANCE_START);
+        addCanDoActionMessage(VdcBllMessages.VAR__TYPE__GLUSTER_VOLUME);
+    }
+
+    @Override
+    protected boolean canDoAction() {
+        GlusterVolumeEntity glusterVolume = getGlusterVolume();
+        if (!super.canDoAction()) {
+            return false;
+        }
+
+        if (!glusterVolume.isOnline()) {
+            
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_GLUSTER_VOLUME_SHOULD_BE_STARTED);
+            return false;
+        }
+
+        if ((glusterVolume.getVolumeType() == GlusterVolumeType.REPLICATE && 
glusterVolume.getBricks().size() <= glusterVolume.getReplicaCount())
+                || (glusterVolume.getVolumeType() == GlusterVolumeType.STRIPE 
&& glusterVolume.getBricks().size() <= glusterVolume.getStripeCount())
+                || (glusterVolume.getBricks().size() == 1)) {
+            
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_GLUSTER_VOLUME_BRICKS_ARE_NOT_DISTRIBUTED);
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    protected StepEnum getStepType() {
+        return StepEnum.REBALANCING_VOLUME;
+    }
+
+    @Override
+    protected GlusterAsyncTask executeAndReturnTask() {
+        VDSReturnValue taskReturn = Backend.getInstance().getResourceManager()
+                .RunVdsCommand(VDSCommandType.StartRebalanceGlusterVolume,
+                        new 
GlusterVolumeRebalanceVDSParameters(upServer.getId(),
+                                getGlusterVolumeName(), 
getParameters().isFixLayoutOnly(), getParameters().isForceAction()));
+        setSucceeded(taskReturn.getSucceeded());
+        if (getSucceeded()) {
+            return (GlusterAsyncTask)taskReturn.getReturnValue();
+        }
+        return null;
+    }
+
+    @Override
+    public AuditLogType getAuditLogTypeValue() {
+        if (getSucceeded()) {
+            return AuditLogType.GLUSTER_VOLUME_REBALANCE_START;
+        } else {
+            return errorType == null ? 
AuditLogType.GLUSTER_VOLUME_REBALANCE_START_FAILED : errorType;
+        }
+    }
+
+
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartRebalanceGlusterVolumeCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartRebalanceGlusterVolumeCommand.java
index 5b7ba17..6741103 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartRebalanceGlusterVolumeCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartRebalanceGlusterVolumeCommand.java
@@ -56,8 +56,9 @@
                                         
VDSCommandType.StartRebalanceGlusterVolume,
                                         new 
GlusterVolumeRebalanceVDSParameters(upServer.getId(),
                                                 getGlusterVolumeName(), 
getParameters().isFixLayoutOnly(), getParameters().isForceAction()));
+        setSucceeded(returnValue.getSucceeded());
         if (getSucceeded()) {
-            setSucceeded(returnValue.getSucceeded());
+            setActionReturnValue(returnValue.getReturnValue());
         } else {
             handleVdsError(AuditLogType.GLUSTER_VOLUME_REBALANCE_START_FAILED, 
returnValue.getVdsError().getMessage());
             return;
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
index 5a144c8..88f2e61 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
@@ -263,6 +263,7 @@
     StartGlusterVolumeProfile(1410, ActionGroup.MANIPULATE_GLUSTER_VOLUME, 
QuotaDependency.NONE),
     StopGlusterVolumeProfile(1411, ActionGroup.MANIPULATE_GLUSTER_VOLUME, 
QuotaDependency.NONE),
     RemoveGlusterServer(1412, ActionGroup.DELETE_HOST, QuotaDependency.NONE),
+    RebalanceGlusterVolume(1413, ActionGroup.MANIPULATE_GLUSTER_VOLUME, 
QuotaDependency.NONE),
 
     // External events
     AddExternalEvent(1500, ActionGroup.INJECT_EXTERNAL_EVENTS, 
QuotaDependency.NONE),
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterAsyncTask.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterAsyncTask.java
new file mode 100644
index 0000000..70dd7f7
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterAsyncTask.java
@@ -0,0 +1,43 @@
+package org.ovirt.engine.core.common.businessentities.gluster;
+
+import java.io.Serializable;
+
+import org.ovirt.engine.core.compat.Guid;
+
+public class GlusterAsyncTask implements Serializable{
+
+    private static final long serialVersionUID = 5165089908032934194L;
+
+    private Guid taskId;
+    private GlusterTaskStatus status;
+    private GlusterTaskType type;
+
+    private String message;
+
+    public Guid getTaskId() {
+        return taskId;
+    }
+    public void setTaskId(Guid taskId) {
+        this.taskId = taskId;
+    }
+    public GlusterTaskStatus getStatus() {
+        return status;
+    }
+    public void setStatus(GlusterTaskStatus status) {
+        this.status = status;
+    }
+    public String getMessage() {
+        return message;
+    }
+    public void setMessage(String message) {
+        this.message = message;
+    }
+    public GlusterTaskType getType() {
+        return type;
+    }
+    public void setType(GlusterTaskType type) {
+        this.type = type;
+    }
+
+
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskStatus.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskStatus.java
new file mode 100644
index 0000000..eb12344
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskStatus.java
@@ -0,0 +1,36 @@
+package org.ovirt.engine.core.common.businessentities.gluster;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum GlusterTaskStatus {
+    RUNNING(0),
+    FAILED(1),
+    COMPLETED(2),
+    ABORTED(3),
+    PAUSED(4);
+
+
+    private int intValue;
+
+    private static Map<Integer, GlusterTaskStatus> mappings;
+
+    static {
+        mappings = new HashMap<Integer, GlusterTaskStatus>();
+        for (GlusterTaskStatus value : values()) {
+            mappings.put(value.getValue(), value);
+        }
+    }
+
+    private GlusterTaskStatus(int value) {
+        intValue = value;
+    }
+
+    public int getValue() {
+        return intValue;
+    }
+
+    public static GlusterTaskStatus forValue(int value) {
+        return mappings.get(value);
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskType.java
new file mode 100644
index 0000000..e76e4fc
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/gluster/GlusterTaskType.java
@@ -0,0 +1,46 @@
+package org.ovirt.engine.core.common.businessentities.gluster;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ovirt.engine.core.common.action.VdcActionType;
+import org.ovirt.engine.core.common.job.StepEnum;
+
+public enum GlusterTaskType {
+    
REBALANCE(VdcActionType.RebalanceGlusterVolume,StepEnum.REBALANCING_VOLUME),
+    REPLACE_BRICK(VdcActionType.ReplaceGlusterVolumeBrick);
+   // REMOVE_BRICK(VdcActionType.DeleteGlusterVolume); //TODO: change
+
+    private VdcActionType _actionType;
+    private StepEnum _step;
+
+    private static Map<VdcActionType, GlusterTaskType> mappings;
+
+    static {
+        mappings = new HashMap<VdcActionType, GlusterTaskType>();
+        for (GlusterTaskType value : values()) {
+            mappings.put(value.getValue(), value);
+        }
+    }
+
+    private GlusterTaskType(VdcActionType actionType) {
+        _actionType = actionType;
+    }
+
+    private GlusterTaskType(VdcActionType actionType, StepEnum step) {
+        _actionType = actionType;
+        _step = step;
+    }
+
+    public VdcActionType getValue() {
+        return _actionType;
+    }
+
+    public StepEnum getStep() {
+        return _step;
+    }
+
+    public static GlusterTaskType forValue(VdcActionType value) {
+        return mappings.get(value);
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/ExternalSystemType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/ExternalSystemType.java
index f73737e..41fa798 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/ExternalSystemType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/ExternalSystemType.java
@@ -1,7 +1,8 @@
 package org.ovirt.engine.core.common.job;
 
 public enum ExternalSystemType {
-    VDSM;
+    VDSM,
+    GLUSTER;
 
     static public ExternalSystemType safeValueOf(String value) {
         if (value == null) {
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
index 17a4b18..4497bb7 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/job/StepEnum.java
@@ -22,7 +22,7 @@
 
     // Gluster
     SETTING_GLUSTER_OPTION,
-
+    REBALANCING_VOLUME,
     /**
      * Maps VDSM tasks type to {@code StepEnum} so it can be resolvable as 
readable description
      */
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDao.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDao.java
index 88f0f5d..3606d29 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDao.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDao.java
@@ -45,5 +45,15 @@
      */
     void updateJobStepsCompleted(Guid jobId, JobExecutionStatus status, Date 
endTime);
 
+    /**
+     * Retrieve all steps associated with the given external id
+     * @param externalId
+     * @return
+     */
+    List<Step> getStepsByExternalId(Guid externalId);
+
+    //TODO: To be removed
+    public List<Step> getAllStepsWithExternalId();
+
 }
 
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDaoDbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDaoDbFacadeImpl.java
index a5a525b..42c6673 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDaoDbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/StepDaoDbFacadeImpl.java
@@ -99,4 +99,16 @@
             return step;
         }
     }
+
+    @Override
+    public List<Step> getStepsByExternalId(Guid externalId) {
+        MapSqlParameterSource parameterSource = 
getCustomMapSqlParameterSource().addValue("external_id", externalId);
+        return getCallsHandler().executeReadList("GetStepsByExternalId", 
createEntityRowMapper(), parameterSource);
+    }
+
+    @Override
+    public List<Step> getAllStepsWithExternalId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/ExecutionMessages.properties
 
b/backend/manager/modules/dal/src/main/resources/bundles/ExecutionMessages.properties
index ece6294..7047321 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/ExecutionMessages.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/ExecutionMessages.properties
@@ -106,6 +106,7 @@
 
 # Gluster step types
 step.SETTING_GLUSTER_OPTION=Setting option ${Key}=${Value} on volume 
${GlusterVolume} of cluster ${Cluster}
+step.REBALANCING_VOLUME=Rebalancing ${GlusterVolume} volume of ${Cluster}.( 
${Status} ${info})
 
 # Non-monitored job:
 job.AddVmInterface=Adding Network Interface ${InterfaceName} to VM ${VM}
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/StartRebalanceGlusterVolumeVDSCommand.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/StartRebalanceGlusterVolumeVDSCommand.java
index 9aad3cc..9478c61 100644
--- 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/StartRebalanceGlusterVolumeVDSCommand.java
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/gluster/StartRebalanceGlusterVolumeVDSCommand.java
@@ -1,19 +1,44 @@
 package org.ovirt.engine.core.vdsbroker.gluster;
 
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
 import 
org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumeRebalanceVDSParameters;
+import org.ovirt.engine.core.compat.Guid;
+import 
org.ovirt.engine.core.vdsbroker.vdsbroker.GlusterTaskInfoReturnForXmlRpc;
+import org.ovirt.engine.core.vdsbroker.vdsbroker.StatusForXmlRpc;
 
 public class StartRebalanceGlusterVolumeVDSCommand<P extends 
GlusterVolumeRebalanceVDSParameters> extends AbstractGlusterBrokerCommand<P> {
+    private GlusterTaskInfoReturnForXmlRpc glusterTaskReturn;
+    private GlusterAsyncTask task;
+
     public StartRebalanceGlusterVolumeVDSCommand(P parameters) {
         super(parameters);
     }
 
     @Override
     protected void ExecuteVdsBrokerCommand() {
-        status =
-                
getBroker().glusterVolumeRebalanceStart(getParameters().getVolumeName(),
-                        getParameters().isFixLayoutOnly(),
-                        getParameters().isForceAction());
-
+        //VDSM does not support task return yet
+        /* glusterTaskReturn = 
getBroker().glusterVolumeRebalanceStart(getParameters().getVolumeName(),
+                getParameters().isFixLayoutOnly(),
+                getParameters().isForceAction());
+           task = glusterTaskReturn.getGlusterTask();
+                */
+        //TODO : REMOVE TEMPORARY HACK
+        task = new GlusterAsyncTask();
+        task.setTaskId(Guid.NewGuid());
+        setReturnValue(task);
         ProceedProxyReturnValue();
     }
+
+    @Override
+    protected StatusForXmlRpc getReturnStatus() {
+        return glusterTaskReturn.mStatus;
+    }
+
+    @Override
+    public Object getReturnValue() {
+        return task;
+    }
+
+
+
 }
diff --git 
a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GlusterTaskInfoReturnForXmlRpc.java
 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GlusterTaskInfoReturnForXmlRpc.java
new file mode 100644
index 0000000..9b8c08e
--- /dev/null
+++ 
b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/GlusterTaskInfoReturnForXmlRpc.java
@@ -0,0 +1,24 @@
+package org.ovirt.engine.core.vdsbroker.vdsbroker;
+
+import java.util.Map;
+
+import org.ovirt.engine.core.common.businessentities.gluster.GlusterAsyncTask;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.vdsbroker.irsbroker.StatusReturnForXmlRpc;
+
+public class GlusterTaskInfoReturnForXmlRpc extends  StatusReturnForXmlRpc {
+    private static final String TASK_ID = "taskId";
+    private final GlusterAsyncTask glusterTask = new GlusterAsyncTask();
+
+    public GlusterTaskInfoReturnForXmlRpc(Map<String, Object> innerMap) {
+        super(innerMap);
+        //TODO: return a GlusterTask from the map
+        if (innerMap.containsKey(TASK_ID))
+            
glusterTask.setTaskId(Guid.createGuidFromString((String)innerMap.get(TASK_ID)));
+    }
+
+    public GlusterAsyncTask getGlusterTask() {
+        return glusterTask;
+    }
+
+}
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 532dcd6..e6c542a 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
@@ -219,7 +219,7 @@
             int replicaCount,
             int stripeCount);
 
-    StatusOnlyReturnForXmlRpc glusterVolumeRebalanceStart(String volumeName, 
Boolean fixLayoutOnly, Boolean force);
+    GlusterTaskInfoReturnForXmlRpc glusterVolumeRebalanceStart(String 
volumeName, Boolean fixLayoutOnly, Boolean force);
 
     StatusOnlyReturnForXmlRpc glusterVolumeReplaceBrickStart(String volumeName,
             String existingBrickDir,
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 13ea1f6..1476541 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
@@ -1073,9 +1073,9 @@
     }
 
     @Override
-    public StatusOnlyReturnForXmlRpc glusterVolumeRebalanceStart(String 
volumeName, Boolean fixLayoutOnly, Boolean force) {
+    public GlusterTaskInfoReturnForXmlRpc glusterVolumeRebalanceStart(String 
volumeName, Boolean fixLayoutOnly, Boolean force) {
         try {
-            return new 
StatusOnlyReturnForXmlRpc(vdsServer.glusterVolumeRebalanceStart(volumeName, 
fixLayoutOnly, force));
+            return new 
GlusterTaskInfoReturnForXmlRpc(vdsServer.glusterVolumeRebalanceStart(volumeName,
 fixLayoutOnly, force));
         } catch (UndeclaredThrowableException ute) {
             throw new XmlRpcRunTimeException(ute);
         }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
index a0c23ba..4476198 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/volumes/VolumeListModel.java
@@ -130,7 +130,7 @@
         setStopCommand(new UICommand("Stop", this)); //$NON-NLS-1$
         setRebalanceCommand(new UICommand("Rebalance", this)); //$NON-NLS-1$
         setOptimizeForVirtStoreCommand(new UICommand("OptimizeForVirtStore", 
this)); //$NON-NLS-1$
-        getRebalanceCommand().setIsAvailable(false);
+        getRebalanceCommand().setIsAvailable(true);
 
         getRemoveVolumeCommand().setIsExecutionAllowed(false);
         getStartCommand().setIsExecutionAllowed(false);
@@ -406,7 +406,7 @@
             GlusterVolumeEntity volume = (GlusterVolumeEntity) item;
             list.add(new GlusterVolumeRebalanceParameters(volume.getId(), 
false, false));
         }
-        Frontend.RunMultipleAction(VdcActionType.StartRebalanceGlusterVolume, 
list);
+        Frontend.RunMultipleAction(VdcActionType.RebalanceGlusterVolume, list);
     }
 
     private void optimizeForVirtStore() {


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8a56785edef091bce74e2b7b0ba9a3314f1397f1
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Sahina Bose <sab...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to