private void processDisconnectAndTimeout(VMOperationListener listener, String resultMessage) { UserVmVO vm = listener.getVm(); VMOperationParam param = listener.getParam(); AsyncJobManager asyncMgr = getAsyncJobMgr(); EventVO event = new EventVO(); event.setUserId(param.getUserId()); event.setAccountId(vm.getAccountId()); event.setType(EventTypes.EVENT_VM_STOP); event.setParameters( "id=" + vm.getId() + "\nvmName=" + vm.getName() + "\nsoId=" + vm.getServiceOfferingId() + "\ntId=" + vm.getTemplateId() + "\ndcId=" + vm.getDataCenterId()); event.setDescription( "failed to stop VM instance : " + vm.getName() + " due to " + resultMessage); event.setLevel(EventVO.LEVEL_ERROR); asyncMgr.completeAsyncJob(getJob().getId(), AsyncJobResult.STATUS_FAILED, 0, resultMessage); asyncMgr.getExecutorContext().getEventDao().persist(event); asyncMgr.releaseSyncSource(this); }
private void buildAsyncListResponse(BaseListCmd command, Account account) { List<ResponseObject> responses = ((ListResponse) command.getResponseObject()).getResponses(); if (responses != null && responses.size() > 0) { List<? extends AsyncJob> jobs = null; // list all jobs for ROOT admin if (account.getType() == Account.ACCOUNT_TYPE_ADMIN) { jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), null); } else { jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), account.getId()); } if (jobs.size() == 0) { return; } Map<String, AsyncJob> objectJobMap = new HashMap<String, AsyncJob>(); for (AsyncJob job : jobs) { if (job.getInstanceId() == null) { continue; } String instanceUuid = ApiDBUtils.findJobInstanceUuid(job); if (instanceUuid != null) { objectJobMap.put(instanceUuid, job); } } for (ResponseObject response : responses) { if (response.getObjectId() != null && objectJobMap.containsKey(response.getObjectId())) { AsyncJob job = objectJobMap.get(response.getObjectId()); response.setJobId(job.getUuid()); response.setJobStatus(job.getStatus()); } } } }
private String queueCommand(BaseCmd cmdObj, Map<String, String> params) throws Exception { UserContext ctx = UserContext.current(); Long callerUserId = ctx.getCallerUserId(); Account caller = ctx.getCaller(); // Queue command based on Cmd super class: // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. // BaseAsyncCreateCmd: cmd params are processed and create() is called, then same workflow as // BaseAsyncCmd. // BaseAsyncCmd: cmd is processed and submitted as an AsyncJob, job related info is serialized // and returned. if (cmdObj instanceof BaseAsyncCmd) { Long objectId = null; String objectUuid = null; if (cmdObj instanceof BaseAsyncCreateCmd) { BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; _dispatcher.dispatchCreateCmd(createCmd, params); objectId = createCmd.getEntityId(); objectUuid = createCmd.getEntityUuid(); params.put("id", objectId.toString()); } else { ApiDispatcher.processParameters(cmdObj, params); } BaseAsyncCmd asyncCmd = (BaseAsyncCmd) cmdObj; if (callerUserId != null) { params.put("ctxUserId", callerUserId.toString()); } if (caller != null) { params.put("ctxAccountId", String.valueOf(caller.getId())); } long startEventId = ctx.getStartEventId(); asyncCmd.setStartEventId(startEventId); // save the scheduled event Long eventId = EventUtils.saveScheduledEvent( (callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), startEventId); if (startEventId == 0) { // There was no create event before, set current event id as start eventId startEventId = eventId; } params.put("ctxStartEventId", String.valueOf(startEventId)); ctx.setAccountId(asyncCmd.getEntityOwnerId()); Long instanceId = (objectId == null) ? asyncCmd.getInstanceId() : objectId; AsyncJobVO job = new AsyncJobVO( callerUserId, caller.getId(), cmdObj.getClass().getName(), ApiGsonHelper.getBuilder().create().toJson(params), instanceId, asyncCmd.getInstanceType()); long jobId = _asyncMgr.submitAsyncJob(job); if (jobId == 0L) { String errorMsg = "Unable to schedule async job for command " + job.getCmd(); s_logger.warn(errorMsg); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg); } if (objectId != null) { String objUuid = (objectUuid == null) ? objectId.toString() : objectUuid; return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objUuid); } SerializationContext.current().setUuidTranslation(true); return ApiResponseSerializer.toSerializedString( asyncCmd.getResponse(jobId), asyncCmd.getResponseType()); } else { _dispatcher.dispatch(cmdObj, params); // if the command is of the listXXXCommand, we will need to also return the // the job id and status if possible // For those listXXXCommand which we have already created DB views, this step is not needed // since async job is joined in their db views. if (cmdObj instanceof BaseListCmd && !(cmdObj instanceof ListVMsCmd) && !(cmdObj instanceof ListRoutersCmd) && !(cmdObj instanceof ListSecurityGroupsCmd) && !(cmdObj instanceof ListTagsCmd) && !(cmdObj instanceof ListEventsCmd) && !(cmdObj instanceof ListVMGroupsCmd) && !(cmdObj instanceof ListProjectsCmd) && !(cmdObj instanceof ListProjectAccountsCmd) && !(cmdObj instanceof ListProjectInvitationsCmd) && !(cmdObj instanceof ListHostsCmd) && !(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) && !(cmdObj instanceof ListStoragePoolsCmd)) { buildAsyncListResponse((BaseListCmd) cmdObj, caller); } SerializationContext.current().setUuidTranslation(true); return ApiResponseSerializer.toSerializedString( (ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); } }
public void processAnswer(VMOperationListener listener, long agentId, long seq, Answer answer) { UserVmVO vm = listener.getVm(); VMOperationParam param = listener.getParam(); AsyncJobManager asyncMgr = getAsyncJobMgr(); ManagementServer managementServer = asyncMgr.getExecutorContext().getManagementServer(); String params = "id=" + vm.getId() + "\nvmName=" + vm.getName() + "\nsoId=" + vm.getServiceOfferingId() + "\ntId=" + vm.getTemplateId() + "\ndcId=" + vm.getDataCenterId(); if (s_logger.isDebugEnabled()) s_logger.debug( "Execute asynchronize stop VM command: received answer, " + vm.getHostId() + "-" + seq); boolean stopped = false; if (answer != null && answer.getResult()) stopped = true; boolean jobStatusUpdated = false; try { if (stopped) { // completeStopCommand will log the event, if we log it here we will end up with duplicated // stop event asyncMgr .getExecutorContext() .getVmMgr() .completeStopCommand( param.getUserId(), vm, Event.OperationSucceeded, param.getEventId()); asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, VMExecutorHelper.composeResultObject( asyncMgr.getExecutorContext().getManagementServer(), vm, null)); jobStatusUpdated = true; } else { asyncMgr .getExecutorContext() .getItMgr() .stateTransitTo(vm, Event.OperationFailed, vm.getHostId()); asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, "Agent failed to stop VM"); jobStatusUpdated = true; EventUtils.saveEvent( param.getUserId(), param.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_STOP, "Failed to stop VM instance : " + vm.getName(), params, param.getEventId()); } } catch (Exception e) { s_logger.error("Unexpected exception " + e.getMessage(), e); if (!jobStatusUpdated) { if (stopped) { asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, VMExecutorHelper.composeResultObject( asyncMgr.getExecutorContext().getManagementServer(), vm, null)); } else { asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, "Agent failed to stop VM"); EventUtils.saveEvent( param.getUserId(), param.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_STOP, "Failed to stop VM instance : " + vm.getName(), params, param.getEventId()); } } } finally { asyncMgr.releaseSyncSource(this); } }
public boolean execute() { Gson gson = GsonHelper.getBuilder().create(); AsyncJobManager asyncMgr = getAsyncJobMgr(); AsyncJobVO job = getJob(); ManagementServer managementServer = asyncMgr.getExecutorContext().getManagementServer(); VMOperationParam param = gson.fromJson(job.getCmdInfo(), VMOperationParam.class); VmOp oper = param.getOperation(); VMInstanceVO vm; if (getSyncSource() == null) { asyncMgr.syncAsyncJobExecution(job.getId(), "SystemVm", param.getVmId()); return true; } else { try { switch (oper) { case Destroy: asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.UNSUPPORTED_ACTION_ERROR, "operation not allowed"); break; case Noop: asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, "noop operation"); break; case Start: vm = managementServer.startSystemVM(param.getVmId(), param.getEventId()); if (vm != null) asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, composeResultObject(managementServer, vm)); else asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, "operation failed"); break; case Stop: boolean result = managementServer.stopSystemVM(param.getVmId(), param.getEventId()); if (result) { vm = managementServer.findSystemVMById(param.getVmId()); asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, composeResultObject(managementServer, vm)); } else { asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, "operation failed"); } break; case Reboot: result = managementServer.rebootSystemVM(param.getVmId(), param.getEventId()); if (result) { vm = managementServer.findSystemVMById(param.getVmId()); asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_SUCCEEDED, 0, composeResultObject(managementServer, vm)); } else { asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, "operation failed"); } break; default: assert false : "Unknown vm operation"; } } catch (InternalErrorException e) { asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, e.getMessage()); } catch (Exception e) { s_logger.warn("Unable to start console vm " + param.getVmId() + ":" + e.getMessage(), e); asyncMgr.completeAsyncJob( getJob().getId(), AsyncJobResult.STATUS_FAILED, BaseCmd.INTERNAL_ERROR, e.getMessage()); } return true; } }
@DB protected void scheduleSnapshots() { String displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, _currentTimestamp); s_logger.debug("Snapshot scheduler.poll is being called at " + displayTime); List<SnapshotScheduleVO> snapshotsToBeExecuted = _snapshotScheduleDao.getSchedulesToExecute(_currentTimestamp); s_logger.debug( "Got " + snapshotsToBeExecuted.size() + " snapshots to be executed at " + displayTime); // This is done for recurring snapshots, which are executed by the system automatically // Hence set user id to that of system long userId = 1; for (SnapshotScheduleVO snapshotToBeExecuted : snapshotsToBeExecuted) { long policyId = snapshotToBeExecuted.getPolicyId(); long volumeId = snapshotToBeExecuted.getVolumeId(); VolumeVO volume = _volsDao.findById(volumeId); if (volume.getPoolId() == null) { // this volume is not attached continue; } if (_snapshotPolicyDao.findById(policyId) == null) { _snapshotScheduleDao.remove(snapshotToBeExecuted.getId()); } if (s_logger.isDebugEnabled()) { Date scheduledTimestamp = snapshotToBeExecuted.getScheduledTimestamp(); displayTime = DateUtil.displayDateInTimezone(DateUtil.GMT_TIMEZONE, scheduledTimestamp); s_logger.debug( "Scheduling 1 snapshot for volume " + volumeId + " for schedule id: " + snapshotToBeExecuted.getId() + " at " + displayTime); } long snapshotScheId = snapshotToBeExecuted.getId(); SnapshotScheduleVO tmpSnapshotScheduleVO = null; try { tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId); Long eventId = EventUtils.saveScheduledEvent( User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" + volumeId, 0); Map<String, String> params = new HashMap<String, String>(); params.put("volumeid", "" + volumeId); params.put("policyid", "" + policyId); params.put("ctxUserId", "1"); params.put("ctxAccountId", "1"); params.put("ctxStartEventId", String.valueOf(eventId)); CreateSnapshotCmd cmd = new CreateSnapshotCmd(); ApiDispatcher.getInstance().dispatchCreateCmd(cmd, params); params.put("id", "" + cmd.getEntityId()); params.put("ctxStartEventId", "1"); AsyncJobVO job = new AsyncJobVO(); job.setUserId(userId); // Just have SYSTEM own the job for now. Users won't be able to see this job, but // it's an internal job so probably not a huge deal. job.setAccountId(1L); job.setCmd(CreateSnapshotCmd.class.getName()); job.setInstanceId(cmd.getEntityId()); job.setCmdInfo(GsonHelper.getBuilder().create().toJson(params)); long jobId = _asyncMgr.submitAsyncJob(job); tmpSnapshotScheduleVO.setAsyncJobId(jobId); _snapshotScheduleDao.update(snapshotScheId, tmpSnapshotScheduleVO); } finally { if (tmpSnapshotScheduleVO != null) { _snapshotScheduleDao.releaseFromLockTable(snapshotScheId); } } } }