@Override
  public DeleteStatusMetaData deleteHostComponents(
      Set<ServiceComponentHostRequest> requests) throws AmbariException, AuthorizationException {

    Set<ServiceComponentHostRequest> expanded = new HashSet<>();

    // if any request are for the whole host, they need to be expanded
    for (ServiceComponentHostRequest request : requests) {
      if (null == request.getComponentName()) {
        if (null == request.getClusterName() || request.getClusterName().isEmpty() ||
            null == request.getHostname() || request.getHostname().isEmpty()) {
          throw new IllegalArgumentException("Cluster name and hostname must be specified.");
        }
        Cluster cluster = clusters.getCluster(request.getClusterName());

        if (!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, cluster.getResourceId(),
            EnumSet.of(RoleAuthorization.SERVICE_ADD_DELETE_SERVICES,RoleAuthorization.HOST_ADD_DELETE_COMPONENTS))) {
          throw new AuthorizationException("The authenticated user is not authorized to delete service components from hosts");
        }

        for (ServiceComponentHost sch : cluster.getServiceComponentHosts(request.getHostname())) {
          ServiceComponentHostRequest schr = new ServiceComponentHostRequest(request.getClusterName(),
              sch.getServiceName(), sch.getServiceComponentName(), sch.getHostName(), null);
          expanded.add(schr);
        }
      }
      else {
        expanded.add(request);
      }
    }

    Map<ServiceComponent, Set<ServiceComponentHost>> safeToRemoveSCHs = new HashMap<>();
    DeleteHostComponentStatusMetaData deleteMetaData = new DeleteHostComponentStatusMetaData();

    for (ServiceComponentHostRequest request : expanded) {

      validateServiceComponentHostRequest(request);

      Cluster cluster = clusters.getCluster(request.getClusterName());

      if (StringUtils.isEmpty(request.getServiceName())) {
        request.setServiceName(findServiceName(cluster, request.getComponentName()));
      }

      LOG.info("Received a hostComponent DELETE request"
        + ", clusterName=" + request.getClusterName()
        + ", serviceName=" + request.getServiceName()
        + ", componentName=" + request.getComponentName()
        + ", hostname=" + request.getHostname()
        + ", request=" + request);

      Service service = cluster.getService(request.getServiceName());
      ServiceComponent component = service.getServiceComponent(request.getComponentName());
      ServiceComponentHost componentHost = component.getServiceComponentHost(request.getHostname());

      setRestartRequiredServices(service, request.getComponentName());
      try {
        checkIfHostComponentsInDeleteFriendlyState(request, cluster);
        if (!safeToRemoveSCHs.containsKey(component)) {
          safeToRemoveSCHs.put(component, new HashSet<>());
        }
        safeToRemoveSCHs.get(component).add(componentHost);
      } catch (Exception ex) {
        deleteMetaData.addException(request.getHostname() + "/" + request.getComponentName(), ex);
      }
    }

    //keep 2 maps for simpler maintenance
    Map<String, Map<String, String>> clusterServiceMasterForDecommissionMap = new HashMap<>();
    Map<String, Map<String, Set<String>>> clusterMasterSlaveHostsMap = new HashMap<>();
    for (Entry<ServiceComponent, Set<ServiceComponentHost>> entry : safeToRemoveSCHs.entrySet()) {
      for (ServiceComponentHost componentHost : entry.getValue()) {
        try {
          //actually delete the component
          //TODO update metadata processing according to AMBARI-21587
          entry.getKey().deleteServiceComponentHosts(componentHost.getHostName(), deleteMetaData);

          //create cluster-master-service map to update all include/exclude files in one action
          String componentName = componentHost.getServiceComponentName();
          if (masterToSlaveMappingForDecom.containsValue(componentName)) {
            String masterComponentName = null;
            for (Entry<String, String> entrySet : masterToSlaveMappingForDecom.entrySet()) {
              if (entrySet.getValue().equals(componentName)) {
                masterComponentName = entrySet.getKey();
              }
            }
            if (clusterServiceMasterForDecommissionMap.containsKey(componentHost.getClusterName())) {
              clusterServiceMasterForDecommissionMap.get(componentHost.getClusterName()).put(componentHost.getServiceName(), masterComponentName);
              Map<String, Set<String>> masterSlaveMap  = clusterMasterSlaveHostsMap.get(componentHost.getClusterName());
              masterSlaveMap.putIfAbsent(masterComponentName, new HashSet<>());
              masterSlaveMap.get(masterComponentName).add(componentHost.getHostName());
            } else {
              Map<String, String> serviceMasterMap = new HashMap<>();
              serviceMasterMap.put(componentHost.getServiceName(), masterComponentName);
              clusterServiceMasterForDecommissionMap.put(componentHost.getClusterName(), serviceMasterMap);

              Map<String, Set<String>> masterSlaveHostsMap = new HashMap<>();
              masterSlaveHostsMap.put(masterComponentName, new HashSet<>(Collections.singletonList(componentHost.getHostName())));
              clusterMasterSlaveHostsMap.put(componentHost.getClusterName(), masterSlaveHostsMap);
            }
          }
        } catch (Exception ex) {
          deleteMetaData.addException(componentHost.getHostName() + "/" + componentHost.getServiceComponentName(), ex);
        }
      }
    }

    for (String cluster : clusterServiceMasterForDecommissionMap.keySet()) {
      createAndExecuteRefreshIncludeExcludeFilesActionForMasters(clusterServiceMasterForDecommissionMap.get(cluster), clusterMasterSlaveHostsMap.get(cluster), cluster, true);
    }

    //Do not break behavior for existing clients where delete request contains only 1 host component.
    //Response for these requests will have empty body with appropriate error code.
    if (deleteMetaData.getDeletedKeys().size() + deleteMetaData.getExceptionForKeys().size() == 1) {
      if (deleteMetaData.getDeletedKeys().size() == 1) {
        STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
        return null;
      }
      Exception ex = deleteMetaData.getExceptionForKeys().values().iterator().next();
      if (ex instanceof AmbariException) {
        throw (AmbariException)ex;
      } else {
        throw new AmbariException(ex.getMessage(), ex);
      }
    }

    // set restartRequired flag for  monitoring services
    if (!safeToRemoveSCHs.isEmpty()) {
      setMonitoringServicesRestartRequired(requests);
    }
    STOMPComponentsDeleteHandler.processDeleteByMetaData(deleteMetaData);
    return deleteMetaData;
  }
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