add job path to help associate an API job to related internal job. Reviewed-By: Self

This commit is contained in:
Kelven Yang 2014-02-19 17:22:28 -08:00
parent 414b1cbb22
commit 537bf7ced1
14 changed files with 95 additions and 73 deletions

View File

@ -131,7 +131,10 @@ public class CallContext {
protected static CallContext register(User callingUser, Account callingAccount, Long userId, Long accountId, String contextId) {
/*
<<<<<<< HEAD
Unit tests will have multiple times of setup/tear-down call to this, remove assertions to all unit test to run
=======
>>>>>>> a7a8a19... BUG-ID: CS-19295: add job path to help associate an API job to related internal job. Reviewed-By: Self
assert s_currentContext.get() == null : "There's a context already so what does this new register context mean? " + s_currentContext.get().toString();
if (s_currentContext.get() != null) { // FIXME: This should be removed soon. I added this check only to surface all the places that have this problem.
throw new CloudRuntimeException("There's a context already so what does this new register context mean? " + s_currentContext.get().toString());
@ -154,6 +157,14 @@ public class CallContext {
return callingContext;
}
public static CallContext registerPlaceHolderContext() {
CallContext context = new CallContext(0, 0, UUID.randomUUID().toString());
s_currentContext.set(context);
s_currentContextStack.get().push(context);
return context;
}
public static CallContext register(User callingUser, Account callingAccount) {
return register(callingUser, callingAccount, UUID.randomUUID().toString());
}

View File

@ -32,10 +32,9 @@ public class CallContextListener implements ManagedContextListener<Object> {
@Override
public Object onEnterContext(boolean reentry) {
if (!reentry) {
if (!reentry && CallContext.current() == null) {
CallContext.registerSystemCallContextOnceOnly();
}
return null;
}

View File

@ -4436,7 +4436,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkStart workInfo = new VmWorkStart(callingUser.getId(), callingAccount.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER);
@ -4493,7 +4493,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setStep(VmWorkJobVO.Step.Prepare);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkStop workInfo = new VmWorkStop(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, cleanup);
@ -4549,7 +4549,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setStep(VmWorkJobVO.Step.Prepare);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkReboot workInfo = new VmWorkReboot(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, params);
@ -4604,7 +4604,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkMigrate workInfo = new VmWorkMigrate(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId, dest);
@ -4656,7 +4656,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkMigrateAway workInfo = new VmWorkMigrateAway(user.getId(), account.getId(), vm.getId(), VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, srcHostId);
@ -4713,7 +4713,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkMigrateWithStorage workInfo = new VmWorkMigrateWithStorage(user.getId(), account.getId(), vm.getId(),
@ -4770,7 +4770,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkMigrateForScale workInfo = new VmWorkMigrateForScale(user.getId(), account.getId(), vm.getId(),
@ -4827,7 +4827,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkStorageMigration workInfo = new VmWorkStorageMigration(user.getId(), account.getId(), vm.getId(),
@ -4883,7 +4883,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
@ -4937,7 +4937,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkRemoveNicFromVm workInfo = new VmWorkRemoveNicFromVm(user.getId(), account.getId(), vm.getId(),
@ -4991,7 +4991,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkRemoveVmFromNetwork workInfo = new VmWorkRemoveVmFromNetwork(user.getId(), account.getId(), vm.getId(),
@ -5047,7 +5047,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
workJob.setUserId(user.getId());
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkReconfigure workInfo = new VmWorkReconfigure(user.getId(), account.getId(), vm.getId(),

View File

@ -96,10 +96,14 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch
return;
}
CallContext.register(work.getUserId(), work.getAccountId(), job.getRelated());
CallContext.register(work.getUserId(), work.getAccountId());
Pair<JobInfo.Status, String> result = handler.handleVmWorkJob(work);
_asyncJobMgr.completeAsyncJob(job.getId(), result.first(), 0, result.second());
try {
Pair<JobInfo.Status, String> result = handler.handleVmWorkJob(work);
_asyncJobMgr.completeAsyncJob(job.getId(), result.first(), 0, result.second());
} finally {
CallContext.unregister();
}
} finally {
if (s_logger.isDebugEnabled())
s_logger.debug("Done with run of VM work job: " + cmd + " for VM " + work.getVmId() + ", job origin: " + job.getRelated());
@ -109,8 +113,6 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch
RuntimeException ex = new RuntimeException("Job failed due to exception " + e.getMessage());
_asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, _asyncJobMgr.marshallResultObject(ex));
} finally {
CallContext.unregister();
}
}
}

View File

@ -204,7 +204,11 @@ public class AsyncJobExecutionContext {
s_currentExectionContext.set(currentContext);
}
public static String getOriginJobContextId() {
return String.valueOf(CallContext.current().getContextId());
public static String getOriginJobId() {
AsyncJobExecutionContext context = AsyncJobExecutionContext.getCurrentExecutionContext();
if (context != null && context.getJob() != null)
return "Job-" + context.getJob().getId();
return "";
}
}

View File

@ -34,8 +34,10 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.ConfigDepot;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
@ -428,6 +430,24 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
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();
if (job.getRelated() != null && !job.getRelated().isEmpty())
NDC.push("Job-" + job.getRelated() + "/" + "Job-" + job.getId());
else
NDC.push("Job-" + job.getId());
try {
super.run();
} finally {
NDC.pop();
}
}
@Override
protected void runInContext() {
long runNumber = getJobRunNumber();

View File

@ -132,7 +132,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
public AsyncJobVO() {
uuid = UUID.randomUUID().toString();
related = UUID.randomUUID().toString();
related = "";
status = Status.IN_PROGRESS;
}

View File

@ -42,7 +42,7 @@ public abstract class ManagedContextRunnable implements Runnable {
}
@Override
final public void run() {
public void run() {
getContext().runWithContext(new Runnable() {
@Override
public void run() {

View File

@ -36,7 +36,6 @@ import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.jobs.JobInfo;
import org.apache.cloudstack.managed.context.ManagedContext;
import com.cloud.user.Account;
import com.cloud.user.User;
@ -54,23 +53,12 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
private AsyncJobManager _asyncJobMgr;
@Inject
private EntityManager _entityMgr;
@Inject
ManagedContext _managedContext;
public ApiAsyncJobDispatcher() {
}
@Override
public void runJob(final AsyncJob job) {
_managedContext.runWithContext(new Runnable() {
@Override
public void run() {
runJobInContext(job);
}
});
}
protected void runJobInContext(AsyncJob job) {
BaseAsyncCmd cmdObj = null;
try {
Class<?> cmdClass = Class.forName(job.getCmd());
@ -106,7 +94,7 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat
accountObject = _entityMgr.findById(Account.class, Long.parseLong(acctIdStr));
}
CallContext.register(user, accountObject, job.getRelated());
CallContext.register(user, accountObject);
try {
// dispatch could ultimately queue the job
_dispatcher.dispatch(cmdObj, params, true);

View File

@ -522,9 +522,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
params.put("cmdEventType", asyncCmd.getEventType().toString());
Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId;
AsyncJobVO job =
new AsyncJobVO(ctx.getContextId(), callerUserId, caller.getId(), cmdObj.getClass().getName(), ApiGsonHelper.getBuilder().create().toJson(params),
instanceId, asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null);
AsyncJobVO job = new AsyncJobVO("", callerUserId, caller.getId(), cmdObj.getClass().getName(),
ApiGsonHelper.getBuilder().create().toJson(params), instanceId,
asyncCmd.getInstanceType() != null ? asyncCmd.getInstanceType().toString() : null);
job.setDispatcher(_asyncDispatcher.getName());
long jobId = _asyncMgr.submitAsyncJob(job);

View File

@ -30,7 +30,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -106,6 +105,7 @@ import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiAsyncJobDispatcher;
import com.cloud.api.ApiDispatcher;
import com.cloud.api.ApiGsonHelper;
import com.cloud.cluster.ManagementServerHostVO;
import com.cloud.cluster.dao.ManagementServerHostDao;
@ -4194,26 +4194,26 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
return (Version.compare(trimmedVersion, MinVRVersion) >= 0);
}
private List<Long> rebootRouters(final List<DomainRouterVO> routers) {
final List<Long> jobIds = new ArrayList<Long>();
for (final DomainRouterVO router : routers) {
if (!checkRouterVersion(router)) {
s_logger.debug("Upgrading template for router: " + router.getId());
final Map<String, String> params = new HashMap<String, String>();
params.put("ctxUserId", "1");
params.put("ctxAccountId", "" + router.getAccountId());
private List<Long> rebootRouters(List<DomainRouterVO> routers){
List<Long> jobIds = new ArrayList<Long>();
for(DomainRouterVO router: routers){
if(!checkRouterVersion(router)){
s_logger.debug("Upgrading template for router: "+router.getId());
ApiDispatcher.getInstance();
Map<String, String> params = new HashMap<String, String>();
params.put("ctxUserId", "1");
params.put("ctxAccountId", "" + router.getAccountId());
final RebootRouterCmd cmd = new RebootRouterCmd();
ComponentContext.inject(cmd);
params.put("id", "" + router.getId());
params.put("ctxStartEventId", "1");
final AsyncJobVO job =
new AsyncJobVO(UUID.randomUUID().toString(), User.UID_SYSTEM, router.getAccountId(), RebootRouterCmd.class.getName(), ApiGsonHelper.getBuilder()
.create()
.toJson(params), router.getId(), cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
job.setDispatcher(_asyncDispatcher.getName());
final long jobId = _asyncMgr.submitAsyncJob(job);
jobIds.add(jobId);
RebootRouterCmd cmd = new RebootRouterCmd();
ComponentContext.inject(cmd);
params.put("id", ""+router.getId());
params.put("ctxStartEventId", "1");
AsyncJobVO job = new AsyncJobVO("", User.UID_SYSTEM, router.getAccountId(), RebootRouterCmd.class.getName(),
ApiGsonHelper.getBuilder().create().toJson(params), router.getId(),
cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
job.setDispatcher(_asyncDispatcher.getName());
long jobId = _asyncMgr.submitAsyncJob(job);
jobIds.add(jobId);
} else {
s_logger.debug("Router: " + router.getId() + " is already at the latest version. No upgrade required");
}

View File

@ -2141,7 +2141,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkAttachVolume workInfo = new VmWorkAttachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -2192,7 +2192,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkDetachVolume workInfo = new VmWorkDetachVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -2242,7 +2242,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkResizeVolume workInfo = new VmWorkResizeVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -2291,7 +2291,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkMigrateVolume workInfo = new VmWorkMigrateVolume(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -2340,7 +2340,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkTakeVolumeSnapshot workInfo = new VmWorkTakeVolumeSnapshot(

View File

@ -22,7 +22,6 @@ import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
@ -261,10 +260,9 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
params.put("id", "" + cmd.getEntityId());
params.put("ctxStartEventId", "1");
AsyncJobVO job =
new AsyncJobVO(UUID.randomUUID().toString(), User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(), ApiGsonHelper.getBuilder()
.create()
.toJson(params), cmd.getEntityId(), cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
AsyncJobVO job = new AsyncJobVO("", User.UID_SYSTEM, volume.getAccountId(), CreateSnapshotCmd.class.getName(),
ApiGsonHelper.getBuilder().create().toJson(params), cmd.getEntityId(),
cmd.getInstanceType() != null ? cmd.getInstanceType().toString() : null);
job.setDispatcher(_asyncDispatcher.getName());
long jobId = _asyncMgr.submitAsyncJob(job);

View File

@ -875,7 +875,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkCreateVMSnapshot workInfo = new VmWorkCreateVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -923,7 +923,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkDeleteVMSnapshot workInfo = new VmWorkDeleteVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -971,7 +971,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkRevertToVMSnapshot workInfo = new VmWorkRevertToVMSnapshot(callingUser.getId(), callingAccount.getId(), vm.getId(),
@ -1019,7 +1019,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana
workJob.setStep(VmWorkJobVO.Step.Starting);
workJob.setVmType(VirtualMachine.Type.Instance);
workJob.setVmInstanceId(vm.getId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId());
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
// save work context info (there are some duplications)
VmWorkDeleteAllVMSnapshots workInfo = new VmWorkDeleteAllVMSnapshots(callingUser.getId(), callingAccount.getId(), vm.getId(),