private Resource populateResource()

in ambari-server/src/main/java/org/apache/ambari/server/controller/jmx/JMXPropertyProvider.java [278:406]


  private Resource populateResource(Resource resource, Request request, Predicate predicate)
      throws SystemException {

    Set<String> ids = getRequestPropertyIds(request, predicate);
    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 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;
    }

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

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

    String hostName = getHost(resource, clusterName, componentName);
    if (hostName == null) {
      LOG.warn("Unable to get JMX metrics.  No host name for " + componentName);
      return resource;
    }
    
    String protocol = getJMXProtocol(clusterName, componentName);
    try {
      InputStream in = streamProvider.readFrom(getSpec(protocol, hostName, port));

      try {
        JMXMetricHolder metricHolder = objectReader.readValue(in);

        Map<String, Map<String, Object>> categories = new HashMap<String, Map<String, Object>>();

        for (Map<String, Object> bean : metricHolder.getBeans()) {
          String category = getCategory(bean);
          if (category != null) {
            categories.put(category, bean);
          }
        }

        for (String propertyId : ids) {
          Map<String, PropertyInfo> propertyInfoMap = getPropertyInfoMap(componentName, propertyId);

          String requestedPropertyId = propertyId;

          for (Map.Entry<String, PropertyInfo> entry : propertyInfoMap.entrySet()) {

            PropertyInfo propertyInfo = entry.getValue();
            propertyId = entry.getKey();

            if (propertyInfo.isPointInTime()) {

              String property = propertyInfo.getPropertyId();
              String category = "";

              
              List<String> keyList = new LinkedList<String>();
              
              int keyStartIndex = property.indexOf('[');
              if (-1 != keyStartIndex) {
                int keyEndIndex = property.indexOf(']', keyStartIndex);
                if (-1 != keyEndIndex && keyEndIndex > keyStartIndex) {
                  keyList.add(property.substring(keyStartIndex+1, keyEndIndex));
                }
              }
              
              if (!containsArguments(propertyId)) {
                int dotIndex = property.indexOf('.', property.indexOf('='));
                if (-1 != dotIndex) {
                  category = property.substring(0, dotIndex);
                  property = (-1 == keyStartIndex) ?
                      property.substring(dotIndex+1) :
                        property.substring(dotIndex+1, keyStartIndex);
                }
              } else {
                int firstKeyIndex = keyStartIndex > -1 ? keyStartIndex : property.length();
                int dotIndex = property.lastIndexOf('.', firstKeyIndex);

                if (dotIndex != -1) {
                  category = property.substring(0, dotIndex);
                  property = property.substring(dotIndex + 1, firstKeyIndex);
                }
              }

              if (containsArguments(propertyId)) {
                Pattern pattern = Pattern.compile(category);
                
                // find all jmx categories that match the regex
                for (String jmxCat : categories.keySet()) {
                  Matcher matcher = pattern.matcher(jmxCat);
                  if (matcher.matches()) {
                    String newPropertyId = propertyId;
                    for (int i = 0; i < matcher.groupCount(); i++) {
                      newPropertyId = substituteArgument(newPropertyId, "$" + (i + 1), matcher.group(i + 1));
                    }
                    // We need to do the final filtering here, after the argument substitution
                    if (isRequestedPropertyId(newPropertyId, requestedPropertyId, request)) {
                      setResourceValue(resource, categories, newPropertyId, jmxCat, property, keyList);
                    }
                  }
                }
              } else {
                setResourceValue(resource, categories, propertyId, category, property, keyList);
              }
            }
          }
        }
      } finally {
        in.close();
      }
    } catch (IOException e) {
      logException(e);
    }
    return resource;
  }