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;
}