package org.ovirt.engine.core.bll.gluster; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.validator.gluster.GlusterBrickValidator; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.action.gluster.GlusterVolumeRebalanceParameters; import org.ovirt.engine.core.common.asynctasks.gluster.GlusterAsyncTask; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; import org.ovirt.engine.core.common.errors.EngineMessage; 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; /** * 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 StartRebalanceGlusterVolumeCommand extends GlusterAsyncCommandBase<GlusterVolumeRebalanceParameters> { public StartRebalanceGlusterVolumeCommand(GlusterVolumeRebalanceParameters params, CommandContext commandContext) { super(params, commandContext); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Command); } @Override protected void setActionMessageParameters() { addValidationMessage(EngineMessage.VAR__ACTION__REBALANCE_START); addValidationMessage(EngineMessage.VAR__TYPE__GLUSTER_VOLUME); super.setActionMessageParameters(); } @Override protected boolean validate() { GlusterVolumeEntity glusterVolume = getGlusterVolume(); if (!super.validate()) { return false; } boolean isVolumeDistributed = glusterVolume.getVolumeType().isDistributedType(); if (!isVolumeDistributed) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_GLUSTER_VOLUME_NOT_DISTRIBUTED); } else if (glusterVolume.getBricks().size() == 1) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_GLUSTER_VOLUME_DISTRIBUTED_AND_HAS_SINGLE_BRICK); } GlusterBrickValidator brickValidator = new GlusterBrickValidator(); return validate(brickValidator.canRebalance(glusterVolume)); } @Override protected StepEnum getStepType() { return StepEnum.REBALANCING_VOLUME; } @Override protected void executeCommand() { startSubStep(); VDSReturnValue taskReturn = runVdsCommand(VDSCommandType.StartRebalanceGlusterVolume, new GlusterVolumeRebalanceVDSParameters(upServer.getId(), getGlusterVolumeName(), getParameters().isFixLayoutOnly(), getParameters().isForceAction())); setSucceeded(taskReturn.getSucceeded()); if (!getSucceeded()) { handleVdsError(AuditLogType.GLUSTER_VOLUME_REBALANCE_START_FAILED, taskReturn.getVdsError().getMessage()); return; } GlusterAsyncTask glusterTask = (GlusterAsyncTask) taskReturn.getReturnValue(); handleTaskReturn(glusterTask); updateVolumeWithTaskID(glusterTask); getReturnValue().setActionReturnValue(glusterTask); } private void updateVolumeWithTaskID(GlusterAsyncTask rebalanceAsyncTask) { glusterVolumeDao.updateVolumeTask(getGlusterVolumeId(), rebalanceAsyncTask.getTaskId()); } @Override public AuditLogType getAuditLogTypeValue() { if (getSucceeded()) { return AuditLogType.GLUSTER_VOLUME_REBALANCE_START; } else { return errorType == null ? AuditLogType.GLUSTER_VOLUME_REBALANCE_START_FAILED : errorType; } } @Override protected void freeLock() { // We have to keep the lock acquired on gluster volume if start rebalance was success, otherwsie we should // release all the locks. if (!getSucceeded()) { super.freeLock(); } } }