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);
}
}
}
}
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);
}
}
}
}
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);
}
}
}
};
}
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;
}
}
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;
}
}
Aggregations