@Test public void testDetachVolumeFromStoppedXenVm() throws NoSuchFieldException, IllegalAccessException { thrown.expect(NullPointerException.class); final Field dedicateIdField = _detachCmdClass.getDeclaredField("id"); dedicateIdField.setAccessible(true); dedicateIdField.set(detachCmd, 2L); _svc.detachVolumeFromVM(detachCmd); }
@Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(final DetachVolumeCmd cmmd) { final Account caller = CallContext.current().getCallingAccount(); if (cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null || cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null) || cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null)) { throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)"); } final Long volumeId = cmmd.getId(); final VolumeVO volume; if (volumeId != null) { volume = this._volsDao.findById(volumeId); } else { volume = this._volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0); } if (volume == null) { throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId); } final Long vmId; if (cmmd.getVirtualMachineId() == null) { vmId = volume.getInstanceId(); } else { vmId = cmmd.getVirtualMachineId(); } this._accountMgr.checkAccess(caller, null, true, volume); if (vmId == null) { throw new InvalidParameterValueException("The specified volume is not attached to a VM."); } final UserVmVO vm = this._userVmDao.findById(vmId); if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } if (!(volume.getVolumeType() == VolumeType.ROOT || volume.getVolumeType() == VolumeType.DATADISK)) { throw new InvalidParameterValueException("Please specify volume of type " + VolumeType.DATADISK.toString() + " or " + VolumeType.ROOT.toString()); } if (volume.getVolumeType() == VolumeType.ROOT) { validateRootVolumeDetachAttach(volume, vm); } final List<VMSnapshotVO> vmSnapshots = this._vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); } final AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { final 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"); } this._jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { final VmWorkJobVO placeHolder; placeHolder = createPlaceHolderWork(vmId); try { return orchestrateDetachVolumeFromVM(vmId, volumeId); } finally { this._workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); Volume vol = null; try { outcome.get(); } catch (final InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (final java.util.concurrent.ExecutionException e) { throw new RuntimeException("Execution excetion", e); } final Object jobResult = this._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); } else if (jobResult instanceof Long) { vol = this._volsDao.findById((Long) jobResult); } } return vol; } }
VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler { @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(final DetachVolumeCmd cmmd) { final Account caller = CallContext.current().getCallingAccount(); if (cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null || cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null) || cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null)) { throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)"); } final Long volumeId = cmmd.getId(); final VolumeVO volume; if (volumeId != null) { volume = this._volsDao.findById(volumeId); } else { volume = this._volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0); } if (volume == null) { throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId); } final Long vmId; if (cmmd.getVirtualMachineId() == null) { vmId = volume.getInstanceId(); } else { vmId = cmmd.getVirtualMachineId(); } this._accountMgr.checkAccess(caller, null, true, volume); if (vmId == null) { throw new InvalidParameterValueException("The specified volume is not attached to a VM."); } final UserVmVO vm = this._userVmDao.findById(vmId); if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } if (!(volume.getVolumeType() == VolumeType.ROOT || volume.getVolumeType() == VolumeType.DATADISK)) { throw new InvalidParameterValueException("Please specify volume of type " + VolumeType.DATADISK.toString() + " or " + VolumeType.ROOT.toString()); } if (volume.getVolumeType() == VolumeType.ROOT) { validateRootVolumeDetachAttach(volume, vm); } final List<VMSnapshotVO> vmSnapshots = this._vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); } final AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { final 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"); } this._jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { final VmWorkJobVO placeHolder; placeHolder = createPlaceHolderWork(vmId); try { return orchestrateDetachVolumeFromVM(vmId, volumeId); } finally { this._workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); Volume vol = null; try { outcome.get(); } catch (final InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (final java.util.concurrent.ExecutionException e) { throw new RuntimeException("Execution excetion", e); } final Object jobResult = this._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); } else if (jobResult instanceof Long) { vol = this._volsDao.findById((Long) jobResult); } } return vol; } } }
VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler { @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(final DetachVolumeCmd cmmd) { final Account caller = CallContext.current().getCallingAccount(); if (cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null || cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null) || cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null)) { throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)"); } final Long volumeId = cmmd.getId(); final VolumeVO volume; if (volumeId != null) { volume = this._volsDao.findById(volumeId); } else { volume = this._volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0); } if (volume == null) { throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId); } final Long vmId; if (cmmd.getVirtualMachineId() == null) { vmId = volume.getInstanceId(); } else { vmId = cmmd.getVirtualMachineId(); } this._accountMgr.checkAccess(caller, null, true, volume); if (vmId == null) { throw new InvalidParameterValueException("The specified volume is not attached to a VM."); } final UserVmVO vm = this._userVmDao.findById(vmId); if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } if (!(volume.getVolumeType() == VolumeType.ROOT || volume.getVolumeType() == VolumeType.DATADISK)) { throw new InvalidParameterValueException("Please specify volume of type " + VolumeType.DATADISK.toString() + " or " + VolumeType.ROOT.toString()); } if (volume.getVolumeType() == VolumeType.ROOT) { validateRootVolumeDetachAttach(volume, vm); } final List<VMSnapshotVO> vmSnapshots = this._vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); } final AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { final 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"); } this._jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { final VmWorkJobVO placeHolder; placeHolder = createPlaceHolderWork(vmId); try { return orchestrateDetachVolumeFromVM(vmId, volumeId); } finally { this._workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); Volume vol = null; try { outcome.get(); } catch (final InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (final java.util.concurrent.ExecutionException e) { throw new RuntimeException("Execution excetion", e); } final Object jobResult = this._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); } else if (jobResult instanceof Long) { vol = this._volsDao.findById((Long) jobResult); } } return vol; } } protected  VolumeApiServiceImpl(); }
VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler { @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(final DetachVolumeCmd cmmd) { final Account caller = CallContext.current().getCallingAccount(); if (cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null || cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null) || cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null)) { throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)"); } final Long volumeId = cmmd.getId(); final VolumeVO volume; if (volumeId != null) { volume = this._volsDao.findById(volumeId); } else { volume = this._volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0); } if (volume == null) { throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId); } final Long vmId; if (cmmd.getVirtualMachineId() == null) { vmId = volume.getInstanceId(); } else { vmId = cmmd.getVirtualMachineId(); } this._accountMgr.checkAccess(caller, null, true, volume); if (vmId == null) { throw new InvalidParameterValueException("The specified volume is not attached to a VM."); } final UserVmVO vm = this._userVmDao.findById(vmId); if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } if (!(volume.getVolumeType() == VolumeType.ROOT || volume.getVolumeType() == VolumeType.DATADISK)) { throw new InvalidParameterValueException("Please specify volume of type " + VolumeType.DATADISK.toString() + " or " + VolumeType.ROOT.toString()); } if (volume.getVolumeType() == VolumeType.ROOT) { validateRootVolumeDetachAttach(volume, vm); } final List<VMSnapshotVO> vmSnapshots = this._vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); } final AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { final 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"); } this._jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { final VmWorkJobVO placeHolder; placeHolder = createPlaceHolderWork(vmId); try { return orchestrateDetachVolumeFromVM(vmId, volumeId); } finally { this._workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); Volume vol = null; try { outcome.get(); } catch (final InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (final java.util.concurrent.ExecutionException e) { throw new RuntimeException("Execution excetion", e); } final Object jobResult = this._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); } else if (jobResult instanceof Long) { vol = this._volsDao.findById((Long) jobResult); } } return vol; } } protected  VolumeApiServiceImpl(); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true) VolumeVO allocVolume(final CreateVolumeCmd cmd); boolean validateVolumeSizeRange(final long size); String getVolumeNameFromCommand(final CreateVolumeCmd cmd); String getRandomVolumeName(); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true) VolumeVO createVolume(final CreateVolumeCmd cmd); Volume attachVolumeToVM(final Long vmId, final Long volumeId, final Long deviceId); Outcome<Volume> attachVolumeToVmThroughJobQueue(final Long vmId, final Long volumeId, final Long deviceId, final DiskControllerType diskController); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true) VolumeVO resizeVolume(final ResizeVolumeCmd cmd); Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                       final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops, final Long newServiceOfferingId,
                                                       final boolean shrinkOk); @DB @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true) Volume migrateVolume(final MigrateVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) VolumeVO uploadVolume(final UploadVolumeCmd cmd); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true) GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") boolean deleteVolume(final long volumeId, final Account caller); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true) Volume attachVolumeToVM(final AttachVolumeCmd command); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) Volume detachVolumeFromVM(final DetachVolumeCmd cmmd); Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true) Snapshot takeSnapshot(final Long volumeId, final Long policyId, final Long snapshotId, final Account account, final boolean quiescevm); Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId,
                                                               final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true) Snapshot allocSnapshot(final Long volumeId, final Long policyId, final String snapshotName); @Override Snapshot allocSnapshotForVm(final Long vmId, final Long volumeId, final String snapshotName); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) Volume updateVolume(final long volumeId, final String name, final String path, final String state, final Long storageId, final Boolean displayVolume, final String customId, final long
            entityOwnerId, final String chainInfo, final DiskControllerType diskControllerType); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) String extractVolume(final ExtractVolumeCmd cmd); Outcome<String> extractVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                        final long zoneId); @Override boolean isDisplayResourceEnabled(final Long id); @Override void updateDisplay(final Volume volume, final Boolean displayVolume); Outcome<Volume> migrateVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                        final long destPoolId, final boolean liveMigrate); @Override boolean configure(final String name, final Map<String, Object> params); List<StoragePoolAllocator> getStoragePoolAllocators(); @Inject void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators); @Override Pair<JobInfo.Status, String> handleVmWorkJob(final VmWork work); }
VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler { @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(final DetachVolumeCmd cmmd) { final Account caller = CallContext.current().getCallingAccount(); if (cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null || cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null) || cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd.getVirtualMachineId() == null)) { throw new InvalidParameterValueException("Please provide either a volume id, or a tuple(device id, instance id)"); } final Long volumeId = cmmd.getId(); final VolumeVO volume; if (volumeId != null) { volume = this._volsDao.findById(volumeId); } else { volume = this._volsDao.findByInstanceAndDeviceId(cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0); } if (volume == null) { throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId); } final Long vmId; if (cmmd.getVirtualMachineId() == null) { vmId = volume.getInstanceId(); } else { vmId = cmmd.getVirtualMachineId(); } this._accountMgr.checkAccess(caller, null, true, volume); if (vmId == null) { throw new InvalidParameterValueException("The specified volume is not attached to a VM."); } final UserVmVO vm = this._userVmDao.findById(vmId); if (vm.getState() != State.Running && vm.getState() != State.Stopped && vm.getState() != State.Destroyed) { throw new InvalidParameterValueException("Please specify a VM that is either running or stopped."); } if (!(volume.getVolumeType() == VolumeType.ROOT || volume.getVolumeType() == VolumeType.DATADISK)) { throw new InvalidParameterValueException("Please specify volume of type " + VolumeType.DATADISK.toString() + " or " + VolumeType.ROOT.toString()); } if (volume.getVolumeType() == VolumeType.ROOT) { validateRootVolumeDetachAttach(volume, vm); } final List<VMSnapshotVO> vmSnapshots = this._vmSnapshotDao.findByVm(vmId); if (vmSnapshots.size() > 0) { throw new InvalidParameterValueException("Unable to detach volume, please specify a VM that does not have VM snapshots"); } final AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (asyncExecutionContext != null) { final 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"); } this._jobMgr.updateAsyncJobAttachment(job.getId(), "Volume", volumeId); } final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { final VmWorkJobVO placeHolder; placeHolder = createPlaceHolderWork(vmId); try { return orchestrateDetachVolumeFromVM(vmId, volumeId); } finally { this._workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Volume> outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); Volume vol = null; try { outcome.get(); } catch (final InterruptedException e) { throw new RuntimeException("Operation is interrupted", e); } catch (final java.util.concurrent.ExecutionException e) { throw new RuntimeException("Execution excetion", e); } final Object jobResult = this._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); } else if (jobResult instanceof Long) { vol = this._volsDao.findById((Long) jobResult); } } return vol; } } protected  VolumeApiServiceImpl(); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true) VolumeVO allocVolume(final CreateVolumeCmd cmd); boolean validateVolumeSizeRange(final long size); String getVolumeNameFromCommand(final CreateVolumeCmd cmd); String getRandomVolumeName(); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true) VolumeVO createVolume(final CreateVolumeCmd cmd); Volume attachVolumeToVM(final Long vmId, final Long volumeId, final Long deviceId); Outcome<Volume> attachVolumeToVmThroughJobQueue(final Long vmId, final Long volumeId, final Long deviceId, final DiskControllerType diskController); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true) VolumeVO resizeVolume(final ResizeVolumeCmd cmd); Outcome<Volume> resizeVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                       final long currentSize, final long newSize, final Long newMinIops, final Long newMaxIops, final Long newServiceOfferingId,
                                                       final boolean shrinkOk); @DB @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true) Volume migrateVolume(final MigrateVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) VolumeVO uploadVolume(final UploadVolumeCmd cmd); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true) GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") boolean deleteVolume(final long volumeId, final Account caller); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true) Volume attachVolumeToVM(final AttachVolumeCmd command); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) Volume detachVolumeFromVM(final DetachVolumeCmd cmmd); Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true) Snapshot takeSnapshot(final Long volumeId, final Long policyId, final Long snapshotId, final Account account, final boolean quiescevm); Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId,
                                                               final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true) Snapshot allocSnapshot(final Long volumeId, final Long policyId, final String snapshotName); @Override Snapshot allocSnapshotForVm(final Long vmId, final Long volumeId, final String snapshotName); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) Volume updateVolume(final long volumeId, final String name, final String path, final String state, final Long storageId, final Boolean displayVolume, final String customId, final long
            entityOwnerId, final String chainInfo, final DiskControllerType diskControllerType); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) String extractVolume(final ExtractVolumeCmd cmd); Outcome<String> extractVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                        final long zoneId); @Override boolean isDisplayResourceEnabled(final Long id); @Override void updateDisplay(final Volume volume, final Boolean displayVolume); Outcome<Volume> migrateVolumeThroughJobQueue(final Long vmId, final long volumeId,
                                                        final long destPoolId, final boolean liveMigrate); @Override boolean configure(final String name, final Map<String, Object> params); List<StoragePoolAllocator> getStoragePoolAllocators(); @Inject void setStoragePoolAllocators(final List<StoragePoolAllocator> storagePoolAllocators); @Override Pair<JobInfo.Status, String> handleVmWorkJob(final VmWork work); static final String VM_WORK_JOB_HANDLER; }