Esempio n. 1
0
  @Override
  public void doPolling(Guid cmdId, List<Guid> childCmdIds) {
    RemoveVmPoolCommand<? extends VmPoolParametersBase> command = getCommand(cmdId);

    boolean anyFailed = false;
    for (Guid childCmdId : childCmdIds) {
      CommandEntity entity = CommandCoordinatorUtil.getCommandEntity(childCmdId);
      switch (entity.getCommandStatus()) {
        case ENDED_WITH_FAILURE:
        case FAILED:
        case EXECUTION_FAILED:
        case UNKNOWN:
          anyFailed = true;
          break;

        default:
          break;
      }
    }

    if (anyFailed) {
      command.setCommandStatus(CommandStatus.FAILED);
    } else {
      VmPool pool = DbFacade.getInstance().getVmPoolDao().get(command.getVmPoolId());
      if (pool == null || pool.getRunningVmsCount() == 0) {
        command.setCommandStatus(CommandStatus.SUCCEEDED);
      }
    }
  }
 @Override
 public CommandEntity mapRow(ResultSet resultSet, int rowNum) throws SQLException {
   CommandEntity result = new CommandEntity();
   result.setUserId(Guid.createGuidFromString(resultSet.getString("user_id")));
   result.setId(Guid.createGuidFromString(resultSet.getString("command_id")));
   result.setJobId(Guid.createGuidFromString(resultSet.getString("job_id")));
   result.setStepId(Guid.createGuidFromString(resultSet.getString("step_id")));
   result.setCreatedAt(DbFacadeUtils.fromDate(resultSet.getTimestamp("created_at")));
   result.setCommandType(VdcActionType.forValue(resultSet.getInt("command_type")));
   result.setParentCommandId(
       Guid.createGuidFromString(resultSet.getString("parent_command_id")));
   result.setRootCommandId(
       Guid.createGuidFromString(resultSet.getString("root_command_id")));
   result.setCommandParameters(
       deserializeParameters(
           resultSet.getString("command_parameters"),
           resultSet.getString("command_params_class")));
   result.setReturnValue(
       deserializeReturnValue(
           resultSet.getString("return_value"), resultSet.getString("return_value_class")));
   result.setCommandStatus(getCommandStatus(resultSet.getString("status")));
   result.setExecuted(resultSet.getBoolean("executed"));
   result.setCallbackEnabled(resultSet.getBoolean("callback_enabled"));
   result.setCallbackNotified(resultSet.getBoolean("callback_notified"));
   return result;
 }
 @Override
 protected MapSqlParameterSource createFullParametersMapper(CommandEntity entity) {
   return getCustomMapSqlParameterSource()
       .addValue(
           "user_id", Guid.isNullOrEmpty(entity.getUserId()) ? Guid.Empty : entity.getUserId())
       .addValue("command_id", Guid.isNullOrEmpty(entity.getId()) ? Guid.Empty : entity.getId())
       .addValue("command_type", entity.getCommandType().getValue())
       .addValue("parent_command_id", entity.getParentCommandId())
       .addValue(
           "root_command_id",
           Guid.isNullOrEmpty(entity.getRootCommandId()) ? Guid.Empty : entity.getRootCommandId())
       .addValue("job_id", Guid.isNullOrEmpty(entity.getJobId()) ? Guid.Empty : entity.getJobId())
       .addValue(
           "step_id", Guid.isNullOrEmpty(entity.getStepId()) ? Guid.Empty : entity.getStepId())
       .addValue("command_parameters", serializeParameters(entity.getCommandParameters()))
       .addValue(
           "command_params_class",
           entity.getCommandParameters() == null
               ? null
               : entity.getCommandParameters().getClass().getName())
       .addValue("created_at", entity.getCreatedAt())
       .addValue("status", entity.getCommandStatus().toString())
       .addValue("executed", entity.isExecuted())
       .addValue("callback_enabled", entity.isCallbackEnabled())
       .addValue("return_value", serializeReturnValue(entity.getReturnValue()))
       .addValue(
           "return_value_class",
           entity.getReturnValue() == null ? null : entity.getReturnValue().getClass().getName());
 }
  public void proceedCommandExecution() {
    // Steps are executed such that:
    //  a) all logic before the command runs is idempotent
    //  b) the command is the last action in the step
    // This allows for recovery after a crash at any point during command execution.

    log.debug("Proceeding with execution of RemoveSnapshotSingleDiskLiveCommand");
    if (getParameters().getCommandStep() == null) {
      getParameters().setCommandStep(getInitialMergeStepForImage(getParameters().getImageId()));
      getParameters().setChildCommands(new HashMap<RemoveSnapshotSingleDiskLiveStep, Guid>());
    }

    // Upon recovery or after invoking a new child command, our map may be missing an entry
    syncChildCommandList();
    Guid currentChildId = getCurrentChildId();

    VdcReturnValueBase vdcReturnValue = null;
    if (currentChildId != null) {
      switch (CommandCoordinatorUtil.getCommandStatus(currentChildId)) {
        case ACTIVE:
        case NOT_STARTED:
          log.info(
              "Waiting on Live Merge command step '{}' to complete",
              getParameters().getCommandStep());
          return;

        case SUCCEEDED:
          CommandEntity cmdEntity = CommandCoordinatorUtil.getCommandEntity(currentChildId);
          if (cmdEntity.isCallbackEnabled() && !cmdEntity.isCallbackNotified()) {
            log.info(
                "Waiting on Live Merge command step '{}' to finalize",
                getParameters().getCommandStep());
            return;
          }

          vdcReturnValue = CommandCoordinatorUtil.getCommandReturnValue(currentChildId);
          if (vdcReturnValue != null && vdcReturnValue.getSucceeded()) {
            log.debug("Child command '{}' succeeded", getParameters().getCommandStep());
            getParameters().setCommandStep(getParameters().getNextCommandStep());
            break;
          } else {
            log.error(
                "Child command '{}' failed: {}",
                getParameters().getCommandStep(),
                (vdcReturnValue != null
                    ? vdcReturnValue.getExecuteFailedMessages()
                    : "null return value"));
            setCommandStatus(CommandStatus.FAILED);
            return;
          }

        case FAILED:
        case FAILED_RESTARTED:
          log.error("Failed child command status for step '{}'", getParameters().getCommandStep());
          setCommandStatus(CommandStatus.FAILED);
          return;

        case UNKNOWN:
          log.error("Unknown child command status for step '{}'", getParameters().getCommandStep());
          setCommandStatus(CommandStatus.FAILED);
          return;
      }
    }

    log.info("Executing Live Merge command step '{}'", getParameters().getCommandStep());

    Pair<VdcActionType, ? extends VdcActionParametersBase> nextCommand = null;
    switch (getParameters().getCommandStep()) {
      case EXTEND:
        nextCommand = new Pair<>(VdcActionType.MergeExtend, buildMergeParameters());
        getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.MERGE);
        break;
      case MERGE:
        nextCommand = new Pair<>(VdcActionType.Merge, buildMergeParameters());
        getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.MERGE_STATUS);
        break;
      case MERGE_STATUS:
        getParameters().setMergeCommandComplete(true);
        nextCommand = new Pair<>(VdcActionType.MergeStatus, buildMergeParameters());
        getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.DESTROY_IMAGE);
        break;
      case DESTROY_IMAGE:
        if (vdcReturnValue != null) {
          getParameters()
              .setMergeStatusReturnValue(
                  (MergeStatusReturnValue) vdcReturnValue.getActionReturnValue());
        } else if (getParameters().getMergeStatusReturnValue() == null) {
          // If the images were already merged, just add the orphaned image
          getParameters().setMergeStatusReturnValue(synthesizeMergeStatusReturnValue());
        }
        nextCommand = new Pair<>(VdcActionType.DestroyImage, buildDestroyImageParameters());
        getParameters().setNextCommandStep(RemoveSnapshotSingleDiskLiveStep.COMPLETE);
        break;
      case COMPLETE:
        getParameters().setDestroyImageCommandComplete(true);
        setCommandStatus(CommandStatus.SUCCEEDED);
        break;
    }

    persistCommand(getParameters().getParentCommand(), true);
    if (nextCommand != null) {
      CommandCoordinatorUtil.executeAsyncCommand(
          nextCommand.getFirst(), nextCommand.getSecond(), cloneContextAndDetachFromParent());
      // Add the child, but wait, it's a race!  child will start, task may spawn, get polled, and we
      // won't have the child id
    }
  }