[infinispan-commits] Infinispan SVN: r800 - in trunk/core/src: test/java/org/infinispan/jmx and 1 other directory.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Wed Sep 9 06:50:50 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-09-09 06:50:49 -0400 (Wed, 09 Sep 2009)
New Revision: 800

Modified:
   trunk/core/src/main/java/org/infinispan/jmx/ResourceDMBean.java
   trunk/core/src/test/java/org/infinispan/jmx/CacheManagerMBeanTest.java
Log:
[ISPN-189] (ResourceDMBean.invoke() should check if method invoked is a managed operation) Fixed by checking whether the invoker operation is contained in the mbean operation list.


Modified: trunk/core/src/main/java/org/infinispan/jmx/ResourceDMBean.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/jmx/ResourceDMBean.java	2009-09-09 10:41:41 UTC (rev 799)
+++ trunk/core/src/main/java/org/infinispan/jmx/ResourceDMBean.java	2009-09-09 10:50:49 UTC (rev 800)
@@ -37,6 +37,8 @@
 import javax.management.MBeanInfo;
 import javax.management.MBeanOperationInfo;
 import javax.management.ReflectionException;
+import javax.management.ServiceNotFoundException;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -48,22 +50,22 @@
 import java.util.regex.Pattern;
 
 /**
- * This class was entirely copied from jgroups 2.7 (same name there). Couldn't simply reuse it because jgroups does not
- * ship with MBean, ManagedAttribute and ManagedOperation. Once jgroups will ship these classes, the code can be
- * dinalmically reused from there.
- *
+ * This class was entirely copied from jgroups 2.7 (same name there). Couldn't simply reuse it
+ * because jgroups does not ship with MBean, ManagedAttribute and ManagedOperation. Once jgroups
+ * will ship these classes, the code can be dinalmically reused from there.
+ * 
+ * The original JGroup's ResourceDMBean logic has been modified so that {@link #invoke()} method checks 
+ * whether the operation called has been exposed as a {@link ManagedOperation}, otherwise the call
+ * fails. JGroups deviated from this logic on purpouse because they liked the fact that you could expose 
+ * all class methods by simply annotating class with {@link MBean} annotation.
+ * 
  * @author Mircea.Markus at jboss.com
+ * @author Galder Zamarreño
  * @since 4.0
  */
 public class ResourceDMBean implements DynamicMBean {
-   private static final Class<?>[] primitives = {int.class,
-                                                 byte.class,
-                                                 short.class,
-                                                 long.class,
-                                                 float.class,
-                                                 double.class,
-                                                 boolean.class,
-                                                 char.class};
+   private static final Class<?>[] primitives = { int.class, byte.class, short.class, long.class,
+            float.class, double.class, boolean.class, char.class };
 
    private static final String MBEAN_DESCRITION = "Dynamic MBean Description";
 
@@ -72,7 +74,7 @@
    private String description = "";
 
    private final MBeanAttributeInfo[] attrInfo;
-   private final MBeanOperationInfo[] opInfo;
+   private final MBeanOperationInfo[] opInfos;
 
    private final HashMap<String, AttributeEntry> atts = new HashMap<String, AttributeEntry>();
    private final List<MBeanOperationInfo> ops = new ArrayList<MBeanOperationInfo>();
@@ -95,26 +97,18 @@
          info = entry.getInfo();
          attrInfo[i++] = info;
          if (log.isInfoEnabled()) {
-            log.trace("Attribute " + info.getName()
-                  + "[r="
-                  + info.isReadable()
-                  + ",w="
-                  + info.isWritable()
-                  + ",is="
-                  + info.isIs()
-                  + ",type="
-                  + info.getType()
-                  + "]");
+            log.trace("Attribute " + info.getName() + "[r=" + info.isReadable() + ",w="
+                     + info.isWritable() + ",is=" + info.isIs() + ",type=" + info.getType() + "]");
          }
       }
 
-      opInfo = new MBeanOperationInfo[ops.size()];
-      ops.toArray(opInfo);
+      opInfos = new MBeanOperationInfo[ops.size()];
+      ops.toArray(opInfos);
 
-      if (log.isInfoEnabled()) {
+      if (log.isTraceEnabled()) {
          if (ops.size() > 0)
             log.trace("Operations are:");
-         for (MBeanOperationInfo op : opInfo) {
+         for (MBeanOperationInfo op : opInfos) {
             log.trace("Operation " + op.getReturnType() + " " + op.getName());
          }
       }
@@ -131,18 +125,13 @@
          if (log.isDebugEnabled()) {
             log.debug("@MBean description set - " + mbean.description());
          }
-         MBeanAttributeInfo info = new MBeanAttributeInfo(MBEAN_DESCRITION,
-                                                          "java.lang.String",
-                                                          "@MBean description",
-                                                          true,
-                                                          false,
-                                                          false);
+         MBeanAttributeInfo info = new MBeanAttributeInfo(MBEAN_DESCRITION, "java.lang.String",
+                  "@MBean description", true, false, false);
          try {
-            atts.put(MBEAN_DESCRITION,
-                     new FieldAttributeEntry(info, getClass().getDeclaredField("description")));
-         }
-         catch (NoSuchFieldException e) {
-            //this should not happen unless somebody removes description field
+            atts.put(MBEAN_DESCRITION, new FieldAttributeEntry(info, getClass().getDeclaredField(
+                     "description")));
+         } catch (NoSuchFieldException e) {
+            // this should not happen unless somebody removes description field
             log.warn("Could not reflect field description of this class. Was it removed?");
          }
       }
@@ -150,12 +139,8 @@
 
    public synchronized MBeanInfo getMBeanInfo() {
 
-      return new MBeanInfo(getObject().getClass().getCanonicalName(),
-                           description,
-                           attrInfo,
-                           null,
-                           opInfo,
-                           null);
+      return new MBeanInfo(getObject().getClass().getCanonicalName(), description, attrInfo, null,
+               opInfos, null);
    }
 
    public synchronized Object getAttribute(String name) throws AttributeNotFoundException {
@@ -164,7 +149,8 @@
 
       Attribute attr = getNamedAttribute(name);
       if (attr == null) {
-         throw new AttributeNotFoundException("Unknown attribute '" + name + "'. Known attributes names are: " + atts.keySet());
+         throw new AttributeNotFoundException("Unknown attribute '" + name
+                  + "'. Known attributes names are: " + atts.keySet());
       }
       return attr.getValue();
    }
@@ -198,9 +184,8 @@
             results.add(attr);
          } else {
             if (log.isWarnEnabled()) {
-               log.warn("Failed to update attribute name " + attr.getName()
-                     + " with value "
-                     + attr.getValue());
+               log.warn("Failed to update attribute name " + attr.getName() + " with value "
+                        + attr.getValue());
             }
          }
       }
@@ -208,19 +193,32 @@
    }
 
    public Object invoke(String name, Object[] args, String[] sig) throws MBeanException,
-                                                                         ReflectionException {
-      try {
-         if (log.isDebugEnabled()) {
-            log.debug("Invoke method called on " + name);
+            ReflectionException {
+      if (log.isDebugEnabled()) {
+         log.debug("Invoke method called on " + name);
+      }
+
+      MBeanOperationInfo opInfo = null;
+      for (MBeanOperationInfo op : opInfos) {
+         if (op.getName().equals(name)) {
+            opInfo = op;
+            break;
          }
+      }
+
+      if (opInfo == null) {
+         final String msg = "Operation " + name + " not in ModelMBeanInfo";
+         throw new MBeanException(new ServiceNotFoundException(msg), msg);
+      }
+
+      try {
          Class<?>[] classes = new Class[sig.length];
          for (int i = 0; i < classes.length; i++) {
             classes[i] = getClassForName(sig[i]);
          }
          Method method = getObject().getClass().getMethod(name, classes);
          return method.invoke(getObject(), args);
-      }
-      catch (Exception e) {
+      } catch (Exception e) {
          throw new MBeanException(e);
       }
    }
@@ -229,9 +227,8 @@
       try {
          Class<?> c = Util.loadClass(name);
          return c;
-      }
-      catch (ClassNotFoundException cnfe) {
-         //Could be a primitive - let's check
+      } catch (ClassNotFoundException cnfe) {
+         // Could be a primitive - let's check
          for (int i = 0; i < primitives.length; i++) {
             if (name.equals(primitives[i].getName())) {
                return primitives[i];
@@ -242,116 +239,103 @@
    }
 
    private void findMethods() {
-      //find all methods but don't include methods from Object class
-      List<Method> methods = new ArrayList<Method>(Arrays.asList(getObject().getClass().getMethods()));
+      // find all methods but don't include methods from Object class
+      List<Method> methods = new ArrayList<Method>(Arrays.asList(getObject().getClass()
+               .getMethods()));
       List<Method> objectMethods = new ArrayList<Method>(Arrays.asList(Object.class.getMethods()));
       methods.removeAll(objectMethods);
 
       for (Method method : methods) {
-         //does method have @ManagedAttribute annotation?
+         // does method have @ManagedAttribute annotation?
          ManagedAttribute attr = method.getAnnotation(ManagedAttribute.class);
          if (attr != null) {
             String methodName = method.getName();
             if (!methodName.startsWith("get") && !methodName.startsWith("set")
-                  && !methodName.startsWith("is")) {
+                     && !methodName.startsWith("is")) {
                if (log.isWarnEnabled())
                   log.warn("method name " + methodName
-                        + " doesn't start with \"get\", \"set\", or \"is\""
-                        + ", but is annotated with @ManagedAttribute: will be ignored");
+                           + " doesn't start with \"get\", \"set\", or \"is\""
+                           + ", but is annotated with @ManagedAttribute: will be ignored");
             } else {
                MBeanAttributeInfo info = null;
-               //Is name field of @ManagedAttributed used?
+               // Is name field of @ManagedAttributed used?
                String attributeName = attr.name().length() > 0 ? attr.name().trim() : null;
                boolean writeAttribute = false;
                if (isSetMethod(method)) { // setter
                   attributeName = (attributeName == null) ? methodName.substring(3) : attributeName;
-                  info = new MBeanAttributeInfo(attributeName,
-                                                method.getParameterTypes()[0].getCanonicalName(),
-                                                attr.description(),
-                                                true,
-                                                true,
-                                                false);
+                  info = new MBeanAttributeInfo(attributeName, method.getParameterTypes()[0]
+                           .getCanonicalName(), attr.description(), true, true, false);
                   writeAttribute = true;
                } else { // getter
-                  if (method.getParameterTypes().length == 0 && method.getReturnType() != java.lang.Void.TYPE) {
+                  if (method.getParameterTypes().length == 0
+                           && method.getReturnType() != java.lang.Void.TYPE) {
                      boolean hasSetter = atts.containsKey(attributeName);
-                     //we found is method
+                     // we found is method
                      if (methodName.startsWith("is")) {
-                        attributeName = (attributeName == null) ? methodName.substring(2) : attributeName;
-                        info = new MBeanAttributeInfo(attributeName,
-                                                      method.getReturnType().getCanonicalName(),
-                                                      attr.description(),
-                                                      true,
-                                                      hasSetter,
-                                                      true);
+                        attributeName = (attributeName == null) ? methodName.substring(2)
+                                 : attributeName;
+                        info = new MBeanAttributeInfo(attributeName, method.getReturnType()
+                                 .getCanonicalName(), attr.description(), true, hasSetter, true);
                      } else {
-                        //this has to be get
-                        attributeName = (attributeName == null) ? methodName.substring(3) : attributeName;
-                        info = new MBeanAttributeInfo(attributeName,
-                                                      method.getReturnType().getCanonicalName(),
-                                                      attr.description(),
-                                                      true,
-                                                      hasSetter,
-                                                      false);
+                        // this has to be get
+                        attributeName = (attributeName == null) ? methodName.substring(3)
+                                 : attributeName;
+                        info = new MBeanAttributeInfo(attributeName, method.getReturnType()
+                                 .getCanonicalName(), attr.description(), true, hasSetter, false);
                      }
                   } else {
                      if (log.isWarnEnabled()) {
                         log.warn("Method " + method.getName()
-                              + " must have a valid return type and zero parameters");
+                                 + " must have a valid return type and zero parameters");
                      }
                      continue;
                   }
                }
 
                AttributeEntry ae = atts.get(attributeName);
-               //is it a read method?
+               // is it a read method?
                if (!writeAttribute) {
-                  //we already have annotated field as read
+                  // we already have annotated field as read
                   if (ae instanceof FieldAttributeEntry && ae.getInfo().isReadable()) {
                      log.warn("not adding annotated method " + method
-                           + " since we already have read attribute");
+                              + " since we already have read attribute");
                   }
-                  //we already have annotated set method
+                  // we already have annotated set method
                   else if (ae instanceof MethodAttributeEntry) {
                      MethodAttributeEntry mae = (MethodAttributeEntry) ae;
                      if (mae.hasSetMethod()) {
-                        atts.put(attributeName,
-                                 new MethodAttributeEntry(mae.getInfo(), mae.getSetMethod(), method));
+                        atts.put(attributeName, new MethodAttributeEntry(mae.getInfo(), mae
+                                 .getSetMethod(), method));
                      }
-                  } //we don't have such entry
+                  } // we don't have such entry
                   else {
                      atts.put(attributeName, new MethodAttributeEntry(info, null, method));
                   }
-               }//is it a set method?
+               }// is it a set method?
                else {
                   if (ae instanceof FieldAttributeEntry) {
-                     //we already have annotated field as write
+                     // we already have annotated field as write
                      if (ae.getInfo().isWritable()) {
                         log.warn("Not adding annotated method " + methodName
-                              + " since we already have writable attribute");
+                                 + " since we already have writable attribute");
                      } else {
-                        //we already have annotated field as read
-                        //lets make the field writable
+                        // we already have annotated field as read
+                        // lets make the field writable
                         Field f = ((FieldAttributeEntry) ae).getField();
-                        MBeanAttributeInfo i = new MBeanAttributeInfo(ae.getInfo().getName(),
-                                                                      f.getType().getCanonicalName(),
-                                                                      attr.description(),
-                                                                      true,
-                                                                      Modifier.isFinal(f.getModifiers()) ? false : true,
-                                                                      false);
+                        MBeanAttributeInfo i = new MBeanAttributeInfo(ae.getInfo().getName(), f
+                                 .getType().getCanonicalName(), attr.description(), true, Modifier
+                                 .isFinal(f.getModifiers()) ? false : true, false);
                         atts.put(attributeName, new FieldAttributeEntry(i, f));
                      }
                   }
-                  //we already have annotated getOrIs method
+                  // we already have annotated getOrIs method
                   else if (ae instanceof MethodAttributeEntry) {
                      MethodAttributeEntry mae = (MethodAttributeEntry) ae;
                      if (mae.hasIsOrGetMethod()) {
-                        atts.put(attributeName,
-                                 new MethodAttributeEntry(info,
-                                                          method,
-                                                          mae.getIsOrGetMethod()));
+                        atts.put(attributeName, new MethodAttributeEntry(info, method, mae
+                                 .getIsOrGetMethod()));
                      }
-                  } //we don't have such entry
+                  } // we don't have such entry
                   else {
                      atts.put(attributeName, new MethodAttributeEntry(info, method, null));
                   }
@@ -365,7 +349,7 @@
             } else if (isIsMethod(method)) {
                attName = attName.substring(2);
             }
-            //expose unless we already exposed matching attribute field
+            // expose unless we already exposed matching attribute field
             boolean isAlreadyExposed = atts.containsKey(attName);
             if (!isAlreadyExposed) {
                ops.add(new MBeanOperationInfo(op != null ? op.description() : "", method));
@@ -375,25 +359,24 @@
    }
 
    private boolean isSetMethod(Method method) {
-      return (method.getName().startsWith("set") &&
-            method.getParameterTypes().length == 1 &&
-            method.getReturnType() == java.lang.Void.TYPE);
+      return (method.getName().startsWith("set") && method.getParameterTypes().length == 1 && method
+               .getReturnType() == java.lang.Void.TYPE);
    }
 
    private boolean isGetMethod(Method method) {
-      return (method.getParameterTypes().length == 0 &&
-            method.getReturnType() != java.lang.Void.TYPE &&
-            method.getName().startsWith("get"));
+      return (method.getParameterTypes().length == 0
+               && method.getReturnType() != java.lang.Void.TYPE && method.getName().startsWith(
+               "get"));
    }
 
    private boolean isIsMethod(Method method) {
-      return (method.getParameterTypes().length == 0 &&
-            (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) &&
-            method.getName().startsWith("is"));
+      return (method.getParameterTypes().length == 0
+               && (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) && method
+               .getName().startsWith("is"));
    }
 
    private void findFields() {
-      //traverse class hierarchy and find all annotated fields
+      // traverse class hierarchy and find all annotated fields
       for (Class<?> clazz = getObject().getClass(); clazz != null; clazz = clazz.getSuperclass()) {
 
          Field[] fields = clazz.getDeclaredFields();
@@ -401,12 +384,9 @@
             ManagedAttribute attr = field.getAnnotation(ManagedAttribute.class);
             if (attr != null) {
                String fieldName = renameToJavaCodingConvention(field.getName());
-               MBeanAttributeInfo info = new MBeanAttributeInfo(fieldName,
-                                                                field.getType().getCanonicalName(),
-                                                                attr.description(),
-                                                                true,
-                                                                Modifier.isFinal(field.getModifiers()) ? false : attr.writable(),
-                                                                false);
+               MBeanAttributeInfo info = new MBeanAttributeInfo(fieldName, field.getType()
+                        .getCanonicalName(), attr.description(), true, Modifier.isFinal(field
+                        .getModifiers()) ? false : attr.writable(), false);
 
                atts.put(fieldName, new FieldAttributeEntry(info, field));
             }
@@ -425,17 +405,11 @@
             try {
                result = new Attribute(name, entry.invoke(null));
                if (log.isDebugEnabled())
-                  log.debug("Attribute " + name
-                        + " has r="
-                        + i.isReadable()
-                        + ",w="
-                        + i.isWritable()
-                        + ",is="
-                        + i.isIs()
-                        + " and value "
-                        + result.getValue());
-            }
-            catch (Exception e) {
+                  log
+                           .debug("Attribute " + name + " has r=" + i.isReadable() + ",w="
+                                    + i.isWritable() + ",is=" + i.isIs() + " and value "
+                                    + result.getValue());
+            } catch (Exception e) {
                log.debug("Exception while reading value of attribute " + name, e);
             }
          } else {
@@ -448,28 +422,24 @@
    private boolean setNamedAttribute(Attribute attribute) {
       boolean result = false;
       if (log.isDebugEnabled())
-         log.debug("Invoking set on attribute " + attribute.getName()
-               + " with value "
-               + attribute.getValue());
+         log.debug("Invoking set on attribute " + attribute.getName() + " with value "
+                  + attribute.getValue());
 
       AttributeEntry entry = atts.get(attribute.getName());
       if (entry != null) {
          try {
             entry.invoke(attribute);
             result = true;
-         }
-         catch (Exception e) {
+         } catch (Exception e) {
             log.warn("Exception while writing value for attribute " + attribute.getName(), e);
          }
       } else {
-         log.warn("Could not invoke set on attribute " + attribute.getName()
-               + " with value "
-               + attribute.getValue());
+         log.warn("Could not invoke set on attribute " + attribute.getName() + " with value "
+                  + attribute.getValue());
       }
       return result;
    }
 
-
    private String renameToJavaCodingConvention(String fieldName) {
       if (fieldName.contains("_")) {
          Pattern p = Pattern.compile("_.");
@@ -501,9 +471,8 @@
 
       final Method setMethod;
 
-      public MethodAttributeEntry(final MBeanAttributeInfo info,
-                                  final Method setMethod,
-                                  final Method isOrGetMethod) {
+      public MethodAttributeEntry(final MBeanAttributeInfo info, final Method setMethod,
+               final Method isOrGetMethod) {
          super();
          this.info = info;
          this.setMethod = setMethod;
@@ -512,9 +481,9 @@
 
       public Object invoke(Attribute a) throws Exception {
          if (a == null && isOrGetmethod != null)
-            return isOrGetmethod.invoke(getObject(), new Object[]{});
+            return isOrGetmethod.invoke(getObject(), new Object[] {});
          else if (a != null && setMethod != null)
-            return setMethod.invoke(getObject(), new Object[]{a.getValue()});
+            return setMethod.invoke(getObject(), new Object[] { a.getValue() });
          else
             return null;
       }

Modified: trunk/core/src/test/java/org/infinispan/jmx/CacheManagerMBeanTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/jmx/CacheManagerMBeanTest.java	2009-09-09 10:41:41 UTC (rev 799)
+++ trunk/core/src/test/java/org/infinispan/jmx/CacheManagerMBeanTest.java	2009-09-09 10:50:49 UTC (rev 800)
@@ -7,8 +7,10 @@
 import org.infinispan.test.fwk.TestCacheManagerFactory;
 import org.testng.annotations.Test;
 
+import javax.management.MBeanException;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+import javax.management.ServiceNotFoundException;
 
 /**
  * Tests whether the attributes defined by DefaultCacheManager work correct.
@@ -63,4 +65,14 @@
       assert attribute.contains("b(");
       assert attribute.contains("c(");
    }
+   
+   public void testInvokeJmxOperationNotExposed() throws Exception {
+      try {
+         server.invoke(name, "stop", new Object[]{}, new String[]{});
+         assert false : "Method not exposed, invocation should have failed";
+      } catch (MBeanException mbe) {
+         assert mbe.getCause() instanceof ServiceNotFoundException;
+      }
+      
+   }
 }



More information about the infinispan-commits mailing list