private boolean makeServerSideStage(UpgradeGroupHolder group, UpgradeContext context,
      StackId stackId, RequestStageContainer request,
      UpgradeItemEntity entity, ServerSideActionTask task, ConfigUpgradePack configUpgradePack)
      throws AmbariException {

    Cluster cluster = context.getCluster();
    UpgradePack upgradePack = context.getUpgradePack();

    Map<String, String> commandParams = getNewParameterMap(request, context);
    commandParams.put(UpgradeContext.COMMAND_PARAM_UPGRADE_PACK, upgradePack.getName());

    // Notice that this does not apply any params because the input does not specify a stage.
    // All of the other actions do use additional params.

    String itemDetail = entity.getText();
    String stageText = StringUtils.abbreviate(entity.getText(), 255);

    boolean process = true;

    switch (task.getType()) {
      case SERVER_ACTION:
      case MANUAL: {
        ServerSideActionTask serverTask = task;

        if (null != serverTask.summary) {
          stageText = serverTask.summary;
        }

        if (task.getType() == Task.Type.MANUAL) {
          ManualTask mt = (ManualTask) task;

          if (StringUtils.isNotBlank(mt.structuredOut)) {
            commandParams.put(UpgradeContext.COMMAND_PARAM_STRUCT_OUT, mt.structuredOut);
          }
        }

        if (!serverTask.messages.isEmpty()) {
          JsonArray messageArray = new JsonArray();
          for (String message : serverTask.messages) {
            JsonObject messageObj = new JsonObject();
            messageObj.addProperty("message", message);
            messageArray.add(messageObj);
          }
          itemDetail = messageArray.toString();

          entity.setText(itemDetail);

          //To be used later on by the Stage...
          itemDetail = StringUtils.join(serverTask.messages, " ");
        }
        break;
      }
      case CONFIGURE: {
        ConfigureTask ct = (ConfigureTask) task;

        // !!! would prefer to do this in the sequence generator, but there's too many
        // places to miss
        if (context.getOrchestrationType().isRevertable() && !ct.supportsPatch) {
          process = false;
        }

        Map<String, String> configurationChanges =
                ct.getConfigurationChanges(cluster, configUpgradePack);

        // add all configuration changes to the command params
        commandParams.putAll(configurationChanges);

        // extract the config type to build the summary
        String configType = configurationChanges.get(ConfigureTask.PARAMETER_CONFIG_TYPE);
        if (null != configType) {
          itemDetail = String.format("Updating configuration %s", configType);
        } else {
          itemDetail = "Skipping Configuration Task "
              + StringUtils.defaultString(ct.id, "(missing id)");
        }

        entity.setText(itemDetail);

        String configureTaskSummary = ct.getSummary(configUpgradePack);
        if (null != configureTaskSummary) {
          stageText = configureTaskSummary;
        } else {
          stageText = itemDetail;
        }

        break;
      }
      case CREATE_AND_CONFIGURE: {
        CreateAndConfigureTask ct = (CreateAndConfigureTask) task;

        // !!! would prefer to do this in the sequence generator, but there's too many
        // places to miss
        if (context.getOrchestrationType().isRevertable() && !ct.supportsPatch) {
          process = false;
        }

        Map<String, String> configurationChanges =
                ct.getConfigurationChanges(cluster, configUpgradePack);

        // add all configuration changes to the command params
        commandParams.putAll(configurationChanges);

        // extract the config type to build the summary
        String configType = configurationChanges.get(CreateAndConfigureTask.PARAMETER_CONFIG_TYPE);
        if (null != configType) {
          itemDetail = String.format("Updating configuration %s", configType);
        } else {
          itemDetail = "Skipping Configuration Task "
              + StringUtils.defaultString(ct.id, "(missing id)");
        }

        entity.setText(itemDetail);

        String configureTaskSummary = ct.getSummary(configUpgradePack);
        if (null != configureTaskSummary) {
          stageText = configureTaskSummary;
        } else {
          stageText = itemDetail;
        }

        break;
      }
      case ADD_COMPONENT: {
        AddComponentTask addComponentTask = (AddComponentTask) task;
        String serializedTask = addComponentTask.toJson();
        commandParams.put(AddComponentTask.PARAMETER_SERIALIZED_ADD_COMPONENT_TASK, serializedTask);
        break;
      }
      default:
        break;
    }

    if (!process) {
      return false;
    }

    ActionExecutionContext actionContext = buildActionExecutionContext(cluster, context,
        Role.AMBARI_SERVER_ACTION.toString(), stackId, Collections.emptyList(),
        commandParams, group.allowRetry, -1);

    ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
        cluster, context.getRepositoryVersion().getStackId(), null);

    Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
        cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getCommandParamsForStage(),
      jsons.getHostParamsForStage());

    stage.setSkippable(group.skippable);
    stage.setAutoSkipFailureSupported(group.supportsAutoSkipOnFailure);

    long stageId = request.getLastStageId() + 1;
    if (0L == stageId) {
      stageId = 1L;
    }

    stage.setStageId(stageId);
    entity.setStageId(Long.valueOf(stageId));

    Map<String, String> taskParameters = task.getParameters();
    commandParams.putAll(taskParameters);

    // attempt to get a classloader from the stack (for plugins), and if there
    // is not one, then default to Ambari's classloader
    StackInfo stackInfo = s_metaProvider.get().getStack(stackId);
    ClassLoader classLoader = stackInfo.getLibraryClassLoader();
    if (null == classLoader) {
      classLoader = ClasspathScannerUtils.class.getClassLoader();
    }

    // try to figure out what the class is so it can be scheduled correctly
    final String classToSchedule;
    String taskClass = task.getImplementationClass();
    try {
      Class<?> clazz = classLoader.loadClass(taskClass);
      if (UpgradeAction.class.isAssignableFrom(clazz)) {
        // upgrade actions are scheduled using our own server action, passing
        // the name of the upgrade action in via the command params
        classToSchedule = PluginUpgradeServerAction.class.getName();
        commandParams.put(ServerAction.WRAPPED_CLASS_NAME, taskClass);
      } else if (ServerAction.class.isAssignableFrom(clazz)) {
        classToSchedule = task.getImplementationClass();
      } else {
        throw new AmbariException("The class " + taskClass
            + " was not able to be scheduled during the upgrade because it is not compatible");
      }
    } catch (ClassNotFoundException cnfe) {
      LOG.error("Unable to load {} specified in the upgrade pack", taskClass, cnfe);
      throw new AmbariException("The class " + taskClass
          + " was not able to be scheduled during the upgrade because it was not found");
    }

    stage.addServerActionCommand(classToSchedule,
        getManagementController().getAuthName(), Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE,
        cluster.getClusterName(),
        new ServiceComponentHostServerActionEvent(null, System.currentTimeMillis()), commandParams,
        itemDetail, null, s_configuration.getDefaultServerTaskTimeout(), group.allowRetry,
        context.isComponentFailureAutoSkipped());

    request.addStages(Collections.singletonList(stage));

    return true;
  }
Creates a stage consisting of server side actions. If the server action is
a {@link ServerAction} instance, then it will schedule it after verifying
that the class can be loaded. If the action is an {@link UpgradeAction},
then it will be scheduled as a {@link PluginUpgradeServerAction}.

@param group
         the upgrade group
@param context
         the upgrade context containing all of the information about the
         upgrade.
@param stackId
         the ID of the stack that this stage is being created for. In some
         upgrades, the stack ID changes part way through, such as during an
         express upgrade.
@param request
         the request being constructed, but not yet persisted.
@param entity
         the upgrade item entity associated with the stage.
@param task
         the task from the upgrade pack XML which this command is being
         built for.
@param configUpgradePack
         the configuration changes for the upgrade.
@return {@code true} if the stage creation was successful, or {@code false}
        if no processing was performed.
@throws AmbariException
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java