@Transactional
  void updateServiceStates(
      Cluster cluster,
      Map<State, List<Service>> changedServices,
      Map<State, List<ServiceComponent>> changedComps,
      Map<String, Map<State, List<ServiceComponentHost>>> changedScHosts,
      Collection<ServiceComponentHost> ignoredScHosts
  ) {
    if (changedServices != null) {
      for (Entry<State, List<Service>> entry : changedServices.entrySet()) {
        State newState = entry.getKey();
        for (Service s : entry.getValue()) {
          if (s.isClientOnlyService()
              && newState == State.STARTED) {
            continue;
          }
          s.setDesiredState(newState);
        }
      }
    }

    if (changedComps != null) {
      for (Entry<State, List<ServiceComponent>> entry :
          changedComps.entrySet()) {
        State newState = entry.getKey();
        for (ServiceComponent sc : entry.getValue()) {
          sc.setDesiredState(newState);
        }
      }
    }

    //keep 2 maps for simpler maintenance
    Map<String, String> serviceMasterForDecommissionMap = new HashMap<>();
    Map<String, Set<String>> masterSlaveHostsMap = new HashMap<>();
    for (Map<State, List<ServiceComponentHost>> stateScHostMap :
        changedScHosts.values()) {
      for (Entry<State, List<ServiceComponentHost>> entry :
          stateScHostMap.entrySet()) {
        State newState = entry.getKey();
        for (ServiceComponentHost sch : entry.getValue()) {
          String componentName = sch.getServiceComponentName();
          //Create map for include/exclude files refresh
          if (masterToSlaveMappingForDecom.containsValue(componentName) &&
            sch.getState() == State.INIT && newState == State.INSTALLED) {
            String serviceName = sch.getServiceName();
            String masterComponentName = null;
            for (Entry<String, String> entrySet : masterToSlaveMappingForDecom.entrySet()) {
              if (entrySet.getValue().equals(componentName)) {
                masterComponentName = entrySet.getKey();
              }
            }
            try {
              //Filter services whose masters are not started
              if (isServiceComponentStartedOnAnyHost(cluster, serviceName, masterComponentName)) {
                serviceMasterForDecommissionMap.put(serviceName, masterComponentName);
                masterSlaveHostsMap.putIfAbsent(masterComponentName, new HashSet<>());
                masterSlaveHostsMap.get(masterComponentName).add(sch.getHostName());
              } else {
                LOG.info(String.format("Not adding %s service from include/exclude files refresh map because it's master is not started", serviceName));
              }
            } catch (AmbariException e) {
              LOG.error("Exception during INIT masters cleanup : ", e);
            }
          }

          //actually set the new state
          sch.setDesiredState(newState);
        }
      }
    }

    try {
      createAndExecuteRefreshIncludeExcludeFilesActionForMasters(serviceMasterForDecommissionMap, masterSlaveHostsMap, cluster.getClusterName(), false);
    } catch (AmbariException e) {
      LOG.error("Exception during refresh include exclude files action : ", e);
    }

    if (ignoredScHosts != null) {
      for (ServiceComponentHost scHost : ignoredScHosts) {
        scHost.setDesiredState(scHost.getState());
      }
    }
  }
Computes os-dependent packages for service/host. Does not take into
account package dependencies for ANY_OS. Instead of this method
you should use getPackagesForServiceHost()
because it takes into account both os-dependent and os-independent lists
of packages for service.
@param hostParams may be modified (appended SERVICE_REPO_INFO)
@return a list of os-dependent packages for host
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java