Search in sources :

Example 11 with AsyncJobExecutionContext

use of com.cloud.framework.jobs.AsyncJobExecutionContext in project cosmic by MissionCriticalCloud.

the class VirtualMachineManagerImpl method migrate.

@Override
public void migrate(final String vmUuid, final long srcHostId, final DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException, VirtualMachineMigrationException {
    final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        VmWorkJobVO placeHolder = null;
        final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
        placeHolder = createPlaceHolderWork(vm.getId());
        try {
            orchestrateMigrate(vmUuid, srcHostId, dest);
        } finally {
            if (placeHolder != null) {
                _workJobDao.expunge(placeHolder.getId());
            }
        }
    } else {
        final Outcome<VirtualMachine> outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest);
        try {
            final VirtualMachine vm = 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 ResourceUnavailableException) {
                throw (ResourceUnavailableException) jobResult;
            } else if (jobResult instanceof ConcurrentOperationException) {
                throw (ConcurrentOperationException) jobResult;
            } else if (jobResult instanceof Throwable) {
                final Throwable t = (Throwable) jobResult;
                throw new VirtualMachineMigrationException(t.getMessage(), t);
            }
        }
    }
}
Also used : AsyncJobExecutionContext(com.cloud.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(com.cloud.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) VirtualMachineMigrationException(com.cloud.exception.VirtualMachineMigrationException)

Example 12 with AsyncJobExecutionContext

use of com.cloud.framework.jobs.AsyncJobExecutionContext in project cosmic by MissionCriticalCloud.

the class VirtualMachineManagerImpl method migrateWithStorage.

@Override
public void migrateWithStorage(final String vmUuid, final long srcHostId, final long destHostId, final Map<Long, Long> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException {
    final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        VmWorkJobVO placeHolder = null;
        final VirtualMachine vm = _vmDao.findByUuid(vmUuid);
        placeHolder = createPlaceHolderWork(vm.getId());
        try {
            orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool);
        } finally {
            if (placeHolder != null) {
                _workJobDao.expunge(placeHolder.getId());
            }
        }
    } else {
        final Outcome<VirtualMachine> outcome = migrateVmWithStorageThroughJobQueue(vmUuid, srcHostId, destHostId, volumeToPool);
        try {
            final VirtualMachine vm = 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 jobException = _jobMgr.unmarshallResultObject(outcome.getJob());
        if (jobException != null) {
            if (jobException instanceof ResourceUnavailableException) {
                throw (ResourceUnavailableException) jobException;
            } else if (jobException instanceof ConcurrentOperationException) {
                throw (ConcurrentOperationException) jobException;
            } else if (jobException instanceof RuntimeException) {
                throw (RuntimeException) jobException;
            } else if (jobException instanceof Throwable) {
                throw new RuntimeException("Unexpected exception", (Throwable) jobException);
            }
        }
    }
}
Also used : AsyncJobExecutionContext(com.cloud.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(com.cloud.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException)

Example 13 with AsyncJobExecutionContext

use of com.cloud.framework.jobs.AsyncJobExecutionContext in project cosmic by MissionCriticalCloud.

the class AsyncJobManagerImpl method getExecutorRunnable.

private Runnable getExecutorRunnable(final AsyncJob job) {
    return new ManagedContextRunnable() {

        @Override
        public void run() {
            // register place-holder context to avoid installing system account call context
            if (CallContext.current() == null) {
                CallContext.registerPlaceHolderContext();
            }
            final String related = job.getRelated();
            String logContext = job.getShortUuid();
            if (related != null && !related.isEmpty()) {
                MDC.put("job", " (job: " + related + "/" + "job: " + job.getId() + ")");
                final AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
                if (relatedJob != null) {
                    logContext = relatedJob.getShortUuid();
                }
            } else {
                MDC.put("job", " (job: " + job.getId() + ")");
            }
            MDC.put("logcontextid", " (logid: " + logContext + ")");
            try {
                super.run();
            } finally {
                MDC.remove("job");
            }
        }

        @Override
        protected void runInContext() {
            final long runNumber = getJobRunNumber();
            try {
                // 
                try {
                    JmxUtil.registerMBean("AsyncJobManager", "Active Job " + job.getId(), new AsyncJobMBeanImpl(job));
                } catch (final Exception e) {
                    // is expected to fail under situations
                    if (s_logger.isTraceEnabled()) {
                        s_logger.trace("Unable to register active job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
                    }
                }
                _jobMonitor.registerActiveTask(runNumber, job.getId());
                AsyncJobExecutionContext.setCurrentExecutionContext(new AsyncJobExecutionContext(job));
                final String related = job.getRelated();
                String logContext = job.getShortUuid();
                if (related != null && !related.isEmpty()) {
                    final AsyncJob relatedJob = _jobDao.findByIdIncludingRemoved(Long.parseLong(related));
                    if (relatedJob != null) {
                        logContext = relatedJob.getShortUuid();
                    }
                }
                MDC.put("logcontextid", " (logid: " + logContext + ")");
                // execute the job
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Executing " + StringUtils.cleanString(job.toString()));
                }
                if ((getAndResetPendingSignals(job) & AsyncJob.Constants.SIGNAL_MASK_WAKEUP) != 0) {
                    final AsyncJobDispatcher jobDispatcher = getWakeupDispatcher(job);
                    if (jobDispatcher != null) {
                        jobDispatcher.runJob(job);
                    } else {
                        // TODO, job wakeup is not in use yet
                        if (s_logger.isTraceEnabled()) {
                            s_logger.trace("Unable to find a wakeup dispatcher from the joined job: " + job);
                        }
                    }
                } else {
                    final AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher());
                    if (jobDispatcher != null) {
                        jobDispatcher.runJob(job);
                    } else {
                        s_logger.error("Unable to find job dispatcher, job will be cancelled");
                        final ExceptionResponse response = new ExceptionResponse();
                        response.setErrorCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
                        response.setErrorText("Unable to find job dispatcher, job will be cancelled");
                        completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), JobSerializerHelper.toSerializedString(response));
                    }
                }
                if (s_logger.isDebugEnabled()) {
                    s_logger.debug("Done executing " + job.getCmd() + " for job-" + job.getId());
                }
            } catch (final Throwable e) {
                s_logger.error("Unexpected exception", e);
                final ExceptionResponse response = new ExceptionResponse();
                response.setErrorCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode());
                response.setErrorText(ExceptionUtils.getRootCauseMessage(e));
                completeAsyncJob(job.getId(), JobInfo.Status.FAILED, ApiErrorCode.INTERNAL_ERROR.getHttpCode(), JobSerializerHelper.toSerializedString(response));
            } finally {
                // guard final clause as well
                try {
                    if (job.getSyncSource() != null) {
                        // here check queue item one more time to double make sure that queue item is removed in case of any uncaught exception
                        _queueMgr.purgeItem(job.getSyncSource().getId());
                    }
                    try {
                        JmxUtil.unregisterMBean("AsyncJobManager", "Active Job " + job.getId());
                    } catch (final Exception e) {
                        // is expected to fail under situations
                        if (s_logger.isTraceEnabled()) {
                            s_logger.trace("Unable to unregister job " + job.getId() + " to JMX monitoring due to exception " + ExceptionUtil.toString(e));
                        }
                    }
                    // 
                    // clean execution environment
                    // 
                    AsyncJobExecutionContext.unregister();
                    _jobMonitor.unregisterActiveTask(runNumber);
                } catch (final Throwable e) {
                    s_logger.error("Double exception", e);
                }
            }
        }
    };
}
Also used : ManagedContextRunnable(com.cloud.managed.context.ManagedContextRunnable) ExceptionResponse(com.cloud.api.response.ExceptionResponse) AsyncJobExecutionContext(com.cloud.framework.jobs.AsyncJobExecutionContext) AsyncJob(com.cloud.framework.jobs.AsyncJob) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AsyncJobDispatcher(com.cloud.framework.jobs.AsyncJobDispatcher)

Example 14 with AsyncJobExecutionContext

use of com.cloud.framework.jobs.AsyncJobExecutionContext in project cosmic by MissionCriticalCloud.

the class VMSnapshotManagerImpl method deleteVMSnapshot.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete vm snapshots", async = true)
public boolean deleteVMSnapshot(final Long vmSnapshotId) {
    final Account caller = getCaller();
    final 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())) {
        final 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
    final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        final VmWorkJobVO placeHolder;
        placeHolder = createPlaceHolderWork(vmSnapshot.getVmId());
        try {
            return orchestrateDeleteVMSnapshot(vmSnapshotId);
        } finally {
            _workJobDao.expunge(placeHolder.getId());
        }
    } else {
        final Outcome<VMSnapshot> outcome = deleteVMSnapshotThroughJobQueue(vmSnapshot.getVmId(), vmSnapshotId);
        VMSnapshot result = null;
        try {
            result = outcome.get();
        } catch (final InterruptedException e) {
            throw new RuntimeException("Operation is interrupted", e);
        } catch (final 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 Throwable) {
                throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
            }
        }
        if (jobResult instanceof Boolean) {
            return (Boolean) jobResult;
        }
        return false;
    }
}
Also used : Account(com.cloud.user.Account) AsyncJobExecutionContext(com.cloud.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(com.cloud.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ExecutionException(java.util.concurrent.ExecutionException) ActionEvent(com.cloud.event.ActionEvent)

Example 15 with AsyncJobExecutionContext

use of com.cloud.framework.jobs.AsyncJobExecutionContext in project cosmic by MissionCriticalCloud.

the class VMSnapshotManagerImpl method revertToSnapshot.

@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_REVERT, eventDescription = "revert to VM snapshot", async = true)
public UserVm revertToSnapshot(final Long vmSnapshotId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
    // check if VM snapshot exists in DB
    final VMSnapshotVO vmSnapshotVo = _vmSnapshotDao.findById(vmSnapshotId);
    if (vmSnapshotVo == null) {
        throw new InvalidParameterValueException("unable to find the vm snapshot with id " + vmSnapshotId);
    }
    final Long vmId = vmSnapshotVo.getVmId();
    final UserVmVO userVm = _userVMDao.findById(vmId);
    // check if VM exists
    if (userVm == null) {
        throw new InvalidParameterValueException("Revert vm to snapshot: " + vmSnapshotId + " failed due to vm: " + vmId + " is not found");
    }
    // check if there are other active VM snapshot tasks
    if (hasActiveVMSnapshotTasks(vmId)) {
        throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
    }
    final Account caller = getCaller();
    _accountMgr.checkAccess(caller, null, true, vmSnapshotVo);
    // VM should be in running or stopped states
    if (userVm.getState() != VirtualMachine.State.Running && userVm.getState() != VirtualMachine.State.Stopped) {
        throw new InvalidParameterValueException("VM Snapshot reverting failed due to vm is not in the state of Running or Stopped.");
    }
    if (userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk || userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory) {
        throw new InvalidParameterValueException("VM Snapshot revert not allowed. This will result in VM state change. You can revert running VM to disk and memory type snapshot and stopped VM to disk type" + " snapshot");
    }
    // if snapshot is not created, error out
    if (vmSnapshotVo.getState() != VMSnapshot.State.Ready) {
        throw new InvalidParameterValueException("VM Snapshot reverting failed due to vm snapshot is not in the state of Created.");
    }
    // serialize VM operation
    final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
    if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
        // avoid re-entrance
        final VmWorkJobVO placeHolder;
        placeHolder = createPlaceHolderWork(vmSnapshotVo.getVmId());
        try {
            return orchestrateRevertToVMSnapshot(vmSnapshotId);
        } finally {
            _workJobDao.expunge(placeHolder.getId());
        }
    } else {
        final Outcome<VMSnapshot> outcome = revertToVMSnapshotThroughJobQueue(vmSnapshotVo.getVmId(), vmSnapshotId);
        VMSnapshot result = null;
        try {
            result = outcome.get();
        } catch (final InterruptedException e) {
            throw new RuntimeException("Operation is interrupted", e);
        } catch (final 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 InsufficientCapacityException) {
                throw (InsufficientCapacityException) jobResult;
            } else if (jobResult instanceof ResourceUnavailableException) {
                throw (ResourceUnavailableException) jobResult;
            } else if (jobResult instanceof Throwable) {
                throw new RuntimeException("Unexpected exception", (Throwable) jobResult);
            }
        }
        return userVm;
    }
}
Also used : Account(com.cloud.user.Account) UserVmVO(com.cloud.vm.UserVmVO) AsyncJobExecutionContext(com.cloud.framework.jobs.AsyncJobExecutionContext) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) VmWorkJobVO(com.cloud.framework.jobs.impl.VmWorkJobVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InvalidParameterValueException(com.cloud.utils.exception.InvalidParameterValueException) ResourceUnavailableException(com.cloud.exception.ResourceUnavailableException) ExecutionException(java.util.concurrent.ExecutionException) InsufficientCapacityException(com.cloud.exception.InsufficientCapacityException) ActionEvent(com.cloud.event.ActionEvent)

Aggregations

AsyncJobExecutionContext (com.cloud.framework.jobs.AsyncJobExecutionContext)23 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)22 VmWorkJobVO (com.cloud.framework.jobs.impl.VmWorkJobVO)21 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)20 InvalidParameterValueException (com.cloud.utils.exception.InvalidParameterValueException)10 ExecutionException (java.util.concurrent.ExecutionException)10 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)9 ActionEvent (com.cloud.event.ActionEvent)8 DataObject (com.cloud.engine.subsystem.api.storage.DataObject)6 Account (com.cloud.user.Account)6 UserVmVO (com.cloud.vm.UserVmVO)6 InsufficientCapacityException (com.cloud.exception.InsufficientCapacityException)4 VmWorkAttachVolume (com.cloud.vm.VmWorkAttachVolume)4 VmWorkDetachVolume (com.cloud.vm.VmWorkDetachVolume)4 VmWorkExtractVolume (com.cloud.vm.VmWorkExtractVolume)4 VmWorkMigrateVolume (com.cloud.vm.VmWorkMigrateVolume)4 VmWorkResizeVolume (com.cloud.vm.VmWorkResizeVolume)4 VolumeInfo (com.cloud.engine.subsystem.api.storage.VolumeInfo)3 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)3 AsyncJob (com.cloud.framework.jobs.AsyncJob)3