private List<RequestResourceFilter> parseRequestResourceFilter(Map<String, Object> resourceMap,
                                                           String clusterName) throws SystemException {

    List<RequestResourceFilter> resourceFilterList = new ArrayList<>();

    String serviceName = (String) resourceMap.get(SERVICE_ID);
    String componentName = (String) resourceMap.get(COMPONENT_ID);
    String hostsPredicate = (String) resourceMap.get(HOSTS_PREDICATE);
    Object hostListStr = resourceMap.get(HOSTS_ID);
    List<String> hostList = Collections.emptyList();
    if (hostListStr != null) {
      hostList = new ArrayList<>();
      for (String hostName : ((String) hostListStr).split(",")) {
        hostList.add(hostName.trim());
      }
      resourceFilterList.add(new RequestResourceFilter(serviceName, componentName, hostList));
    } else if (hostsPredicate != null) {
        // Parse the predicate as key=value and apply to the ResourceProvider predicate
      Predicate filterPredicate;
      try {
        filterPredicate = predicateCompiler.compile(hostsPredicate);
      } catch (InvalidQueryException e) {
        String msg = "Invalid predicate expression provided: " + hostsPredicate;
        LOG.warn(msg, e);
        throw new SystemException(msg, e);
      }

      Set<String> propertyIds = new HashSet<>();
      propertyIds.add(CLUSTER_NAME);
      propertyIds.add(SERVICE_NAME);
      propertyIds.add(COMPONENT_NAME);

      Request request = PropertyHelper.getReadRequest(propertyIds);
      
      try {
        ClusterController clusterController = ClusterControllerHelper.getClusterController();
        QueryResponse queryResponse = clusterController.getResources(
          Resource.Type.HostComponent, request, filterPredicate);
        Iterable<Resource> resourceIterable = clusterController.getIterable(
          Resource.Type.HostComponent, queryResponse, request,
          filterPredicate, null, null);
        
        // Allow request to span services / components using just the predicate
        Map<ServiceComponentTuple, List<String>> tupleListMap = new HashMap<>();
        for (Resource resource : resourceIterable) {
          String hostnameStr = (String) resource.getPropertyValue(HOST_NAME);
          if (hostnameStr != null) {
            String computedServiceName = (String) resource.getPropertyValue(SERVICE_NAME);
            String computedComponentName = (String) resource.getPropertyValue(COMPONENT_NAME);
            ServiceComponentTuple tuple = new ServiceComponentTuple(computedServiceName, computedComponentName);

            if (!tupleListMap.containsKey(tuple)) {
              hostList = new ArrayList<>();
              hostList.add(hostnameStr);
              tupleListMap.put(tuple, hostList);
            } else {
              tupleListMap.get(tuple).add(hostnameStr);
            }
          }
        }
        if (!tupleListMap.isEmpty()) {
          for (Map.Entry<ServiceComponentTuple, List<String>> entry : tupleListMap.entrySet()) {
            resourceFilterList.add(new RequestResourceFilter(
              entry.getKey().getServiceName(),
              entry.getKey().getComponentName(),
              entry.getValue()
            ));
          }
        }
      } catch (Exception e) {
        LOG.warn("Exception finding requested resources with serviceName = " + serviceName +
          ", componentName = " + componentName +
          ", hostPredicate" + " = " + hostsPredicate, e);
      }
    } else {
      resourceFilterList.add(new RequestResourceFilter(serviceName, componentName, hostList));
    }

    return resourceFilterList;
  }
Allow host component resource predicate to decide hosts to operate on.
@param resourceMap Properties
@param clusterName clusterName
@return Populated resource filter
@throws SystemException
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java