Search in sources :

Example 11 with AsyncJobExecutionContext

use of org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext in project cloudstack by apache.

the class VolumeApiServiceImplTest method setup.

@Before
public void setup() throws InterruptedException, ExecutionException {
    Mockito.lenient().doReturn(volumeMockId).when(volumeDataStoreVoMock).getVolumeId();
    Mockito.doReturn(volumeMockId).when(volumeVoMock).getId();
    Mockito.lenient().doReturn(accountMockId).when(accountMock).getId();
    Mockito.doReturn(volumeSizeMock).when(volumeVoMock).getSize();
    Mockito.doReturn(volumeSizeMock).when(newDiskOfferingMock).getDiskSize();
    Mockito.doReturn(Mockito.mock(VolumeApiResult.class)).when(asyncCallFutureVolumeapiResultMock).get();
    Mockito.when(storagePoolMock.getId()).thenReturn(storagePoolMockId);
    volumeApiServiceImpl._gson = GsonHelper.getGsonLogger();
    // mock caller context
    AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
    UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
    CallContext.register(user, account);
    // mock async context
    AsyncJobExecutionContext context = new AsyncJobExecutionContext();
    AsyncJobExecutionContext.init(_jobMgr, _joinMapDao);
    AsyncJobVO job = new AsyncJobVO();
    context.setJob(job);
    AsyncJobExecutionContext.setCurrentExecutionContext(context);
    TransactionLegacy txn = TransactionLegacy.open("runVolumeDaoImplTest");
    try {
        // volume of running vm id=1
        VolumeVO volumeOfRunningVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 1L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        when(volumeDaoMock.findById(1L)).thenReturn(volumeOfRunningVm);
        UserVmVO runningVm = new UserVmVO(1L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
        runningVm.setState(State.Running);
        runningVm.setDataCenterId(1L);
        when(userVmDaoMock.findById(1L)).thenReturn(runningVm);
        // volume of stopped vm id=2
        VolumeVO volumeOfStoppedVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        volumeOfStoppedVm.setPoolId(1L);
        when(volumeDaoMock.findById(2L)).thenReturn(volumeOfStoppedVm);
        UserVmVO stoppedVm = new UserVmVO(2L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
        stoppedVm.setState(State.Stopped);
        stoppedVm.setDataCenterId(1L);
        when(userVmDaoMock.findById(2L)).thenReturn(stoppedVm);
        // volume of hyperV vm id=3
        UserVmVO hyperVVm = new UserVmVO(3L, "vm", "vm", 1, HypervisorType.Hyperv, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
        hyperVVm.setState(State.Stopped);
        hyperVVm.setDataCenterId(1L);
        when(userVmDaoMock.findById(3L)).thenReturn(hyperVVm);
        VolumeVO volumeOfStoppeHyperVVm = new VolumeVO("root", 1L, 1L, 1L, 1L, 3L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        volumeOfStoppeHyperVVm.setPoolId(1L);
        when(volumeDaoMock.findById(3L)).thenReturn(volumeOfStoppeHyperVVm);
        StoragePoolVO unmanagedPool = new StoragePoolVO();
        when(primaryDataStoreDaoMock.findById(1L)).thenReturn(unmanagedPool);
        // volume of managed pool id=4
        StoragePoolVO managedPool = new StoragePoolVO();
        managedPool.setManaged(true);
        when(primaryDataStoreDaoMock.findById(2L)).thenReturn(managedPool);
        VolumeVO managedPoolVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        managedPoolVolume.setPoolId(2L);
        when(volumeDaoMock.findById(4L)).thenReturn(managedPoolVolume);
        // non-root non-datadisk volume
        VolumeInfo volumeWithIncorrectVolumeType = Mockito.mock(VolumeInfo.class);
        lenient().when(volumeWithIncorrectVolumeType.getId()).thenReturn(5L);
        when(volumeWithIncorrectVolumeType.getVolumeType()).thenReturn(Volume.Type.ISO);
        when(volumeDataFactoryMock.getVolume(5L)).thenReturn(volumeWithIncorrectVolumeType);
        // correct root volume
        VolumeInfo correctRootVolume = Mockito.mock(VolumeInfo.class);
        when(correctRootVolume.getId()).thenReturn(6L);
        when(correctRootVolume.getDataCenterId()).thenReturn(1L);
        when(correctRootVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
        when(correctRootVolume.getInstanceId()).thenReturn(null);
        when(correctRootVolume.getState()).thenReturn(Volume.State.Ready);
        when(correctRootVolume.getTemplateId()).thenReturn(null);
        when(correctRootVolume.getPoolId()).thenReturn(1L);
        when(volumeDataFactoryMock.getVolume(6L)).thenReturn(correctRootVolume);
        VolumeVO correctRootVolumeVO = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        when(volumeDaoMock.findById(6L)).thenReturn(correctRootVolumeVO);
        // managed root volume
        VolumeInfo managedVolume = Mockito.mock(VolumeInfo.class);
        when(managedVolume.getId()).thenReturn(7L);
        when(managedVolume.getDataCenterId()).thenReturn(1L);
        when(managedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
        when(managedVolume.getInstanceId()).thenReturn(null);
        lenient().when(managedVolume.getPoolId()).thenReturn(2L);
        when(volumeDataFactoryMock.getVolume(7L)).thenReturn(managedVolume);
        VolumeVO managedVolume1 = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        managedVolume1.setPoolId(2L);
        managedVolume1.setDataCenterId(1L);
        when(volumeDaoMock.findById(7L)).thenReturn(managedVolume1);
        // vm having root volume
        UserVmVO vmHavingRootVolume = new UserVmVO(4L, "vm", "vm", 1, HypervisorType.XenServer, 1L, false, false, 1L, 1L, 1, 1L, null, "vm");
        vmHavingRootVolume.setState(State.Stopped);
        vmHavingRootVolume.setDataCenterId(1L);
        when(userVmDaoMock.findById(4L)).thenReturn(vmHavingRootVolume);
        List<VolumeVO> vols = new ArrayList<VolumeVO>();
        vols.add(new VolumeVO());
        when(volumeDaoMock.findByInstanceAndDeviceId(4L, 0L)).thenReturn(vols);
        // volume in uploaded state
        VolumeInfo uploadedVolume = Mockito.mock(VolumeInfo.class);
        when(uploadedVolume.getId()).thenReturn(8L);
        when(uploadedVolume.getDataCenterId()).thenReturn(1L);
        when(uploadedVolume.getVolumeType()).thenReturn(Volume.Type.ROOT);
        when(uploadedVolume.getInstanceId()).thenReturn(null);
        lenient().when(uploadedVolume.getPoolId()).thenReturn(1L);
        when(uploadedVolume.getState()).thenReturn(Volume.State.Uploaded);
        when(volumeDataFactoryMock.getVolume(8L)).thenReturn(uploadedVolume);
        VolumeVO upVolume = new VolumeVO("root", 1L, 1L, 1L, 1L, 2L, "root", "root", Storage.ProvisioningType.THIN, 1, null, null, "root", Volume.Type.ROOT);
        upVolume.setPoolId(1L);
        upVolume.setDataCenterId(1L);
        upVolume.setState(Volume.State.Uploaded);
        when(volumeDaoMock.findById(8L)).thenReturn(upVolume);
        // helper dao methods mock
        when(_vmSnapshotDao.findByVm(any(Long.class))).thenReturn(new ArrayList<VMSnapshotVO>());
        when(_vmInstanceDao.findById(any(Long.class))).thenReturn(stoppedVm);
        DataCenterVO enabledZone = Mockito.mock(DataCenterVO.class);
        when(enabledZone.getAllocationState()).thenReturn(Grouping.AllocationState.Enabled);
        when(_dcDao.findById(anyLong())).thenReturn(enabledZone);
    } finally {
        txn.close("runVolumeDaoImplTest");
    }
    // helper methods mock
    lenient().doNothing().when(accountManagerMock).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class));
    doNothing().when(_jobMgr).updateAsyncJobAttachment(any(Long.class), any(String.class), any(Long.class));
    when(_jobMgr.submitAsyncJob(any(AsyncJobVO.class), any(String.class), any(Long.class))).thenReturn(1L);
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) Account(com.cloud.user.Account) UserVmVO(com.cloud.vm.UserVmVO) AsyncJobExecutionContext(org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext) ArrayList(java.util.ArrayList) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) Matchers.anyString(org.mockito.Matchers.anyString) AccountVO(com.cloud.user.AccountVO) AsyncJobVO(org.apache.cloudstack.framework.jobs.impl.AsyncJobVO) TransactionLegacy(com.cloud.utils.db.TransactionLegacy) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) UserVO(com.cloud.user.UserVO) ControlledEntity(org.apache.cloudstack.acl.ControlledEntity) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) Matchers.anyLong(org.mockito.Matchers.anyLong) AccessType(org.apache.cloudstack.acl.SecurityChecker.AccessType) Before(org.junit.Before)

Example 12 with AsyncJobExecutionContext

use of org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext in project cloudstack by apache.

the class VolumeApiServiceImpl method extractVolume.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true)
public String extractVolume(ExtractVolumeCmd cmd) {
    Long volumeId = cmd.getId();
    Long zoneId = cmd.getZoneId();
    String mode = cmd.getMode();
    Account account = CallContext.current().getCallingAccount();
    if (!_accountMgr.isRootAdmin(account.getId()) && ApiDBUtils.isExtractionDisabled()) {
        throw new PermissionDeniedException("Extraction has been disabled by admin");
    }
    VolumeVO volume = _volsDao.findById(volumeId);
    if (volume == null) {
        InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId");
        ex.addProxyObject(volumeId.toString(), "volumeId");
        throw ex;
    }
    // perform permission check
    _accountMgr.checkAccess(account, null, true, volume);
    if (_dcDao.findById(zoneId) == null) {
        throw new InvalidParameterValueException("Please specify a valid zone.");
    }
    if (volume.getPoolId() == null) {
        throw new InvalidParameterValueException("The volume doesn't belong to a storage pool so can't extract it");
    } else {
        StoragePoolVO poolVO = _storagePoolDao.findById(volume.getPoolId());
        if (poolVO != null && poolVO.getPoolType() == Storage.StoragePoolType.PowerFlex) {
            throw new InvalidParameterValueException("Cannot extract volume, this operation is unsupported for volumes on storage pool type " + poolVO.getPoolType());
        }
    }
    // instance is stopped
    if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) {
        s_logger.debug("Invalid state of the volume with ID: " + volumeId + ". It should be either detached or the VM should be in stopped state.");
        PermissionDeniedException ex = new PermissionDeniedException("Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state.");
        ex.addProxyObject(volume.getUuid(), "volumeId");
        throw ex;
    }
    if (volume.getVolumeType() != Volume.Type.DATADISK) {
        // Datadisk dont have any template dependence.
        VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId());
        if (template != null) {
            // For ISO based volumes template = null and
            // we allow extraction of all ISO based
            // volumes
            boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM;
            if (!isExtractable && account != null && !_accountMgr.isRootAdmin(account.getId())) {
                // Global admins are always allowed to extract
                PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted");
                ex.addProxyObject(volume.getUuid(), "volumeId");
                throw ex;
            }
        }
    }
    if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) {
        throw new InvalidParameterValueException("Please specify a valid extract Mode ");
    }
    // Check if the url already exists
    SearchCriteria<VolumeDataStoreVO> sc = _volumeStoreDao.createSearchCriteria();
    Optional<String> extractUrl = setExtractVolumeSearchCriteria(sc, volume);
    if (extractUrl.isPresent()) {
        return extractUrl.get();
    }
    VMInstanceVO vm = null;
    if (volume.getInstanceId() != null) {
        vm = _vmInstanceDao.findById(volume.getInstanceId());
    }
    if (vm != null) {
        // serialize VM operation
        AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
        if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
            // avoid re-entrance
            VmWorkJobVO placeHolder = null;
            placeHolder = createPlaceHolderWork(vm.getId());
            try {
                return orchestrateExtractVolume(volume.getId(), zoneId);
            } finally {
                _workJobDao.expunge(placeHolder.getId());
            }
        } else {
            Outcome<String> outcome = extractVolumeThroughJobQueue(vm.getId(), volume.getId(), zoneId);
            try {
                outcome.get();
            } catch (InterruptedException e) {
                throw new RuntimeException("Operation is interrupted", e);
            } catch (java.util.concurrent.ExecutionException e) {
                throw new RuntimeException("Execution excetion", e);
            }
            Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
            if (jobResult != null) {
                if (jobResult instanceof ConcurrentOperationException) {
                    throw (ConcurrentOperationException) jobResult;
                } else if (jobResult instanceof RuntimeException) {
                    throw (RuntimeException) jobResult;
                } else if (jobResult instanceof Throwable) {
                    throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
                }
            }
            // retrieve the entity url from job result
            if (jobResult != null && jobResult instanceof String) {
                return (String) jobResult;
            }
            return null;
        }
    }
    return orchestrateExtractVolume(volume.getId(), zoneId);
}
Also used : Account(com.cloud.user.Account) AsyncJobExecutionContext(org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext) VMInstanceVO(com.cloud.vm.VMInstanceVO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO) ExecutionException(java.util.concurrent.ExecutionException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) VolumeDataStoreVO(org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject) ActionEvent(com.cloud.event.ActionEvent)

Example 13 with AsyncJobExecutionContext

use of org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext in project cloudstack by apache.

the class VolumeApiServiceImpl method attachVolumeToVM.

public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
    Account caller = CallContext.current().getCallingAccount();
    // Check that the volume ID is valid
    VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
    // Check that the volume is a data volume
    if (volumeToAttach == null || !(volumeToAttach.getVolumeType() == Volume.Type.DATADISK || volumeToAttach.getVolumeType() == Volume.Type.ROOT)) {
        throw new InvalidParameterValueException("Please specify a volume with the valid type: " + Volume.Type.ROOT.toString() + " or " + Volume.Type.DATADISK.toString());
    }
    // Check that the volume is not currently attached to any VM
    if (volumeToAttach.getInstanceId() != null) {
        throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
    }
    // Check that the volume is not destroyed
    if (volumeToAttach.getState() == Volume.State.Destroy) {
        throw new InvalidParameterValueException("Please specify a volume that is not destroyed.");
    }
    // Check that the virtual machine ID is valid and it's a user vm
    UserVmVO vm = _userVmDao.findById(vmId);
    if (vm == null || vm.getType() != VirtualMachine.Type.User) {
        throw new InvalidParameterValueException("Please specify a valid User VM.");
    }
    // Check that the VM is in the correct state
    if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
        throw new InvalidParameterValueException("Please specify a VM that is either running or stopped.");
    }
    // Check that the VM and the volume are in the same zone
    if (vm.getDataCenterId() != volumeToAttach.getDataCenterId()) {
        throw new InvalidParameterValueException("Please specify a VM that is in the same zone as the volume.");
    }
    // Check that the device ID is valid
    if (deviceId != null) {
        // validate ROOT volume type
        if (deviceId.longValue() == 0) {
            validateRootVolumeDetachAttach(_volsDao.findById(volumeToAttach.getId()), vm);
            // vm shouldn't have any volume with deviceId 0
            if (!_volsDao.findByInstanceAndDeviceId(vm.getId(), 0).isEmpty()) {
                throw new InvalidParameterValueException("Vm already has root volume attached to it");
            }
            // volume can't be in Uploaded state
            if (volumeToAttach.getState() == Volume.State.Uploaded) {
                throw new InvalidParameterValueException("No support for Root volume attach in state " + Volume.State.Uploaded);
            }
        }
    }
    // that supported by hypervisor
    if (deviceId == null || deviceId.longValue() != 0) {
        List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
        int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported(vm);
        if (existingDataVolumes.size() >= maxAttachableDataVolumesSupported) {
            throw new InvalidParameterValueException("The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached. Please specify another VM.");
        }
    }
    // If local storage is disabled then attaching a volume with local disk
    // offering not allowed
    DataCenterVO dataCenter = _dcDao.findById(volumeToAttach.getDataCenterId());
    if (!dataCenter.isLocalStorageEnabled()) {
        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volumeToAttach.getDiskOfferingId());
        if (diskOffering.isUseLocalStorage()) {
            throw new InvalidParameterValueException("Zone is not configured to use local storage but volume's disk offering " + diskOffering.getName() + " uses it");
        }
    }
    // if target VM has associated VM snapshots
    List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
    if (vmSnapshots.size() > 0) {
        throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have VM snapshots");
    }
    // if target VM has backups
    if (vm.getBackupOfferingId() != null || vm.getBackupVolumeList().size() > 0) {
        throw new InvalidParameterValueException("Unable to attach volume, please specify a VM that does not have any backups");
    }
    // permission check
    _accountMgr.checkAccess(caller, null, true, volumeToAttach, vm);
    if (!(Volume.State.Allocated.equals(volumeToAttach.getState()) || Volume.State.Ready.equals(volumeToAttach.getState()) || Volume.State.Uploaded.equals(volumeToAttach.getState()))) {
        throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
    }
    Account owner = _accountDao.findById(volumeToAttach.getAccountId());
    if (!(volumeToAttach.getState() == Volume.State.Allocated || volumeToAttach.getState() == Volume.State.Ready)) {
        try {
            _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, volumeToAttach.getSize());
        } catch (ResourceAllocationException e) {
            s_logger.error("primary storage resource limit check failed", e);
            throw new InvalidParameterValueException(e.getMessage());
        }
    }
    HypervisorType rootDiskHyperType = vm.getHypervisorType();
    HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
    StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
    // only perform this check if the volume's storage pool is not null and not managed
    if (volumeToAttachStoragePool != null && !volumeToAttachStoragePool.isManaged()) {
        if (volumeToAttachHyperType != HypervisorType.None && rootDiskHyperType != volumeToAttachHyperType) {
            throw new InvalidParameterValueException("Can't attach a volume created by: " + volumeToAttachHyperType + " to a " + rootDiskHyperType + " vm");
        }
    }
    AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (asyncExecutionContext != null) {
        AsyncJob job = asyncExecutionContext.getJob();
        if (s_logger.isInfoEnabled()) {
            s_logger.info("Trying to attaching volume " + volumeId + " to vm instance:" + vm.getId() + ", update async job-" + job.getId() + " progress status");
        }
        _jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId);
    }
    AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        VmWorkJobVO placeHolder = null;
        placeHolder = createPlaceHolderWork(vmId);
        try {
            return orchestrateAttachVolumeToVM(vmId, volumeId, deviceId);
        } finally {
            _workJobDao.expunge(placeHolder.getId());
        }
    } else {
        Outcome<Volume> outcome = attachVolumeToVmThroughJobQueue(vmId, volumeId, deviceId);
        Volume vol = null;
        try {
            outcome.get();
        } catch (InterruptedException e) {
            throw new RuntimeException("Operation is interrupted", e);
        } catch (java.util.concurrent.ExecutionException e) {
            throw new RuntimeException("Execution excetion", e);
        }
        Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
        if (jobResult != null) {
            if (jobResult instanceof ConcurrentOperationException) {
                throw (ConcurrentOperationException) jobResult;
            } else if (jobResult instanceof InvalidParameterValueException) {
                throw (InvalidParameterValueException) jobResult;
            } else if (jobResult instanceof RuntimeException) {
                throw (RuntimeException) jobResult;
            } else if (jobResult instanceof Throwable) {
                throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
            } else if (jobResult instanceof Long) {
                vol = _volsDao.findById((Long) jobResult);
            }
        }
        return vol;
    }
}
Also used : Account(com.cloud.user.Account) UserVmVO(com.cloud.vm.UserVmVO) AsyncJobExecutionContext(org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) AsyncJob(org.apache.cloudstack.framework.jobs.AsyncJob) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) DataCenterVO(com.cloud.dc.DataCenterVO) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) VmWorkJobVO(org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) ExecutionException(java.util.concurrent.ExecutionException) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) VmWorkDetachVolume(com.cloud.vm.VmWorkDetachVolume) VmWorkMigrateVolume(com.cloud.vm.VmWorkMigrateVolume) VmWorkResizeVolume(com.cloud.vm.VmWorkResizeVolume) VmWorkAttachVolume(com.cloud.vm.VmWorkAttachVolume) VmWorkExtractVolume(com.cloud.vm.VmWorkExtractVolume) DataObject(org.apache.cloudstack.engine.subsystem.api.storage.DataObject)

Example 14 with AsyncJobExecutionContext

use of org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext in project cloudstack by apache.

the class VMSnapshotManagerImpl method createVMSnapshot.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating VM snapshot", async = true)
public VMSnapshot createVMSnapshot(Long vmId, Long vmSnapshotId, Boolean quiescevm) {
    UserVmVO userVm = _userVMDao.findById(vmId);
    if (userVm == null) {
        throw new InvalidParameterValueException("Create vm to snapshot failed due to vm: " + vmId + " is not found");
    }
    VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
    if (vmSnapshot == null) {
        throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not be found");
    }
    // serialize VM operation
    AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        VmWorkJobVO placeHolder = null;
        placeHolder = createPlaceHolderWork(vmId);
        try {
            return orchestrateCreateVMSnapshot(vmId, vmSnapshotId, quiescevm);
        } finally {
            _workJobDao.expunge(placeHolder.getId());
        }
    } else {
        Outcome<VMSnapshot> outcome = createVMSnapshotThroughJobQueue(vmId, vmSnapshotId, quiescevm);
        VMSnapshot result = null;
        try {
            result = outcome.get();
        } catch (InterruptedException e) {
            throw new RuntimeException("Operation is interrupted", e);
        } catch (java.util.concurrent.ExecutionException e) {
            throw new RuntimeException("Execution excetion", e);
        }
        Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
        if (jobResult != null) {
            if (jobResult instanceof ConcurrentOperationException)
                throw (ConcurrentOperationException) jobResult;
            else if (jobResult instanceof Throwable)
                throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
        }
        return result;
    }
}
Also used : UserVmVO(com.cloud.vm.UserVmVO) AsyncJobExecutionContext(org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ActionEvent(com.cloud.event.ActionEvent)

Example 15 with AsyncJobExecutionContext

use of org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext in project cloudstack by apache.

the class VMSnapshotManagerImpl method deleteVMSnapshot.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete vm snapshots", async = true)
public boolean deleteVMSnapshot(Long vmSnapshotId) {
    Account caller = getCaller();
    VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
    if (vmSnapshot == null) {
        throw new InvalidParameterValueException("unable to find the vm snapshot with id " + vmSnapshotId);
    }
    _accountMgr.checkAccess(caller, null, true, vmSnapshot);
    // check VM snapshot states, only allow to delete vm snapshots in created and error state
    if (VMSnapshot.State.Ready != vmSnapshot.getState() && VMSnapshot.State.Expunging != vmSnapshot.getState() && VMSnapshot.State.Error != vmSnapshot.getState()) {
        throw new InvalidParameterValueException("Can't delete the vm snapshotshot " + vmSnapshotId + " due to it is not in Created or Error, or Expunging State");
    }
    // check if there are other active VM snapshot tasks
    if (hasActiveVMSnapshotTasks(vmSnapshot.getVmId())) {
        List<VMSnapshotVO> expungingSnapshots = _vmSnapshotDao.listByInstanceId(vmSnapshot.getVmId(), VMSnapshot.State.Expunging);
        if (expungingSnapshots.size() > 0 && expungingSnapshots.get(0).getId() == vmSnapshot.getId())
            s_logger.debug("Target VM snapshot already in expunging state, go on deleting it: " + vmSnapshot.getDisplayName());
        else
            throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
    }
    // serialize VM operation
    AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        VmWorkJobVO placeHolder = null;
        placeHolder = createPlaceHolderWork(vmSnapshot.getVmId());
        try {
            return orchestrateDeleteVMSnapshot(vmSnapshotId);
        } finally {
            _workJobDao.expunge(placeHolder.getId());
        }
    } else {
        Outcome<VMSnapshot> outcome = deleteVMSnapshotThroughJobQueue(vmSnapshot.getVmId(), vmSnapshotId);
        VMSnapshot result = null;
        try {
            result = outcome.get();
        } catch (InterruptedException e) {
            throw new RuntimeException("Operation is interrupted", e);
        } catch (java.util.concurrent.ExecutionException e) {
            throw new RuntimeException("Execution excetion", e);
        }
        Object jobResult = _jobMgr.unmarshallResultObject(outcome.getJob());
        if (jobResult != null) {
            if (jobResult instanceof ConcurrentOperationException)
                throw (ConcurrentOperationException) jobResult;
            else if (jobResult instanceof Throwable)
                throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
        }
        if (jobResult instanceof Boolean)
            return ((Boolean) jobResult).booleanValue();
        return false;
    }
}
Also used : Account(com.cloud.user.Account) AsyncJobExecutionContext(org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ActionEvent(com.cloud.event.ActionEvent)

Aggregations

AsyncJobExecutionContext (org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext)32 VmWorkJobVO (org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO)27 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)26 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)14 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)13 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)10 ActionEvent (com.cloud.event.ActionEvent)8 Account (com.cloud.user.Account)8 ExecutionException (java.util.concurrent.ExecutionException)8 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)8 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)7 UserVmVO (com.cloud.vm.UserVmVO)7 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)7 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)5 VMInstanceVO (com.cloud.vm.VMInstanceVO)5 VmWorkAttachVolume (com.cloud.vm.VmWorkAttachVolume)5 VmWorkDetachVolume (com.cloud.vm.VmWorkDetachVolume)5 VmWorkExtractVolume (com.cloud.vm.VmWorkExtractVolume)5 VmWorkMigrateVolume (com.cloud.vm.VmWorkMigrateVolume)5 VmWorkResizeVolume (com.cloud.vm.VmWorkResizeVolume)5