Repository: deltaspike
Updated Branches:
  refs/heads/master 4aa12e065 -> 774887693


DELTASPIKE-1246 add support for TabularData in @MBean


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/77488769
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/77488769
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/77488769

Branch: refs/heads/master
Commit: 7748876931635172a906808d550cd316342109ac
Parents: 4aa12e0
Author: rmannibucau <rmannibu...@apache.org>
Authored: Mon Apr 24 13:19:35 2017 +0200
Committer: rmannibucau <rmannibu...@apache.org>
Committed: Mon Apr 24 13:19:35 2017 +0200

----------------------------------------------------------------------
 .../deltaspike/core/api/jmx/JmxManaged.java     |  5 +
 .../core/impl/jmx/DynamicMBeanWrapper.java      | 96 +++++++++++++++-----
 .../deltaspike/test/core/impl/jmx/MyMBean.java  | 12 +++
 .../core/impl/jmx/SimpleRegistrationTest.java   | 19 +++-
 4 files changed, 106 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/77488769/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java
 
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java
index b9f28ae..b383e4e 100644
--- 
a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java
+++ 
b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java
@@ -45,4 +45,9 @@ public @interface JmxManaged
      * @return the description either of the operation or the attribute 
exported through JMX.
      */
     String description() default "";
+
+    /**
+     * @return if true a Map will be converted to a TabularData with a 
CompositeData entry, if false the map will be returned directly.
+     */
+    boolean convertMapToTabularData() default true;
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/77488769/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java
 
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java
index 9a7c1e0..3146a21 100644
--- 
a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java
+++ 
b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java
@@ -18,19 +18,15 @@
  */
 package org.apache.deltaspike.core.impl.jmx;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.jmx.JmxBroadcaster;
+import org.apache.deltaspike.core.api.jmx.JmxManaged;
+import org.apache.deltaspike.core.api.jmx.JmxParameter;
+import org.apache.deltaspike.core.api.jmx.MBean;
+import org.apache.deltaspike.core.api.jmx.NotificationInfo;
+import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.util.ParameterUtil;
 
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.spi.Bean;
@@ -50,16 +46,27 @@ import javax.management.MBeanParameterInfo;
 import javax.management.Notification;
 import javax.management.NotificationBroadcasterSupport;
 import javax.management.ReflectionException;
-
-import org.apache.deltaspike.core.api.config.ConfigResolver;
-import org.apache.deltaspike.core.api.jmx.JmxBroadcaster;
-import org.apache.deltaspike.core.api.jmx.JmxManaged;
-import org.apache.deltaspike.core.api.jmx.JmxParameter;
-import org.apache.deltaspike.core.api.jmx.MBean;
-import org.apache.deltaspike.core.api.jmx.NotificationInfo;
-import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
-import org.apache.deltaspike.core.api.provider.BeanProvider;
-import org.apache.deltaspike.core.util.ParameterUtil;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * This class is the MBean implementation of a CDI bean.
@@ -230,7 +237,8 @@ public class DynamicMBeanWrapper extends 
NotificationBroadcasterSupport implemen
                     }
 
                     attributeInfos.add(new MBeanAttributeInfo(
-                        fieldName, type.getName(), fieldDescription, getter != 
null, setter != null, false));
+                        fieldName, toMBeanType(type).getName(), 
fieldDescription,
+                            getter != null, setter != null, false));
 
                     fields.put(fieldName, new AttributeAccessor(getter, 
setter));
                 }
@@ -246,6 +254,15 @@ public class DynamicMBeanWrapper extends 
NotificationBroadcasterSupport implemen
                 notificationInfos.toArray(new 
MBeanNotificationInfo[notificationInfos.size()]));
     }
 
+    private Class<?> toMBeanType(final Class<?> type)
+    {
+        if (Map.class == type)
+        {
+            return TabularData.class;
+        }
+        return type;
+    }
+
     private MBeanNotificationInfo getNotificationInfo(final NotificationInfo 
notificationInfo, String sourceInfo)
     {
         return new MBeanNotificationInfo(
@@ -288,7 +305,12 @@ public class DynamicMBeanWrapper extends 
NotificationBroadcasterSupport implemen
             Thread.currentThread().setContextClassLoader(classloader);
             try
             {
-                return fields.get(attribute).get(instance());
+                final Object o = fields.get(attribute).get(instance());
+                if (Map.class.isInstance(o))
+                {
+                    return toTabularData(attribute, attribute, 
Map.class.cast(o));
+                }
+                return o;
             }
             catch (IllegalArgumentException e)
             {
@@ -310,6 +332,30 @@ public class DynamicMBeanWrapper extends 
NotificationBroadcasterSupport implemen
         throw new AttributeNotFoundException();
     }
 
+    private TabularData toTabularData(final String typeName, final String 
description, final Map map)
+    {
+        final OpenType<?>[] types = new OpenType<?>[map.size()];
+        for (int i = 0; i < types.length; i++)
+        {
+            types[i] = SimpleType.STRING;
+        }
+
+        try
+        {
+            final String[] keys = String[].class.cast(map.keySet().toArray(new 
String[map.size()]));
+            final CompositeType ct = new CompositeType(
+                    typeName, description, keys, keys, types);
+            final TabularType type = new TabularType(typeName, description, 
ct, keys);
+            final TabularDataSupport data = new TabularDataSupport(type);
+            data.put(new CompositeDataSupport(ct, map));
+            return data;
+        }
+        catch (final OpenDataException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
     @Override
     public void setAttribute(final Attribute attribute)
         throws AttributeNotFoundException, InvalidAttributeValueException, 
MBeanException, ReflectionException

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/77488769/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java
 
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java
index a48f858..16e8cbd 100644
--- 
a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java
+++ 
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java
@@ -26,6 +26,8 @@ import org.apache.deltaspike.core.api.jmx.MBean;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 import javax.management.Notification;
+import java.util.HashMap;
+import java.util.Map;
 
 @ApplicationScoped
 @MBean(description = "my mbean")
@@ -37,6 +39,16 @@ public class MyMBean
     @Inject
     private JmxBroadcaster broadcaster;
 
+    @JmxManaged
+    private Map<String, String> table;
+
+    public Map<String, String> getTable() {
+        return table != null ? table : (table = new HashMap<String, String>() 
{{
+            put("key1", "value1");
+            put("key2", "value2");
+        }});
+    }
+
     public int getCounter()
     {
         return counter;

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/77488769/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java
----------------------------------------------------------------------
diff --git 
a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java
 
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java
index c999d4f..5409fac 100644
--- 
a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java
+++ 
b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java
@@ -21,7 +21,14 @@ package org.apache.deltaspike.test.core.impl.jmx;
 import org.junit.Test;
 
 import javax.inject.Inject;
-import javax.management.*;
+import javax.management.Attribute;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -67,5 +74,15 @@ public abstract class SimpleRegistrationTest {
         MBeanParameterInfo parameterInfo = 
server.getMBeanInfo(on).getOperations()[0].getSignature()[0];
         assertEquals("multiplier", parameterInfo.getName());
         assertEquals("the multiplier", parameterInfo.getDescription());
+
+        // table support
+        Object table = server.getAttribute(on, "table");
+        assertTrue(TabularData.class.isInstance(table));
+        final TabularData data = TabularData.class.cast(table);
+        assertEquals(1, data.size());
+        final CompositeData compositeData = 
CompositeData.class.cast(data.values().iterator().next());
+        assertEquals(2, compositeData.values().size());
+        assertEquals("value1", compositeData.get("key1"));
+        assertEquals("value2", compositeData.get("key2"));
     }
 }

Reply via email to