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