You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/08/12 17:47:08 UTC
svn commit: r1513172 - in
/sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl:
AttributeResource.java JMXResourceProvider.java MBeanResource.java
Author: cziegeler
Date: Mon Aug 12 15:47:07 2013
New Revision: 1513172
URL: http://svn.apache.org/r1513172
Log:
SLING-2999 : JMX Resource Provider
Modified:
sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java
sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java
sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java
Modified: sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java?rev=1513172&r1=1513171&r2=1513172&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java (original)
+++ sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java Mon Aug 12 15:47:07 2013
@@ -110,9 +110,9 @@ public class AttributeResource extends A
}
if ( info.getDescription() != null ) {
- result.put("description", info.getDescription());
+ result.put("mbean:description", info.getDescription());
}
- result.put("type", info.getType());
+ result.put("mbean:type", info.getType());
try {
final Object value = server.getAttribute(this.on, info.getName());
@@ -124,18 +124,18 @@ public class AttributeResource extends A
final Object o = Array.get(value, i);
values[i] = convert(o);
}
- result.put("value", values);
+ result.put("mbean:value", values);
} else if (value instanceof TabularData) {
// TODO
} else if (value instanceof CompositeData) {
// TODO
} else {
- result.put("value", convert(value));
+ result.put("mbean:value", convert(value));
}
}
} catch (final Exception ignore) {
// ignore, but put this as info
- result.put("exception", ignore.getMessage());
+ result.put("mbean:exception", ignore.getMessage());
}
return result;
}
Modified: sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java?rev=1513172&r1=1513171&r2=1513172&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java (original)
+++ sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java Mon Aug 12 15:47:07 2013
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.TreeMap;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
@@ -55,12 +56,32 @@ import org.apache.sling.commons.osgi.Pro
@Properties({
@Property(name = ResourceProvider.ROOTS, value="/system/sling/monitoring/mbeans")
})
+/**
+ * Brief summary of a "good" object name:
+ *
+ * Object names:
+ * - have a domain
+ * - should have a type property
+ * - could have a name property
+ * - additional props are not recommended
+ *
+ * Path to an MBean:
+ * {Domain}/{type property}/{name property}{all other props}
+ * where
+ * {Domain} : is a path consisting of the domain (dots replaced with slashes)
+ * {type property} : is the value of the type property or "{notype}" if no type property is set
+ * {name property} : is the value of the name property or "{noname}" if no name property is set
+ * {all other props} : name/value pairs containing all additional props
+ */
public class JMXResourceProvider implements ResourceProvider {
+ /** Configured root paths, ending with a slash */
private String[] rootsWithSlash;
+ /** Configured root paths, not ending with a slash */
private String[] roots;
+ /** The mbean server. */
private MBeanServer mbeanServer;
@Activate
@@ -112,13 +133,13 @@ public class JMXResourceProvider impleme
return new RootResource(resourceResolver, path);
}
if ( info.mbeanInfo == null ) {
- final Set<ObjectName> names = this.queryObjectNames(info.pathInfo.replace('/', '.') + ".");
+ final Set<ObjectName> names = this.queryObjectNames(info.pathInfo);
if ( names.size() != 0 ) {
return new RootResource(resourceResolver, path);
}
} else {
if (info.pathInfo == null ) {
- return new MBeanResource(resourceResolver, path, info.mbeanInfo);
+ return new MBeanResource(resourceResolver, this.convertObjectNameToResourcePath(info.objectName), path, info.mbeanInfo, info.objectName);
}
if ( info.pathInfo.equals("attributes") ) {
return new AttributesResource(resourceResolver, path);
@@ -138,13 +159,15 @@ public class JMXResourceProvider impleme
return null;
}
- private Set<ObjectName> queryObjectNames(final String domainPrefix) {
+ private Set<ObjectName> queryObjectNames(final String prefix) {
final Set<ObjectName> allNames = this.mbeanServer.queryNames(null, null);
Set<ObjectName> names = allNames;
- if ( domainPrefix != null ) {
+ if ( prefix != null ) {
+ final String pathPrefix = prefix + '/';
names = new HashSet<ObjectName>();
for(final ObjectName name : allNames) {
- if ( name.getDomain().startsWith(domainPrefix)) {
+ final String path = this.convertObjectNameToResourcePath(name);
+ if ( path.startsWith(pathPrefix) ) {
names.add(name);
}
}
@@ -159,12 +182,13 @@ public class JMXResourceProvider impleme
if ( info != null ) {
if ( info.isRoot || info.mbeanInfo == null ) {
// list all MBeans
- final Set<ObjectName> names = this.queryObjectNames(info.isRoot ? null : info.pathInfo.replace('/', '.') + ".");
+ final Set<ObjectName> names = this.queryObjectNames(info.isRoot ? null : info.pathInfo);
final Set<String> filteredNames = new HashSet<String>();
- final String prefix = (info.isRoot ? null : info.pathInfo.replace('/', '.') + ".");
+ final String prefix = (info.isRoot ? null : info.pathInfo + "/");
for(final ObjectName name : names) {
- final String testName = (info.isRoot ? name.getDomain() : name.getDomain().substring(prefix.length()));
- final int sep = testName.indexOf('.');
+ final String path = this.convertObjectNameToResourcePath(name);
+ final String testName = (info.isRoot ? path : path.substring(prefix.length()));
+ final int sep = testName.indexOf('/');
if ( sep == -1 ) {
filteredNames.add(":" + name.getCanonicalName());
} else {
@@ -190,8 +214,9 @@ public class JMXResourceProvider impleme
try {
final ObjectName on = new ObjectName(name.substring(1));
final MBeanInfo info = mbeanServer.getMBeanInfo(on);
- final int sep = on.getDomain().lastIndexOf('.');
- this.next = new MBeanResource(parent, on.getCanonicalName().substring(sep + 1), info);
+ final String path = convertObjectNameToResourcePath(on);
+ final int sep = path.lastIndexOf('/');
+ this.next = new MBeanResource(parent.getResourceResolver(), path, parent.getPath() + "/" + path.substring(sep + 1), info, on);
} catch (final IntrospectionException e) {
// ignore
} catch (final InstanceNotFoundException e) {
@@ -255,6 +280,92 @@ public class JMXResourceProvider impleme
return null;
}
+ private static final String MARKER_NOTYPE = "{notype}";
+ private static final String MARKER_NONAME = "{noname}";
+
+ private String convertObjectNameToResourcePath(final ObjectName name) {
+ final StringBuilder sb = new StringBuilder(name.getDomain().replace('.', '/'));
+ sb.append('/');
+ if ( name.getKeyProperty("type") != null ) {
+ sb.append(name.getKeyProperty("type"));
+ } else {
+ sb.append(MARKER_NOTYPE);
+ }
+ sb.append('/');
+ if ( name.getKeyProperty("name") != null ) {
+ sb.append(name.getKeyProperty("name"));
+ } else {
+ sb.append(MARKER_NONAME);
+ }
+ final TreeMap<String, String> props = new TreeMap<String, String>(name.getKeyPropertyList());
+ props.remove("name");
+ props.remove("type");
+ boolean first = true;
+ for(final Map.Entry<String, String> entry : props.entrySet()) {
+ if ( first ) {
+ first = false;
+ sb.append(':');
+ } else {
+ sb.append(',');
+ }
+ sb.append(entry.getKey());
+ sb.append('=');
+ sb.append(entry.getValue());
+ }
+ return sb.toString();
+ }
+
+ private ObjectName convertResourcePathToObjectName(final String path) {
+ final int nameSlash = path.lastIndexOf('/');
+ if ( nameSlash != -1 ) {
+ final int typeSlash = path.lastIndexOf('/', nameSlash - 1);
+ if ( typeSlash != -1 ) {
+ final String domain = path.substring(0, typeSlash).replace('/', '.');
+ final String type = path.substring(typeSlash + 1, nameSlash);
+ final String nameAndProps = path.substring(nameSlash + 1);
+ final int colonPos = nameAndProps.indexOf(':');
+ final String name;
+ final String props;
+ if ( colonPos == -1 ) {
+ name = nameAndProps;
+ props = null;
+ } else {
+ name = nameAndProps.substring(0, colonPos);
+ props = nameAndProps.substring(colonPos + 1);
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(domain);
+ sb.append(':');
+ boolean hasProps = false;
+ if ( !MARKER_NOTYPE.equals(type)) {
+ sb.append("type=");
+ sb.append(type);
+ hasProps = true;
+ }
+ if ( !MARKER_NONAME.equals(name) ) {
+ if ( hasProps ) {
+ sb.append(",");
+ }
+ sb.append("name=");
+ sb.append(name);
+ hasProps = true;
+ }
+ if ( props != null ) {
+ if ( hasProps ) {
+ sb.append(",");
+ }
+ sb.append(props);
+ }
+ try {
+ return new ObjectName(sb.toString());
+ } catch (final MalformedObjectNameException e) {
+ // ignore
+ }
+ }
+ }
+ return null;
+ }
+
public final static class PathInfo {
public final boolean isRoot;
@@ -293,10 +404,10 @@ public class JMXResourceProvider impleme
while ( checkPath.length() > 0 && mbi == null ) {
try {
- objectName = new ObjectName(checkPath.replace('/', '.'));
- mbi = this.mbeanServer.getMBeanInfo(objectName);
- } catch (final MalformedObjectNameException e) {
- // ignore
+ objectName = this.convertResourcePathToObjectName(checkPath);
+ if ( objectName != null ) {
+ mbi = this.mbeanServer.getMBeanInfo(objectName);
+ }
} catch (final IntrospectionException e) {
// ignore
} catch (final InstanceNotFoundException e) {
Modified: sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java?rev=1513172&r1=1513171&r2=1513172&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java (original)
+++ sling/trunk/contrib/extensions/jmxprovider/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java Mon Aug 12 15:47:07 2013
@@ -22,9 +22,9 @@ import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanInfo;
+import javax.management.ObjectName;
import org.apache.sling.api.resource.AbstractResource;
-import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
@@ -40,16 +40,25 @@ public class MBeanResource extends Abstr
private final MBeanInfo info;
- public MBeanResource(final Resource parent, final String name, final MBeanInfo info) {
- this.resourceResolver = parent.getResourceResolver();
- this.path = parent.getPath() + '/' + name;
- this.info = info;
- }
+ private final ObjectName objectName;
- public MBeanResource(final ResourceResolver resolver, final String path, final MBeanInfo info) {
+ private final String resourceType;
+
+ public MBeanResource(final ResourceResolver resolver,
+ final String resourceType,
+ final String path,
+ final MBeanInfo info,
+ final ObjectName objectName) {
this.resourceResolver = resolver;
this.path = path;
this.info = info;
+ this.objectName = objectName;
+ final int pos = resourceType.lastIndexOf(':');
+ if ( pos == -1 ) {
+ this.resourceType = resourceType;
+ } else {
+ this.resourceType = resourceType.substring(0, pos);
+ }
}
/**
@@ -63,14 +72,14 @@ public class MBeanResource extends Abstr
* @see org.apache.sling.api.resource.Resource#getResourceType()
*/
public String getResourceType() {
- return "sling:mbean";
+ return resourceType;
}
/**
* @see org.apache.sling.api.resource.Resource#getResourceSuperType()
*/
public String getResourceSuperType() {
- return null;
+ return "sling:mbean";
}
/**
@@ -99,14 +108,14 @@ public class MBeanResource extends Abstr
private Map<String, Object> getPropertiesMap() {
final Map<String, Object> result = new HashMap<String, Object>();
result.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, this.getResourceType());
- if ( this.getResourceSuperType() != null ) {
- result.put("sling:resourceSuperType", this.getResourceSuperType());
- }
+ result.put("sling:resourceSuperType", this.getResourceSuperType());
if ( this.info.getDescription() != null ) {
- result.put("description", this.info.getDescription());
+ result.put("mbean:description", this.info.getDescription());
}
- result.put("className", this.info.getClassName());
+ result.put("mbean:className", this.info.getClassName());
+ result.put("mbean:objectName", this.objectName.getCanonicalName());
+
return result;
}
}