package org.ovirt.engine.core.bll; import java.util.Collections; import java.util.Map; import javax.inject.Inject; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.RemoveVmFromPoolParameters; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.dao.VmPoolDao; import org.ovirt.engine.core.utils.lock.EngineLock; public class RemoveVmFromPoolCommand<T extends RemoveVmFromPoolParameters> extends VmPoolCommandBase<T> { @Inject private VmPoolDao vmPoolDao; public RemoveVmFromPoolCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); } @Override protected void init() { super.init(); setVmId(getParameters().getVmId()); if (getVm() != null) { setVmPoolId(getVm().getVmPoolId()); } } @Override protected boolean validate() { if (getVm() == null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_VM_NOT_FOUND); } if (getVmPoolId() == null) { return failValidation(EngineMessage.VM_POOL_CANNOT_DETACH_VM_NOT_ATTACHED_TO_POOL); } if (getVm().isRunningOrPaused() || getVm().getStatus() == VMStatus.Unknown) { return failValidation(EngineMessage.VM_POOL_CANNOT_REMOVE_RUNNING_VM_FROM_POOL); } return true; } @Override protected void executeCommand() { if (getVmPoolId() != null) { vmPoolDao.removeVmFromVmPool(getVmId()); if (getParameters().isUpdatePrestartedVms()) { vmPoolDao.boundVmPoolPrestartedVms(getVmPoolId()); } if (getParameters().isRemovePoolUponDetachAllVMs()) { removeVmPoolIfNeeded(); } setSucceeded(true); } } @Override protected Map<String, Pair<String, String>> getSharedLocks() { return getParameters().isUpdatePrestartedVms() ? Collections.singletonMap(getVmPoolId().toString(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.VM_POOL, getVmBeingRemovedFromPoolMessage())) : null; } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(LockProperties.Scope.Execution); } private LockMessage getVmBeingRemovedFromPoolMessage() { return new LockMessage(EngineMessage.ACTION_TYPE_FAILED_VM_IS_BEING_REMOVED_FROM_POOL) .withOptional("VmName", getVm() != null ? getVm().getName() : null) .withOptional("VmPoolName", getVmPool() != null ? getVmPool().getName() : null); } @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.USER_REMOVE_VM_FROM_POOL : AuditLogType.USER_REMOVE_VM_FROM_POOL_FAILED; } protected void removeVmPoolIfNeeded() { try { lockManager.acquireLockWait(new EngineLock(getExclusiveLockForPoolDetach())); if (vmPoolDao.getVmPoolsMapByVmPoolId(getVmPoolId()).isEmpty()) { vmPoolDao.remove(getVmPoolId()); } } finally { lockManager.releaseLock(new EngineLock(getExclusiveLockForPoolDetach())); } } private Map<String, Pair<String, String>> getExclusiveLockForPoolDetach() { return Collections.singletonMap( getVmPoolId().toString(), LockMessagesMatchUtil.makeLockingPair( LockingGroup.VM_POOL_DETACH, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED)); } }