@Transactional
  RequestStageContainer handle(Cluster cluster,
                               KerberosDetails kerberosDetails,
                               Map<String, ? extends Collection<String>> serviceComponentFilter,
                               Set<String> hostFilter, Collection<String> identityFilter,
                               Set<String> hostsToForceKerberosOperations,
                               RequestStageContainer requestStageContainer,
                               final Handler handler)
    throws AmbariException, KerberosOperationException {

    final KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false);

    List<ServiceComponentHost> schToProcess = getServiceComponentHostsToProcess(
      cluster,
      kerberosDescriptor,
      serviceComponentFilter,
      hostFilter);

    // While iterating over all the ServiceComponentHosts find hosts that have KERBEROS_CLIENT
    // components in the INSTALLED state and add them to the hostsWithValidKerberosClient Set.
    // This is needed to help determine which hosts to perform actions for and create tasks for.
    Set<String> hostsWithValidKerberosClient = null;

    // Create a temporary directory to store metadata needed to complete this task.  Information
    // such as which principals and keytabs files to create as well as what configurations need
    // to be update are stored in data files in this directory. Any keytab files are stored in
    // this directory until they are distributed to their appropriate hosts.
    File dataDirectory = null;

    // If there are ServiceComponentHosts to process...
    if (!schToProcess.isEmpty()) {

      validateKDCCredentials(kerberosDetails, cluster);

      // Create a temporary directory to store metadata needed to complete this task.  Information
      // such as which principals and keytabs files to create as well as what configurations need
      // to be update are stored in data files in this directory. Any keytab files are stored in
      // this directory until they are distributed to their appropriate hosts.
      dataDirectory = createTemporaryDirectory();

      hostsWithValidKerberosClient = getHostsWithValidKerberosClient(cluster);

      // Ensure that that hosts that should be assumed to be in the correct state when needed are
      // in the hostsWithValidKerberosClient collection.
      if (hostsToForceKerberosOperations != null) {
        hostsWithValidKerberosClient.addAll(hostsToForceKerberosOperations);
      }
    }

    // Always set up the necessary stages to perform the tasks needed to complete the operation.
    // Some stages may be no-ops, this is expected.
    // Gather data needed to create stages and tasks...
    Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
    String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);

    @Experimental(feature = ExperimentalFeature.MULTI_SERVICE, comment = "The cluster stack id is deprecated")
    Map<String, String> hostParams = customCommandExecutionHelper.createDefaultHostParams(cluster, cluster.getDesiredStackVersion());
    String hostParamsJson = StageUtils.getGson().toJson(hostParams);
    String ambariServerHostname = StageUtils.getHostName();
    ServiceComponentHostServerActionEvent event = new ServiceComponentHostServerActionEvent(
      RootComponent.AMBARI_SERVER.name(),
      ambariServerHostname, // TODO: Choose a random hostname from the cluster. All tasks for the AMBARI_SERVER service will be executed on this Ambari server
      System.currentTimeMillis());
    RoleCommandOrder roleCommandOrder = ambariManagementController.getRoleCommandOrder(cluster);

    // If a RequestStageContainer does not already exist, create a new one...
    if (requestStageContainer == null) {
      requestStageContainer = new RequestStageContainer(
        actionManager.getNextRequestId(),
        null,
        requestFactory,
        actionManager);
    }

    // Use the handler implementation to setup the relevant stages.
    handler.createStages(cluster, clusterHostInfoJson,
      hostParamsJson, event, roleCommandOrder, kerberosDetails, dataDirectory,
      requestStageContainer, schToProcess, serviceComponentFilter, hostFilter, identityFilter,
      hostsWithValidKerberosClient);

    // Add the finalize stage...
    handler.addFinalizeOperationStage(cluster, clusterHostInfoJson, hostParamsJson, event,
      dataDirectory, roleCommandOrder, requestStageContainer, kerberosDetails);

    return requestStageContainer;
  }
Performs operations needed to process Kerberos related tasks on the relevant cluster.
<p/>
Iterates through the components installed on the relevant cluster to determine if work
need to be done.  Calls into the Handler implementation to provide guidance and set up stages
to perform the work needed to complete the relative action.

@param cluster                        the relevant Cluster
@param kerberosDetails                a KerberosDetails containing information about relevant Kerberos configuration
@param serviceComponentFilter         a Map of service names to component names indicating the relevant
                                      set of services and components - if null, no filter is relevant;
                                      if empty, the filter indicates no relevant services or components
@param hostFilter                     a set of hostname indicating the set of hosts to process -
                                      if null, no filter is relevant; if empty, the filter indicates no
                                      relevant hosts
@param identityFilter                 a Collection of identity names indicating the relevant identities -
                                      if null, no filter is relevant; if empty, the filter indicates no
                                      relevant identities
@param hostsToForceKerberosOperations a set of host names on which it is expected that the
                                      Kerberos client is or will be in the INSTALLED state by
                                      the time the operations targeted for them are to be
                                      executed - if empty or null, this no hosts will be
                                      "forced"
@param requestStageContainer          a RequestStageContainer to place generated stages, if needed -
                                      if null a new RequestStageContainer will be created.
@param handler                        a Handler to use to provide guidance and set up stages
                                      to perform the work needed to complete the relative action
@return the updated or a new RequestStageContainer containing the stages that need to be
executed to complete this task; or null if no stages need to be executed.
@throws AmbariException
@throws KerberosInvalidConfigurationException if an issue occurs trying to get the
                                              Kerberos-specific configuration details
ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java