@Override
  protected Resource populateResource(Resource resource,
                                      Request request, Predicate predicate, Ticket ticket)
      throws SystemException {

    // Remove request properties that request temporal information
    Set<String> ids = getRequestPropertyIds(request, predicate);
    Set<String> temporalIds = new HashSet<>();
    String resourceComponentName = (String) resource.getPropertyValue(componentNamePropertyId);

    if (!componentName.equals(resourceComponentName)) {
      return resource;
    }

    for (String id : ids) {
      if (request.getTemporalInfo(id) != null) {
        temporalIds.add(id);
      }
    }
    ids.removeAll(temporalIds);

    if (ids.isEmpty()) {
      // no properties requested
      return resource;
    }

    // Don't attempt to get REST properties if the resource is in
    // an unhealthy state
    if (statePropertyId != null) {
      String state = (String) resource.getPropertyValue(statePropertyId);
      if (state != null && !healthyStates.contains(state)) {
        return resource;
      }
    }

    Map<String, PropertyInfo> propertyInfos =
        getComponentMetrics().get(StackDefinedPropertyProvider.WRAPPED_METRICS_KEY);
    if (propertyInfos == null) {
      // If there are no metrics defined for the given component then there is nothing to do.
      return resource;
    }
    String protocol = null;
    String port = "-1";
    String hostname = null;
    try {
      String clusterName = (String) resource.getPropertyValue(clusterNamePropertyId);
      Cluster cluster = clusters.getCluster(clusterName);
      hostname = getHost(resource, clusterName, resourceComponentName);
      if (hostname == null) {
        String msg = String.format("Unable to get component REST metrics. " +
            "No host name for %s.", resourceComponentName);
        LOG.warn(msg);
        return resource;
      }
      protocol = resolveProtocol(cluster, hostname);
      port = resolvePort(cluster, hostname, resourceComponentName, metricsProperties, protocol);
    } catch (Exception e) {
      rethrowSystemException(e);
    }

    Set<String> resultIds = new HashSet<>();
    for (String id : ids){
      for (String metricId : propertyInfos.keySet()){
        if (metricId.startsWith(id)){
          resultIds.add(metricId);
        }
      }
    }

    // Extract set of URLs for metrics
    HashMap<String, Set<String>> urls = extractPropertyURLs(resultIds, propertyInfos);

    for (String url : urls.keySet()) {
      String spec = getSpec(protocol, hostname, port, url);

      // always submit a request to cache the latest data
      metricsRetrievalService.submitRequest(MetricSourceType.REST, streamProvider, spec);

      // check to see if there is a cached value and use it if there is
      Map<String, String> jsonMap = metricsRetrievalService.getCachedRESTMetric(spec);
      if (null == jsonMap) {
        return resource;
      }

      if (!ticket.isValid()) {
        return resource;
      }

      try {
        extractValuesFromJSON(jsonMap, urls.get(url), resource, propertyInfos);
      } catch (AmbariException ambariException) {
        AmbariException detailedException = new AmbariException(String.format(
            "Unable to get REST metrics from the for %s at %s", resourceComponentName, spec),
            ambariException);

        logException(detailedException);
      }
    }
    return resource;
  }
Populate a resource by obtaining the requested REST properties.

@param resource  the resource to be populated
@param request   the request
@param predicate the predicate
@return the populated resource; null if the resource should NOT be
        part of the result set for the given predicate
ambari-server/src/main/java/org/apache/ambari/server/controller/metrics/RestMetricsPropertyProvider.java