VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler { @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true) public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm) throws ResourceAllocationException { final VolumeInfo volume = volFactory.getVolume(volumeId); if (volume == null) { throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); } if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } VMInstanceVO vm = null; if (volume.getInstanceId() != null) { vm = _vmInstanceDao.findById(volume.getInstanceId()); } if (vm != null) { final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { VmWorkJobVO placeHolder = null; placeHolder = createPlaceHolderWork(vm.getId()); try { return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm); } finally { _workJobDao.expunge(placeHolder.getId()); } } else { final Outcome<Snapshot> outcome = takeVolumeSnapshotThroughJobQueue(vm.getId(), volumeId, policyId, snapshotId, account.getId(), quiescevm); 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 = _jobMgr.unmarshallResultObject(outcome.getJob()); if (jobResult != null) { if (jobResult instanceof ConcurrentOperationException) { throw (ConcurrentOperationException)jobResult; } else if (jobResult instanceof ResourceAllocationException) { throw (ResourceAllocationException)jobResult; } else if (jobResult instanceof Throwable) { throw new RuntimeException("Unexpected exception", (Throwable)jobResult); } } return _snapshotDao.findById(snapshotId); } } else { final CreateSnapshotPayload payload = new CreateSnapshotPayload(); payload.setSnapshotId(snapshotId); payload.setSnapshotPolicyId(policyId); payload.setAccount(account); payload.setQuiescevm(quiescevm); volume.addPayload(payload); return volService.takeSnapshot(volume); } } protected  VolumeApiServiceImpl(); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true) VolumeVO uploadVolume(UploadVolumeCmd cmd); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume for post upload", async = true) GetUploadParamsResponse uploadVolume(final GetUploadParamsForVolumeCmd cmd); String getRandomVolumeName(); String getVolumeNameFromCommand(CreateVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true) VolumeVO allocVolume(CreateVolumeCmd cmd); boolean validateVolumeSizeRange(long size); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true) VolumeVO createVolume(CreateVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true) VolumeVO resizeVolume(ResizeVolumeCmd cmd); @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") boolean deleteVolume(long volumeId, Account caller); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true) Volume attachVolumeToVM(AttachVolumeCmd command); Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true) Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId, String chainInfo); @Override void updateDisplay(Volume volume, Boolean displayVolume); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) Volume detachVolumeFromVM(DetachVolumeCmd cmmd); @DB @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true) Volume migrateVolume(MigrateVolumeCmd cmd); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "taking snapshot", async = true) Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm); @Override @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_CREATE, eventDescription = "allocating snapshot", create = true) Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName); @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) String extractVolume(ExtractVolumeCmd cmd); @Override boolean isDisplayResourceEnabled(Long id); @Override boolean configure(String name, Map<String, Object> params); List<StoragePoolAllocator> getStoragePoolAllocators(); @Inject void setStoragePoolAllocators(List<StoragePoolAllocator> storagePoolAllocators); Outcome<Volume> attachVolumeToVmThroughJobQueue(final Long vmId, final Long volumeId, final Long deviceId); Outcome<Volume> detachVolumeFromVmThroughJobQueue(final Long vmId, final Long volumeId); 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); Outcome<String> extractVolumeThroughJobQueue(final Long vmId, final long volumeId,
      final long zoneId); Outcome<Volume> migrateVolumeThroughJobQueue(final Long vmId, final long volumeId,
      final long destPoolId, final boolean liveMigrate); Outcome<Snapshot> takeVolumeSnapshotThroughJobQueue(final Long vmId, final Long volumeId,
      final Long policyId, final Long snapshotId, final Long accountId, final boolean quiesceVm); @Override Pair<JobInfo.Status, String> handleVmWorkJob(VmWork work); static final String VM_WORK_JOB_HANDLER; }
@Test(expected = InvalidParameterValueException.class) public void testTakeSnapshotF1() throws ResourceAllocationException { when(_volFactory.getVolume(anyLong())).thenReturn(volumeInfoMock); when(volumeInfoMock.getState()).thenReturn(Volume.State.Allocated); _svc.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false); }
@Test public void testTakeSnapshotF2() throws ResourceAllocationException { when(_volFactory.getVolume(anyLong())).thenReturn(volumeInfoMock); when(volumeInfoMock.getState()).thenReturn(Volume.State.Ready); when(volumeInfoMock.getInstanceId()).thenReturn(null); when (volService.takeSnapshot(Mockito.any(VolumeInfo.class))).thenReturn(snapshotInfoMock); _svc.takeSnapshot(5L, Snapshot.MANUAL_POLICY_ID, 3L, null, false); }