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