Example #1
0
  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());
    }
  }
Example #4
0
  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);
        }
      }
    }
  }