[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openejb-cvs
Subject:    svn commit: r939204 - in
From:       dblevins () apache ! org
Date:       2010-04-29 6:07:41
Message-ID: 20100429060741.630A223888EA () eris ! apache ! org
[Download RAW message or body]

Author: dblevins
Date: Thu Apr 29 06:07:40 2010
New Revision: 939204

URL: http://svn.apache.org/viewvc?rev=939204&view=rev
Log:
Ability to easily export annotated stats beans as JMX objects.  Based on Martin \
Traverso's jmxutils.  Still a work in progress.

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/
  openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java \
(with props)  openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java \
(with props)  openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java \
(with props)  openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java \
(with props)

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java
                
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java?rev=939204&view=auto
 ==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java \
                (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java \
Thu Apr 29 06:07:40 2010 @@ -0,0 +1,101 @@
+/**
+ * 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.openejb.monitoring;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanException;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.RequiredModelMBean;
+import javax.management.modelmbean.ModelMBeanInfoSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanConstructorInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+import javax.management.modelmbean.ModelMBeanNotificationInfo;
+import java.util.List;
+import java.util.ArrayList;
+
+public class MBeanExporter {
+    private final MBeanServer server;
+
+    public MBeanExporter(MBeanServer server) {
+        this.server = server;
+    }
+
+    public void export(String name, Object object) {
+        try {
+            ObjectName objectName = new ObjectName(name);
+
+            MBeanInfoBuilder builder = new MBeanInfoBuilder();
+            ModelMBeanInfo info = builder.buildInfo(object.getClass());
+
+            // Use the GetterStrippingMBeanInfo to work around \
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6339571. +            \
RequiredModelMBean mbean = new RequiredModelMBean(new \
GetterStrippingMBeanInfo(info)); +            mbean.setManagedResource(object, \
"objectReference"); +
+            server.registerMBean(mbean, objectName);
+        }
+        catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static class GetterStrippingMBeanInfo extends ModelMBeanInfoSupport {
+        
+        public GetterStrippingMBeanInfo(ModelMBeanInfo info) {
+            super(info);
+        }
+
+        @Override
+        public GetterStrippingMBeanInfo clone() {
+            return new GetterStrippingMBeanInfo(this);
+        }
+
+        /**
+         * Get rid of getter and setter operations as the mbeaninfo is serialized
+         * Clients will see just the attributes
+         *
+         * @return
+         */
+        private Object writeReplace() {
+            List<MBeanOperationInfo> operations = new \
ArrayList<MBeanOperationInfo>(); +
+            for (MBeanOperationInfo operation : getOperations()) {
+    //            Descriptor descriptor = operation.getDescriptor();
+    //            String role = (String) descriptor.getFieldValue("role");
+    //            if (!"getter".equalsIgnoreCase(role) && \
!"setter".equalsIgnoreCase(role)) { +                operations.add(operation);
+    //            }
+            }
+
+            try {
+                return new ModelMBeanInfoSupport(
+                        this.getClassName(),
+                        this.getDescription(),
+                        (ModelMBeanAttributeInfo[]) this.getAttributes(),
+                        (ModelMBeanConstructorInfo[]) this.getConstructors(),
+                        operations.toArray(new ModelMBeanOperationInfo[0]),
+                        (ModelMBeanNotificationInfo[]) this.getNotifications(),
+                        this.getMBeanDescriptor());
+            }
+            catch (MBeanException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanExporter.java
                
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java
                
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java?rev=939204&view=auto
 ==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java \
                (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java \
Thu Apr 29 06:07:40 2010 @@ -0,0 +1,158 @@
+/**
+ * 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.openejb.monitoring;
+
+import org.apache.openejb.jee.oejb2.ClassFilterType;
+import org.apache.xbean.finder.ClassFinder;
+
+import javax.management.Descriptor;
+import javax.management.IntrospectionException;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanConstructorInfo;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanInfoSupport;
+import javax.management.modelmbean.ModelMBeanNotificationInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+class MBeanInfoBuilder {
+    private final static Pattern getterOrSetterPattern = \
Pattern.compile("(get|set|is)(.+)"); +
+    private static final String SUFFIX = MBeanInfoBuilder.class.getName();
+    private final static String DESCRIPTION = SUFFIX + ".description";
+    private final static String METHOD_INSTANCE = SUFFIX + ".methodInstance";
+    private final static String GET_METHOD_INSTANCE = SUFFIX + ".getMethodInstance";
+    private final static String SET_METHOD_INSTANCE = SUFFIX + ".setMethodInstance";
+
+    public ModelMBeanInfo buildInfo(Class clazz) throws IntrospectionException {
+        
+        Map<String, DescriptorSupport> attributes = new HashMap<String, \
DescriptorSupport>(); +        List<DescriptorSupport> operations = new \
ArrayList<DescriptorSupport>(); +
+        ClassFinder finder = new ClassFinder(clazz);
+
+        List<Method> methods = finder.findAnnotatedMethods(Managed.class);
+
+        for (Method method : methods) {
+            Managed annotation = method.getAnnotation(Managed.class);
+
+            DescriptorSupport operationDescriptor = new DescriptorSupport();
+            operationDescriptor.setField("name", method.getName());
+            operationDescriptor.setField("class", clazz.getName());
+            operationDescriptor.setField("descriptorType", "operation");
+            operationDescriptor.setField(DESCRIPTION, annotation.description());
+            operationDescriptor.setField(METHOD_INSTANCE, method);
+
+            operations.add(operationDescriptor);
+
+            Matcher matcher = getterOrSetterPattern.matcher(method.getName());
+            if (matcher.matches()) {
+                String type = matcher.group(1);
+                String attributeName = matcher.group(2);
+
+                DescriptorSupport descriptor = attributes.get(attributeName);
+                if (descriptor == null) {
+                    descriptor = new DescriptorSupport();
+                    descriptor.setField("name", attributeName);
+                    descriptor.setField("descriptorType", "attribute");
+                    descriptor.setField(DESCRIPTION, annotation.description());
+
+                    attributes.put(attributeName, descriptor);
+                }
+
+                if (type.equals("get") || type.equals("is")) {
+                    descriptor.setField(GET_METHOD_INSTANCE, method);
+                    descriptor.setField("getMethod", method.getName());
+                    operationDescriptor.setField("role", "getter");
+                } else if (type.equals("set")) {
+                    descriptor.setField(SET_METHOD_INSTANCE, method);
+                    descriptor.setField("setMethod", method.getName());
+                    operationDescriptor.setField("role", "setter");
+                }
+            } else {
+                operationDescriptor.setField("role", "operation");
+            }
+        }
+
+        List<ModelMBeanAttributeInfo> attributeInfos = new \
ArrayList<ModelMBeanAttributeInfo>(); +
+        for (DescriptorSupport attribute : attributes.values()) {
+            Method getter = (Method) attribute.getFieldValue(GET_METHOD_INSTANCE);
+            Method setter = (Method) attribute.getFieldValue(SET_METHOD_INSTANCE);
+            String description = (String) attribute.getFieldValue(DESCRIPTION);
+
+            // we're piggybacking on Descriptor to hold values that we need here. \
Remove them before passing +            // them on, as they will cause problems if \
they are not serializable (e.g., Method) +            strip(attribute);
+
+            attributeInfos.add(new \
ModelMBeanAttributeInfo(attribute.getFieldValue("name").toString(), +                 \
description, +                    getter,
+                    setter,
+                    attribute));
+        }
+
+        List<ModelMBeanOperationInfo> operationInfos = new \
ArrayList<ModelMBeanOperationInfo>(); +
+        for (DescriptorSupport operation : operations) {
+            String description = (String) operation.getFieldValue(DESCRIPTION);
+            Method method = (Method) operation.getFieldValue(METHOD_INSTANCE);
+
+            // we're piggybacking on Descriptor to hold values that we need here. \
Remove them before passing +            // them on, as they will cause problems if \
they are not serializable (e.g., Method) +            strip(operation);
+
+            Class<?>[] types = method.getParameterTypes();
+            String[] names = new String[types.length];
+            for (int i = 0; i < names.length; i++) {
+                names[i] = "arg" + i;
+            }
+
+            MBeanParameterInfo[] params = new MBeanParameterInfo[names.length];
+
+            for (int i = 0; i < names.length; ++i) {
+                params[i] = new MBeanParameterInfo(names[i], types[i].getName(), \
null); +            }
+
+            operationInfos.add(new ModelMBeanOperationInfo(method.getName(), \
description, params, +                    method.getReturnType().toString(), \
MBeanOperationInfo.UNKNOWN, operation)); +        }
+
+        return new ModelMBeanInfoSupport(clazz.getName(), null,
+                attributeInfos.toArray(new ModelMBeanAttributeInfo[0]),
+                new ModelMBeanConstructorInfo[0],
+                operationInfos.toArray(new ModelMBeanOperationInfo[0]),
+                new ModelMBeanNotificationInfo[0]);
+    }
+
+    private void strip(Descriptor descriptor) {
+        for (String name : descriptor.getFieldNames()) {
+            if (name.startsWith(SUFFIX)) {
+                descriptor.removeField(name);
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MBeanInfoBuilder.java
                
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java
                
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java?rev=939204&view=auto
 ==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java \
                (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java \
Thu Apr 29 06:07:40 2010 @@ -0,0 +1,28 @@
+/**
+ * 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.openejb.monitoring;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Managed {
+    String description() default "";
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/Managed.java
                
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java
                
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java?rev=939204&view=auto
 ==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java \
                (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java \
Thu Apr 29 06:07:40 2010 @@ -0,0 +1,66 @@
+/**
+ * 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.openejb.monitoring;
+
+import static java.lang.String.format;
+import java.lang.annotation.Annotation;
+
+/**
+ * Generate JMX object names.
+ */
+public class ObjectNames {
+
+    /**
+     * Produce a standardized JMX object name.
+     *
+     * @param clazz
+     * @return JMX object name of the form "[package_name]:name=[class_name]"
+     */
+    public static String generatedNameOf(Class<?> clazz) {
+        return format("%s:name=%s",
+                clazz.getPackage().getName(),
+                clazz.getSimpleName());
+    }
+
+    /**
+     * Produce a generated JMX object name.
+     *
+     * @param clazz
+     * @param annotation
+     * @return JMX object name of the form \
"[package_name]:type=[class_name],name=[ann_class_name]" +     */
+    public static String generatedNameOf(Class<?> clazz, Annotation annotation) {
+        return format("%s:type=%s,name=%s",
+                clazz.getPackage().getName(),
+                clazz.getSimpleName(),
+                annotation.annotationType().getSimpleName());
+    }
+
+    /**
+     * Produce a generated JMX object name.
+     *
+     * @param clazz
+     * @param annotationClass
+     * @return JMX object name of the form \
"[package_name]:type=[class_name],name=[ann_class_name]" +     */
+    public static String generatedNameOf(Class<?> clazz, Class<? extends Annotation> \
annotationClass) { +        return format("%s:type=%s,name=%s",
+                clazz.getPackage().getName(),
+                clazz.getSimpleName(),
+                annotationClass.getSimpleName());
+    }
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNames.java
                
------------------------------------------------------------------------------
    svn:eol-style = native


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic