@Override
  public Set<Resource> getResources(Request request, Predicate predicate)
      throws SystemException, UnsupportedPropertyException, NoSuchResourceException,
          NoSuchParentResourceException {

    final Set<HostRequest> requests = new HashSet<HostRequest>();

    if (predicate == null) {
      requests.add(getRequest(null));
    } else {
      for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
        requests.add(getRequest(propertyMap));
      }
    }

    Set<HostResponse> responses =
        getResources(
            new Command<Set<HostResponse>>() {
              @Override
              public Set<HostResponse> invoke() throws AmbariException {
                return getHosts(requests);
              }
            });

    Set<String> requestedIds = getRequestPropertyIds(request, predicate);
    Set<Resource> resources = new HashSet<Resource>();

    for (HostResponse response : responses) {
      Resource resource = new ResourceImpl(Resource.Type.Host);

      // TODO : properly handle more than one cluster
      if (response.getClusterName() != null && !response.getClusterName().isEmpty()) {
        setResourceProperty(
            resource, HOST_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
      }
      setResourceProperty(resource, HOST_NAME_PROPERTY_ID, response.getHostname(), requestedIds);
      setResourceProperty(
          resource, HOST_PUBLIC_NAME_PROPERTY_ID, response.getPublicHostName(), requestedIds);
      setResourceProperty(resource, HOST_IP_PROPERTY_ID, response.getIpv4(), requestedIds);
      setResourceProperty(
          resource, HOST_TOTAL_MEM_PROPERTY_ID, response.getTotalMemBytes(), requestedIds);
      setResourceProperty(
          resource, HOST_CPU_COUNT_PROPERTY_ID, (long) response.getCpuCount(), requestedIds);
      setResourceProperty(
          resource,
          HOST_PHYSICAL_CPU_COUNT_PROPERTY_ID,
          (long) response.getPhCpuCount(),
          requestedIds);
      setResourceProperty(resource, HOST_OS_ARCH_PROPERTY_ID, response.getOsArch(), requestedIds);
      setResourceProperty(resource, HOST_OS_TYPE_PROPERTY_ID, response.getOsType(), requestedIds);

      String hostOsFamily = osFamily.find(response.getOsType());
      if (hostOsFamily == null) {
        LOG.error(
            "Can not find host OS family. For OS type = '{}' and host name = '{}'",
            response.getOsType(),
            response.getHostname());
      }
      setResourceProperty(resource, HOST_OS_FAMILY_PROPERTY_ID, hostOsFamily, requestedIds);

      setResourceProperty(
          resource, HOST_RACK_INFO_PROPERTY_ID, response.getRackInfo(), requestedIds);
      setResourceProperty(
          resource,
          HOST_LAST_HEARTBEAT_TIME_PROPERTY_ID,
          response.getLastHeartbeatTime(),
          requestedIds);
      setResourceProperty(
          resource, HOST_LAST_AGENT_ENV_PROPERTY_ID, response.getLastAgentEnv(), requestedIds);
      setResourceProperty(
          resource,
          HOST_LAST_REGISTRATION_TIME_PROPERTY_ID,
          response.getLastRegistrationTime(),
          requestedIds);
      setResourceProperty(
          resource, HOST_HOST_STATUS_PROPERTY_ID, response.getStatus(), requestedIds);
      setResourceProperty(
          resource,
          HOST_HOST_HEALTH_REPORT_PROPERTY_ID,
          response.getHealthStatus().getHealthReport(),
          requestedIds);
      setResourceProperty(
          resource, HOST_RECOVERY_REPORT_PROPERTY_ID, response.getRecoveryReport(), requestedIds);
      setResourceProperty(
          resource, HOST_RECOVERY_SUMMARY_PROPERTY_ID, response.getRecoverySummary(), requestedIds);
      setResourceProperty(
          resource, HOST_DISK_INFO_PROPERTY_ID, response.getDisksInfo(), requestedIds);
      setResourceProperty(resource, HOST_STATE_PROPERTY_ID, response.getHostState(), requestedIds);
      setResourceProperty(
          resource,
          HOST_DESIRED_CONFIGS_PROPERTY_ID,
          response.getDesiredHostConfigs(),
          requestedIds);

      // only when a cluster request
      if (null != response.getMaintenanceState()) {
        setResourceProperty(
            resource,
            HOST_MAINTENANCE_STATE_PROPERTY_ID,
            response.getMaintenanceState(),
            requestedIds);
      }

      resources.add(resource);
    }
    return resources;
  }