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

    Set<String> ids = getRequestPropertyIds(request, predicate);
    Set<String> unsupportedIds = new HashSet<>();
    String componentName = (String) resource.getPropertyValue(componentNamePropertyId);

    if (getComponentMetrics().get(componentName) == null) {
      // If there are no metrics defined for the given component then there is nothing to do.
      return resource;
    }

    for (String id : ids) {
      if (request.getTemporalInfo(id) != null) {
        unsupportedIds.add(id);
      }
      if (!isSupportedPropertyId(componentName, id)) {
        unsupportedIds.add(id);
      }
    }

    ids.removeAll(unsupportedIds);

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

    // Don't attempt to get the JMX 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;
      }
    }

    String clusterName = (String) resource.getPropertyValue(clusterNamePropertyId);

    String protocol = jmxHostProvider.getJMXProtocol(clusterName, componentName);

    boolean httpsEnabled = false;

    if (protocol.equals("https")){
      httpsEnabled = true;
    }

    Set<String> hostNames = getHosts(resource, clusterName, componentName);
    if (hostNames == null || hostNames.isEmpty()) {
      LOG.warn("Unable to get JMX metrics.  No host name for " + componentName);
      return resource;
    }

    String spec = null;
    for (String hostName : hostNames) {
      try {
        String port = getPort(clusterName, componentName, hostName, httpsEnabled);
        String publicHostName = jmxHostProvider.getPublicHostName(clusterName, hostName);

        if (port == null) {
          LOG.warn("Unable to get JMX metrics.  No port value for " + componentName);
          return resource;
        }

        // build the URL
        String jmxUrl = getSpec(protocol, hostName, port, "/jmx");

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

        // check to see if there is a cached value and use it if there is
        JMXMetricHolder jmxMetricHolder = metricsRetrievalService.getCachedJMXMetric(jmxUrl);

        if( jmxMetricHolder == null && !hostName.equalsIgnoreCase(publicHostName)) {
          // build the URL using public host name
          String publicJmxUrl = getSpec(protocol, publicHostName, port, "/jmx");

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

          // check to see if there is a cached value and use it if there is
          jmxMetricHolder = metricsRetrievalService.getCachedJMXMetric(publicJmxUrl);
        }

        // if the ticket becomes invalid (timeout) then bail out
        if (!ticket.isValid()) {
          return resource;
        }

        if (null != jmxMetricHolder) {
          getHadoopMetricValue(jmxMetricHolder, ids, resource, request, ticket);
        }

        if (AD_HOC_PROPERTIES.containsKey(componentName)) {
          for (String propertyId : ids) {
            for (String adHocId : AD_HOC_PROPERTIES.get(componentName).keySet()) {
              String queryURL = null;
              // if all metrics from "metrics/dfs/FSNamesystem" were requested, retrieves HAState.
              if (adHocId.equals(propertyId) || adHocId.startsWith(propertyId + '/')) {
                queryURL = AD_HOC_PROPERTIES.get(componentName).get(adHocId);
              }
              if (queryURL != null) {
                String adHocUrl = getSpec(protocol, hostName, port, queryURL);
                metricsRetrievalService.submitRequest(MetricSourceType.JMX, streamProvider, adHocUrl);
                JMXMetricHolder adHocJMXMetricHolder = metricsRetrievalService.getCachedJMXMetric(adHocUrl);

                if( adHocJMXMetricHolder == null && !hostName.equalsIgnoreCase(publicHostName)) {
                  // build the adhoc URL using public host name
                  String publicAdHocUrl = getSpec(protocol, publicHostName, port, queryURL);

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

                  // check to see if there is a cached value and use it if there is
                  adHocJMXMetricHolder = metricsRetrievalService.getCachedJMXMetric(publicAdHocUrl);
                }

                // if the ticket becomes invalid (timeout) then bail out
                if (!ticket.isValid()) {
                  return resource;
                }
                if (null != adHocJMXMetricHolder) {
                  getHadoopMetricValue(adHocJMXMetricHolder, Collections.singleton(propertyId), resource, request, ticket);
                }
              }
            }
          }
        }
      } catch (IOException e) {
        AmbariException detailedException = new AmbariException(String.format(
            "Unable to get JMX metrics from the host %s for the component %s. Spec: %s", hostName,
            componentName, spec), e);
        logException(detailedException);
      }
    }

    return resource;
  }
Populate a resource by obtaining the requested JMX properties.

@param resource  the resource to be populated
@param request   the request
@param predicate the predicate
@param ticket    a valid ticket

@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/jmx/JMXPropertyProvider.java