You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:24:24 UTC

[sling-org-apache-sling-jmx-provider] 01/39: SLING-2999 : JMX Resource Provider

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jmx-provider.git

commit c075cc53c493b3e54d8e0d4e52a9d9353036f1e2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Aug 9 15:20:23 2013 +0000

    SLING-2999 : JMX Resource Provider
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1512336 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  93 +++++++
 .../sling/jmx/provider/impl/AttributeResource.java | 138 ++++++++++
 .../jmx/provider/impl/AttributesResource.java      |  98 +++++++
 .../jmx/provider/impl/JMXResourceProvider.java     | 289 +++++++++++++++++++++
 .../sling/jmx/provider/impl/MBeanResource.java     | 113 ++++++++
 .../sling/jmx/provider/impl/RootResource.java      |  98 +++++++
 6 files changed, 829 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..07cbefa
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>17</version>
+    </parent>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>org.apache.sling.jmx.provider</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling JMX Resource Provider</name>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/jmxprovider</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/jmxprovider</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/jmxprovider</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.jmx.provider.impl
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+    	    <groupId>org.apache.sling</groupId>
+    	    <artifactId>org.apache.sling.api</artifactId>
+    	    <version>2.4.0</version>
+    	    <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.felix</groupId>
+        	<artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+        	<groupId>org.slf4j</groupId>
+        	<artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+        	<groupId>javax.servlet</groupId>
+        	<artifactId>servlet-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java b/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java
new file mode 100644
index 0000000..5e303a3
--- /dev/null
+++ b/src/main/java/org/apache/sling/jmx/provider/impl/AttributeResource.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jmx.provider.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeMBeanException;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+public class AttributeResource extends AbstractResource {
+
+    private final String path;
+
+    private final ResourceResolver resourceResolver;
+
+    private final ResourceMetadata metadata = new ResourceMetadata();
+
+    private final MBeanAttributeInfo info;
+
+    private final MBeanServer server;
+
+    private final ObjectName on;
+
+    public AttributeResource(final MBeanServer server,
+                             final ObjectName on,
+                             final ResourceResolver resolver, final String p, final MBeanAttributeInfo mai) {
+        this.resourceResolver = resolver;
+        this.path = p;
+        this.info = mai;
+        this.on = on;
+        this.server = server;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getPath()
+     */
+    public String getPath() {
+        return this.path;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceType()
+     */
+    public String getResourceType() {
+        return "sling:mbeanattribute";
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+     */
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+     */
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+     */
+    public ResourceResolver getResourceResolver() {
+        return this.resourceResolver;
+    }
+
+    @Override
+    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+        if ( type == ValueMap.class || type == Map.class ) {
+            final Map<String, Object> propMap = this.getPropertiesMap();
+            return (AdapterType) new ValueMapDecorator(propMap);
+        }
+        return super.adaptTo(type);
+    }
+
+    private Map<String, Object> getPropertiesMap() {
+        final Map<String, Object> result = new HashMap<String, Object>();
+        result.put(SlingConstants.PROPERTY_RESOURCE_TYPE, this.getResourceType());
+        if ( this.getResourceSuperType() != null ) {
+            result.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, this.getResourceSuperType());
+        }
+
+        if ( info.getDescription() != null ) {
+            result.put("description", info.getDescription());
+        }
+        result.put("type", info.getType());
+
+        try {
+            final Object value = server.getAttribute(this.on, info.getName());
+            if ( value != null ) {
+                result.put("value", value.toString());
+            }
+        } catch (final RuntimeMBeanException uoe) {
+            // ignore
+        } catch (final AttributeNotFoundException e) {
+            // ignore
+        } catch (final InstanceNotFoundException e) {
+            // ignore
+        } catch (final MBeanException e) {
+            // ignore
+        } catch (final ReflectionException e) {
+            // ignore
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/org/apache/sling/jmx/provider/impl/AttributesResource.java b/src/main/java/org/apache/sling/jmx/provider/impl/AttributesResource.java
new file mode 100644
index 0000000..976cd06
--- /dev/null
+++ b/src/main/java/org/apache/sling/jmx/provider/impl/AttributesResource.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jmx.provider.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+public class AttributesResource extends AbstractResource {
+
+    private final String path;
+
+    private final ResourceResolver resourceResolver;
+
+    private final ResourceMetadata metadata = new ResourceMetadata();
+
+    public AttributesResource(final ResourceResolver resolver, final String p) {
+        this.resourceResolver = resolver;
+        this.path = p;
+
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getPath()
+     */
+    public String getPath() {
+        return this.path;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceType()
+     */
+    public String getResourceType() {
+        return "sling:mbeanattributes";
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+     */
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+     */
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+     */
+    public ResourceResolver getResourceResolver() {
+        return this.resourceResolver;
+    }
+
+    @Override
+    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+        if ( type == ValueMap.class || type == Map.class ) {
+            final Map<String, Object> propMap = this.getPropertiesMap();
+            return (AdapterType) new ValueMapDecorator(propMap);
+        }
+        return super.adaptTo(type);
+    }
+
+    private Map<String, Object> getPropertiesMap() {
+        final Map<String, Object> result = new HashMap<String, Object>();
+        result.put(SlingConstants.PROPERTY_RESOURCE_TYPE, this.getResourceType());
+        if ( this.getResourceSuperType() != null ) {
+            result.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, this.getResourceSuperType());
+        }
+
+        return result;
+    }
+}
diff --git a/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java b/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java
new file mode 100644
index 0000000..a8c99c6
--- /dev/null
+++ b/src/main/java/org/apache/sling/jmx/provider/impl/JMXResourceProvider.java
@@ -0,0 +1,289 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jmx.provider.impl;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+
+@Component
+@Service(value = ResourceProvider.class)
+@Properties({
+    @Property(name = ResourceProvider.ROOTS, value="/system/sling/monitoring/mbeans")
+})
+public class JMXResourceProvider implements ResourceProvider {
+
+    private String[] rootsWithSlash;
+
+    private String[] roots;
+
+    private MBeanServer mbeanServer;
+
+    @Activate
+    protected void activate(final Map<String, Object> props) {
+        final String paths[] = PropertiesUtil.toStringArray(props.get(ResourceProvider.ROOTS));
+        final List<String> rootsList = new ArrayList<String>();
+        final List<String> rootsWithSlashList = new ArrayList<String>();
+        if ( paths != null ) {
+            for(final String p : paths) {
+                if ( p.length() > 0 ) {
+                    if ( p.endsWith("/") ) {
+                        rootsList.add(p.substring(0,  p.length() - 1));
+                        rootsWithSlashList.add(p);
+                    } else {
+                        rootsList.add(p);
+                        rootsWithSlashList.add(p + "/");
+                    }
+                }
+            }
+        }
+        this.rootsWithSlash = rootsWithSlashList.toArray(new String[rootsWithSlashList.size()]);
+        this.roots = rootsList.toArray(new String[rootsList.size()]);
+
+        this.mbeanServer = ManagementFactory.getPlatformMBeanServer();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        this.mbeanServer = null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, javax.servlet.http.HttpServletRequest, java.lang.String)
+     */
+    public Resource getResource(final ResourceResolver resourceResolver,
+                                final HttpServletRequest request,
+                                final String path) {
+        return getResource(resourceResolver, path);
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
+     */
+    public Resource getResource(final ResourceResolver resourceResolver,
+                                final String path) {
+        final PathInfo info = this.parse(path);
+        if ( info != null ) {
+            if ( info.isRoot ) {
+                return new RootResource(resourceResolver, path);
+            }
+            try {
+                final ObjectName on = new ObjectName(info.mbeanName);
+                final MBeanInfo mbi = this.mbeanServer.getMBeanInfo(on);
+                if (info.pathInfo == null ) {
+                    return new MBeanResource(resourceResolver, path, mbi);
+                }
+                if ( info.pathInfo.equals("attributes") ) {
+                    return new AttributesResource(resourceResolver, path);
+                }
+                if ( info.pathInfo.startsWith("attributes/") ) {
+                    final String attrName = info.pathInfo.substring(11);
+                    if ( attrName.indexOf('/') == - 1) {
+                        for(final MBeanAttributeInfo mai : mbi.getAttributes()) {
+                            if ( mai.getName().equals(attrName) ) {
+                                return new AttributeResource(mbeanServer, on, resourceResolver, path, mai);
+                            }
+                        }
+                    }
+                }
+            } catch (final MalformedObjectNameException e) {
+                // ignore
+            } catch (final IntrospectionException e) {
+                // ignore
+            } catch (final InstanceNotFoundException e) {
+                // ignore
+            } catch (final ReflectionException e) {
+                // ignore
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache.sling.api.resource.Resource)
+     */
+    public Iterator<Resource> listChildren(final Resource parent) {
+        final PathInfo info = this.parse(parent.getPath());
+        if ( info != null ) {
+            if ( info.isRoot ) {
+                // list all mbeans
+                final Set<ObjectName> beans = this.mbeanServer.queryNames(null, null);
+                final List<ObjectName> sortedBeans = new ArrayList<ObjectName>(beans);
+                Collections.sort(sortedBeans);
+                final Iterator<ObjectName> iter = sortedBeans.iterator();
+                return new Iterator<Resource>() {
+
+                    private Resource next;
+
+                    {
+                        seek();
+                    }
+
+                    private void seek() {
+                        while ( iter.hasNext() ) {
+                            final ObjectName on = iter.next();
+                            try {
+                                final MBeanInfo info = mbeanServer.getMBeanInfo(on);
+                                this.next = new MBeanResource(parent, on.getCanonicalName(), info);
+                                break;
+                            } catch (final IntrospectionException e) {
+                                // ignore
+                            } catch (final InstanceNotFoundException e) {
+                                // ignore
+                            } catch (final ReflectionException e) {
+                                // ignore
+                            }
+                        }
+                    }
+
+                    public boolean hasNext() {
+                        return next != null;
+                    }
+
+                    public Resource next() {
+                        if ( next != null ) {
+                            final Resource rsrc = next;
+                            this.next = null;
+                            seek();
+                            return rsrc;
+                        }
+                        throw new NoSuchElementException();
+                    }
+
+                    public void remove() {
+                        throw new UnsupportedOperationException("remove");
+                    }
+                };
+            } else {
+                try {
+                    final ObjectName on = new ObjectName(info.mbeanName);
+                    final MBeanInfo mbi = this.mbeanServer.getMBeanInfo(on);
+                    if ( info.pathInfo == null ) {
+                        final List<Resource> list = new ArrayList<Resource>();
+                        list.add(new AttributesResource(parent.getResourceResolver(), parent.getPath() + "/attributes"));
+                        return list.iterator();
+                    } else if ( info.pathInfo.equals("attributes") ) {
+                        final MBeanAttributeInfo[] infos = mbi.getAttributes();
+                        final List<MBeanAttributeInfo> list = Arrays.asList(infos);
+                        final Iterator<MBeanAttributeInfo> iter = list.iterator();
+                        return new Iterator<Resource>() {
+
+                            public void remove() {
+                                throw new UnsupportedOperationException("remove");
+                            }
+
+                            public Resource next() {
+                                final MBeanAttributeInfo mai = iter.next();
+                                return new AttributeResource(mbeanServer, on, parent.getResourceResolver(), parent.getPath() + "/" + mai.getName(), mai);
+                            }
+
+                            public boolean hasNext() {
+                                return iter.hasNext();
+                            }
+                        };
+                    }
+                } catch (final MalformedObjectNameException e) {
+                    // ignore
+                } catch (final IntrospectionException e) {
+                    // ignore
+                } catch (final InstanceNotFoundException e) {
+                    // ignore
+                } catch (final ReflectionException e) {
+                    // ignore
+                }
+            }
+        }
+        return null;
+    }
+
+    public final static class PathInfo {
+        public final boolean isRoot;
+        public final String mbeanName;
+        public final String pathInfo;
+
+        public PathInfo(final boolean isRoot) {
+            this.isRoot = isRoot;
+            this.mbeanName = null;
+            this.pathInfo = null;
+        }
+
+        public PathInfo(final String name, final String info) {
+            this.isRoot = false;
+            this.mbeanName = name;
+            this.pathInfo = info;
+        }
+    }
+
+    private PathInfo parse(final String path) {
+        for(final String root : this.rootsWithSlash) {
+            if ( path.startsWith(root) ) {
+                final String subPath = path.substring(root.length());
+                if ( subPath.length() == 0 ) {
+                    return new PathInfo(true);
+                }
+                // mbean name
+                final int sep = subPath.indexOf('/');
+                final String mbeanName;
+                final String pathInfo;
+                if ( sep == -1 ) {
+                    mbeanName = subPath;
+                    pathInfo = null;
+                } else {
+                    mbeanName = subPath.substring(0, sep);
+                    pathInfo = subPath.substring(sep + 1);
+                }
+                return new PathInfo(mbeanName, pathInfo);
+            }
+        }
+        for(final String root : this.roots) {
+            if ( path.equals(root) ) {
+                return new PathInfo(true);
+            }
+        }
+        return null;
+
+    }
+}
diff --git a/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java b/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java
new file mode 100644
index 0000000..c3a89b8
--- /dev/null
+++ b/src/main/java/org/apache/sling/jmx/provider/impl/MBeanResource.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jmx.provider.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.MBeanInfo;
+
+import org.apache.sling.api.SlingConstants;
+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;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+public class MBeanResource extends AbstractResource {
+
+    private final String path;
+
+    private final ResourceResolver resourceResolver;
+
+    private final ResourceMetadata metadata = new ResourceMetadata();
+
+    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;
+    }
+
+    public MBeanResource(final ResourceResolver resolver, final String path, final MBeanInfo info) {
+        this.resourceResolver = resolver;
+        this.path = path;
+        this.info = info;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getPath()
+     */
+    public String getPath() {
+        return this.path;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceType()
+     */
+    public String getResourceType() {
+        return "sling:mbean";
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+     */
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+     */
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+     */
+    public ResourceResolver getResourceResolver() {
+        return this.resourceResolver;
+    }
+
+    @Override
+    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+        if ( type == ValueMap.class || type == Map.class ) {
+            final Map<String, Object> propMap = this.getPropertiesMap();
+            return (AdapterType) new ValueMapDecorator(propMap);
+        }
+        return super.adaptTo(type);
+    }
+
+    private Map<String, Object> getPropertiesMap() {
+        final Map<String, Object> result = new HashMap<String, Object>();
+        result.put(SlingConstants.PROPERTY_RESOURCE_TYPE, this.getResourceType());
+        if ( this.getResourceSuperType() != null ) {
+            result.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, this.getResourceSuperType());
+        }
+
+        if ( this.info.getDescription() != null ) {
+            result.put("description", this.info.getDescription());
+        }
+        result.put("className", this.info.getClassName());
+        return result;
+    }
+}
diff --git a/src/main/java/org/apache/sling/jmx/provider/impl/RootResource.java b/src/main/java/org/apache/sling/jmx/provider/impl/RootResource.java
new file mode 100644
index 0000000..b687e90
--- /dev/null
+++ b/src/main/java/org/apache/sling/jmx/provider/impl/RootResource.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jmx.provider.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+public class RootResource extends AbstractResource {
+
+    private final String path;
+
+    private final ResourceResolver resourceResolver;
+
+    private final ResourceMetadata metadata = new ResourceMetadata();
+
+    public RootResource(final ResourceResolver resolver, final String p) {
+        this.resourceResolver = resolver;
+        this.path = p;
+
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getPath()
+     */
+    public String getPath() {
+        return this.path;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceType()
+     */
+    public String getResourceType() {
+        return "sling:mbeans";
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+     */
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+     */
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+     */
+    public ResourceResolver getResourceResolver() {
+        return this.resourceResolver;
+    }
+
+    @Override
+    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
+        if ( type == ValueMap.class || type == Map.class ) {
+            final Map<String, Object> propMap = this.getPropertiesMap();
+            return (AdapterType) new ValueMapDecorator(propMap);
+        }
+        return super.adaptTo(type);
+    }
+
+    private Map<String, Object> getPropertiesMap() {
+        final Map<String, Object> result = new HashMap<String, Object>();
+        result.put(SlingConstants.PROPERTY_RESOURCE_TYPE, this.getResourceType());
+        if ( this.getResourceSuperType() != null ) {
+            result.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, this.getResourceSuperType());
+        }
+
+        return result;
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.