/** * Define an attribute. Explicit definition of an attribute. Reflection is used to locate the * actual getter and setter methods. * * @param attrInfo ModelMBeanAttributeInfo. */ public synchronized void defineAttribute(ModelMBeanAttributeInfo attrInfo) { if (_object == null) throw new IllegalStateException("No Object"); _dirty = true; String name = attrInfo.getName(); String uName = name.substring(0, 1).toUpperCase() + name.substring(1); Class oClass = _object.getClass(); try { Class type = TypeUtil.fromName(attrInfo.getType()); if (type == null) type = Thread.currentThread().getContextClassLoader().loadClass(attrInfo.getType()); Method getter = null; Method setter = null; if (attrInfo.isReadable()) getter = oClass.getMethod((attrInfo.isIs() ? "is" : "get") + uName, (java.lang.Class[]) null); if (attrInfo.isWritable()) setter = oClass.getMethod("set" + uName, new Class[] {type}); _getter.put(name, getter); _setter.put(name, setter); _attributes.add(attrInfo); } catch (Exception e) { log.warn(LogSupport.EXCEPTION, e); throw new IllegalArgumentException(e.toString()); } }
/** * Define an operation. Explicit definition of an operation. Reflection is used to locate method * called. * * @param opInfo */ public synchronized void defineOperation(ModelMBeanOperationInfo opInfo) { _dirty = true; Class oClass = _object.getClass(); try { MBeanParameterInfo[] pInfo = opInfo.getSignature(); Class[] types = new Class[pInfo.length]; String method = opInfo.getName() + "("; for (int i = 0; i < pInfo.length; i++) { Class type = TypeUtil.fromName(pInfo[i].getType()); if (type == null) type = Thread.currentThread().getContextClassLoader().loadClass(pInfo[i].getType()); types[i] = type; method += (i > 0 ? "," : "") + pInfo[i].getType(); } method += ")"; _method.put(method, oClass.getMethod(opInfo.getName(), types)); _operations.add(opInfo); } catch (Exception e) { log.warn(LogSupport.EXCEPTION, e); throw new IllegalArgumentException(e.toString()); } }
/** * Create MBean for Object. Attempts to create an MBean for the object by searching the package * and class name space. For example an object of the type * * <PRE> * class com.acme.MyClass extends com.acme.util.BaseClass * </PRE> * * Then this method would look for the following classes: * * <UL> * <LI>com.acme.MyClassMBean * <LI>com.acme.jmx.MyClassMBean * <LI>com.acme.util.BaseClassMBean * <LI>com.acme.util.jmx.BaseClassMBean * </UL> * * @param o The object * @return A new instance of an MBean for the object or null. */ public static ModelMBean mbeanFor(Object o) { try { Class oClass = o.getClass(); ClassLoader loader = oClass.getClassLoader(); ModelMBean mbean = null; boolean jmx = false; Class[] interfaces = null; int i = 0; while (mbean == null && oClass != null) { Class focus = interfaces == null ? oClass : interfaces[i]; String pName = focus.getPackage().getName(); String cName = focus.getName().substring(pName.length() + 1); String mName = pName + (jmx ? ".jmx." : ".") + cName + "MBean"; try { Class mClass = loader.loadClass(mName); if (log.isTraceEnabled()) log.trace("mbeanFor " + o + " mClass=" + mClass); mbean = (ModelMBean) mClass.newInstance(); mbean.setManagedResource(o, "objectReference"); if (log.isDebugEnabled()) log.debug("mbeanFor " + o + " is " + mbean); return mbean; } catch (ClassNotFoundException e) { if (e.toString().endsWith("MBean")) { if (log.isTraceEnabled()) log.trace(e.toString()); } else log.warn(LogSupport.EXCEPTION, e); } catch (Error e) { log.warn(LogSupport.EXCEPTION, e); mbean = null; } catch (Exception e) { log.warn(LogSupport.EXCEPTION, e); mbean = null; } if (jmx) { if (interfaces != null) { i++; if (i >= interfaces.length) { interfaces = null; oClass = oClass.getSuperclass(); } } else { interfaces = oClass.getInterfaces(); i = 0; if (interfaces == null || interfaces.length == 0) { interfaces = null; oClass = oClass.getSuperclass(); } } } jmx = !jmx; } } catch (Exception e) { LogSupport.ignore(log, e); } return null; }
/* Find MBean descriptions. * MBean descriptions are searched for in ResourceBundles. Bundles * are looked for in a mbean.property files within each package of * the MBean class inheritance hierachy. * Once a bundle is found, the key is added to object names in the * following order: fully qualied managed resource class name, tail * managed resource class name, tail mbean class name. The string * "MBean" is stripped from the tail of any name. * <P>For example, if the class a.b.C is managed by a MBean * p.q.RMBean which is derived from p.SMBean, then the seach order * for a key x is as follows:<PRE> * bundle: p.q.mbean name: a.b.C.x * bundle: p.q.mbean name: C.x * bundle: p.q.mbean name: R.x * bundle: p.mbean name: a.b.C.x * bundle: p.mbean name: C.x * bundle: p.mbean name: S.x * </PRE> * <P>The convention used for keys passed to this method are:<PRE> * null or empty - Object description * xxx - Attribute xxx description * xxx() - Simple operation xxx description * xxx(type,..) - Operation xxx with signature desciption * xxx(type,..)[n] - Param n of operation xxx description * </PRE> * @param key * @return Description string. */ private String findDescription(String key) { Class lookIn = this.getClass(); // Array of possible objectNames String[] objectNames = new String[3]; objectNames[0] = _object.getClass().getName(); if (objectNames[0].indexOf(".") >= 0) objectNames[1] = objectNames[0].substring(objectNames[0].lastIndexOf(".") + 1); while (lookIn != null) { String pkg = lookIn.getName(); int lastDot = pkg.lastIndexOf("."); if (lastDot > 0) { objectNames[2] = pkg.substring(lastDot + 1); pkg = pkg.substring(0, lastDot); } else { objectNames[2] = pkg; pkg = null; } String resource = (pkg == null ? "mbean" : (pkg.replace('.', '/') + "/mbean")); if (log.isTraceEnabled()) log.trace("Look for: " + resource); try { ResourceBundle bundle = ResourceBundle.getBundle( resource, Locale.getDefault(), _object.getClass().getClassLoader()); if (log.isTraceEnabled()) log.trace("Bundle " + resource); for (int i = 0; i < objectNames.length; i++) { String name = objectNames[i]; if (name == null) continue; if (name.endsWith("MBean")) name = name.substring(0, name.length() - 5); if (key != null && key.length() > 0) name += "." + key; try { String description = bundle.getString(name); if (description != null && description.length() > 0) return description; } catch (Exception e) { if (log.isTraceEnabled()) log.trace(e.toString()); } } } catch (Exception e) { if (log.isTraceEnabled()) log.trace(e.toString()); } lookIn = lookIn.getSuperclass(); } if (key == null || key.length() == 0) return objectNames[0]; return key; }
/** * Define an attribute on the managed object. The meta data is defined by looking for standard * getter and setter methods. Descriptions are obtained with a call to findDescription with the * attribute name. * * @param name The name of the attribute. Normal java bean capitlization is enforced on this name. * @param writable If false, do not look for a setter. * @param onMBean . */ public synchronized void defineAttribute(String name, boolean writable, boolean onMBean) { _dirty = true; String uName = name.substring(0, 1).toUpperCase() + name.substring(1); name = java.beans.Introspector.decapitalize(name); Class oClass = onMBean ? this.getClass() : _object.getClass(); Class type = null; Method getter = null; Method setter = null; Method[] methods = oClass.getMethods(); for (int m = 0; m < methods.length; m++) { if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0) continue; // Look for a getter if (methods[m].getName().equals("get" + uName) && methods[m].getParameterTypes().length == 0) { if (getter != null) throw new IllegalArgumentException("Multiple getters for attr " + name); getter = methods[m]; if (type != null && !type.equals(methods[m].getReturnType())) throw new IllegalArgumentException("Type conflict for attr " + name); type = methods[m].getReturnType(); } // Look for an is getter if (methods[m].getName().equals("is" + uName) && methods[m].getParameterTypes().length == 0) { if (getter != null) throw new IllegalArgumentException("Multiple getters for attr " + name); getter = methods[m]; if (type != null && !type.equals(methods[m].getReturnType())) throw new IllegalArgumentException("Type conflict for attr " + name); type = methods[m].getReturnType(); } // look for a setter if (writable && methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1) { if (setter != null) throw new IllegalArgumentException("Multiple setters for attr " + name); setter = methods[m]; if (type != null && !type.equals(methods[m].getParameterTypes()[0])) throw new IllegalArgumentException("Type conflict for attr " + name); type = methods[m].getParameterTypes()[0]; } } if (getter == null && setter == null) throw new IllegalArgumentException("No getter or setters found for " + name); try { // Remember the methods _getter.put(name, getter); _setter.put(name, setter); // create and add the info _attributes.add(new ModelMBeanAttributeInfo(name, findDescription(name), getter, setter)); } catch (Exception e) { log.warn(LogSupport.EXCEPTION, e); throw new IllegalArgumentException(e.toString()); } }
/** * Define an operation on the managed object. Defines an operation with parameters. Refection is * used to determine find the method and it's return type. The description of the method is found * with a call to findDescription on "name(signature)". The name and description of each parameter * is found with a call to findDescription with "name(partialSignature", the returned description * is for the last parameter of the partial signature and is assumed to start with the parameter * name, followed by a colon. * * @param name The name of the method call. * @param signature The types of the operation parameters. * @param impact Impact as defined in MBeanOperationInfo * @param onMBean true if the operation is defined on the mbean */ public synchronized void defineOperation( String name, String[] signature, int impact, boolean onMBean) { _dirty = true; Class oClass = onMBean ? this.getClass() : _object.getClass(); if (signature == null) signature = new String[0]; try { Class[] types = new Class[signature.length]; MBeanParameterInfo[] pInfo = new MBeanParameterInfo[signature.length]; // Check types and build methodKey String methodKey = name + "("; for (int i = 0; i < signature.length; i++) { Class type = TypeUtil.fromName(signature[i]); if (type == null) type = Thread.currentThread().getContextClassLoader().loadClass(signature[i]); types[i] = type; signature[i] = type.isPrimitive() ? TypeUtil.toName(type) : signature[i]; methodKey += (i > 0 ? "," : "") + signature[i]; } methodKey += ")"; // Build param infos for (int i = 0; i < signature.length; i++) { String description = findDescription(methodKey + "[" + i + "]"); int colon = description.indexOf(":"); if (colon < 0) { description = "param" + i + ":" + description; colon = description.indexOf(":"); } pInfo[i] = new MBeanParameterInfo( description.substring(0, colon).trim(), signature[i], description.substring(colon + 1).trim()); } // build the operation info Method method = oClass.getMethod(name, types); Class returnClass = method.getReturnType(); _method.put(methodKey, method); _operations.add( new ModelMBeanOperationInfo( name, findDescription(methodKey), pInfo, returnClass.isPrimitive() ? TypeUtil.toName(returnClass) : (returnClass.getName()), impact)); } catch (Exception e) { log.warn("operation " + name, e); throw new IllegalArgumentException(e.toString()); } }
private static void test(int testno) throws Exception { // com.sun.jmx.trace.TraceImplementation.init(2); Resource resource = new Resource(); Class resourceClass = Resource.class; Class rmmbClass = RequiredModelMBean.class; Method setManagedResource = rmmbClass.getMethod("setManagedResource", new Class[] {Object.class, String.class}); Method sendNotification = rmmbClass.getMethod("sendNotification", new Class[] {Notification.class}); Method addAttributeChangeNL = rmmbClass.getMethod( "addAttributeChangeNotificationListener", new Class[] {NotificationListener.class, String.class, Object.class}); Method getArray = resourceClass.getMethod("getArray", new Class[0]); Method getNumber = resourceClass.getMethod("getNumber", new Class[0]); Method setNumber = resourceClass.getMethod("setNumber", new Class[] {Integer.TYPE}); Method tweakArray = resourceClass.getMethod("tweakArray", new Class[] {Object[].class}); Method addOne = resourceClass.getMethod("addOne", new Class[] {Integer.TYPE}); MBeanServer mbs = MBeanServerFactory.newMBeanServer(); ObjectName on = new ObjectName("a:b=c"); Descriptor attrDescr = new DescriptorSupport(); attrDescr.setField("name", "Array"); attrDescr.setField("descriptorType", "attribute"); attrDescr.setField("getMethod", "getArray"); ModelMBeanAttributeInfo attrInfo = new ModelMBeanAttributeInfo("Array", "array attr", getArray, null, attrDescr); Descriptor attrDescr2 = new DescriptorSupport(); attrDescr2.setField("name", "Number"); attrDescr2.setField("descriptorType", "attribute"); attrDescr2.setField("getMethod", "getNumber"); attrDescr2.setField("setMethod", "setNumber"); ModelMBeanAttributeInfo attrInfo2 = new ModelMBeanAttributeInfo("Number", "number attr", getNumber, setNumber, attrDescr2); Descriptor attrDescr3 = new DescriptorSupport(); attrDescr3.setField("name", "Local"); attrDescr3.setField("descriptorType", "attribute"); attrDescr3.setField("currencyTimeLimit", "" + Integer.MAX_VALUE); ModelMBeanAttributeInfo attrInfo3 = new ModelMBeanAttributeInfo( "Local", "java.lang.String", "local attr", true, true, false, attrDescr3); Descriptor attrDescr4 = new DescriptorSupport(); attrDescr4.setField("name", "Local2"); attrDescr4.setField("descriptorType", "attribute"); ModelMBeanAttributeInfo attrInfo4 = new ModelMBeanAttributeInfo( "Local2", "java.lang.String", "local attr 2", true, true, false, attrDescr4); ModelMBeanAttributeInfo[] attrs = new ModelMBeanAttributeInfo[] {attrInfo, attrInfo2, attrInfo3, attrInfo4}; ModelMBeanOperationInfo operInfo = new ModelMBeanOperationInfo("getArray descr", getArray); ModelMBeanOperationInfo operInfo2 = new ModelMBeanOperationInfo("getNumber descr", getNumber); ModelMBeanOperationInfo operInfo3 = new ModelMBeanOperationInfo("addOne descr", addOne); ModelMBeanOperationInfo operInfo4 = new ModelMBeanOperationInfo("setNumber descr", setNumber); ModelMBeanOperationInfo operInfo5 = new ModelMBeanOperationInfo("tweakArray descr", tweakArray); ModelMBeanOperationInfo operInfoSetManagedResource = new ModelMBeanOperationInfo("setManagedResource descr", setManagedResource); ModelMBeanOperationInfo operInfoSendNotification = new ModelMBeanOperationInfo("sendNotification descr", sendNotification); ModelMBeanOperationInfo operInfoAddAttributeChangeNL = new ModelMBeanOperationInfo("AddAttributeChangeNL descr", addAttributeChangeNL); ModelMBeanOperationInfo[] opers = new ModelMBeanOperationInfo[] { operInfo, operInfo2, operInfo3, operInfo4, operInfo5, operInfoSetManagedResource, operInfoSendNotification, operInfoAddAttributeChangeNL }; ModelMBeanInfo info = new ModelMBeanInfoSupport( Resource.class.getName(), "Resourcish resource", attrs, null, opers, null, null); mbs.createMBean( RequiredModelMBean.class.getName(), on, new Object[] {info}, new String[] {ModelMBeanInfo.class.getName()}); mbs.invoke( on, "setManagedResource", new Object[] {resource, "objectReference"}, new String[] {"java.lang.Object", "java.lang.String"}); switch (testno) { case 0: { /* Check getDescriptors("") on original MBeanInfo */ final Descriptor[] desc = info.getDescriptors(""); checkDescriptors(info, desc, "info.getDescriptors(\"\")"); break; } case 1: { /* Check getDescriptors(null) on original MBeanInfo */ final Descriptor[] desc = info.getDescriptors(null); checkDescriptors(info, desc, "info.getDescriptors(null)"); break; } case 2: { /* Check getDescriptors("") on retrieved MBeanInfo */ final MBeanInfo mbi = mbs.getMBeanInfo(on); final ModelMBeanInfo model = (ModelMBeanInfo) mbi; final Descriptor[] desc = model.getDescriptors(""); checkDescriptors(info, desc, "model.getDescriptors(\"\")"); break; } case 3: { /* Check getDescriptors(null) on retrieved MBeanInfo */ final MBeanInfo mbi = mbs.getMBeanInfo(on); final ModelMBeanInfo model = (ModelMBeanInfo) mbi; final Descriptor[] desc = model.getDescriptors(null); checkDescriptors(info, desc, "model.getDescriptors(null)"); break; } default: System.err.println("UNKNOWN TEST NUMBER " + testno); break; } }
/** * Getting all the alerts in the NMS Alert table and using the alerts, forming the array of * CompositeData.Using the CompositeData forming the TabularData and returning the TabularData */ TabularData getTable() { if (!agentName.initAlert()) return null; TabularData td = null; OpenMBeanParameterInfo[] parameterInfo = new OpenMBeanParameterInfo[names.length]; String returnType = null; try { Class entryClassName = Class.forName(instrClassName); for (int i = 0; i < names.length; i++) { String methodName = "get" + names[i]; // No I18N Method method = entryClassName.getMethod(methodName, null); returnType = method.getReturnType().getName(); parameterInfo[i] = new OpenMBeanParameterInfo(names[i], returnType, null, null, null); } } catch (Exception e) { agentName.agentErr.fail("Exception in getTable(): ", e); // No I18N return null; } try { int numalerts = agentName.alertAPI.getTotalAlertCount(); CompositeData[] comps = new CompositeData[numalerts]; int count = 0; Alert alert = null; String entity = ""; // No I18N String ownerName = ""; // No I18N while (true) { if (alert == null) { try { /** * getting the oldest/first alert in the database which has the least recent mod time */ alert = agentName.alertAPI.getOldestModifiedAlert(); } catch (Exception e) { agentName.agentErr.fail("exception ", e); // No I18N } } else { try { entity = alert.getEntity(); ownerName = alert.getOwnerName(); /** getting the next alert from the database using the modified time as criteria */ if (ownerName != null) alert = agentName.alertAPI.getNextAlertBasedOnModtime( entity + "\t" + ownerName); // No I18N else alert = agentName.alertAPI.getNextAlertBasedOnModtime(entity); } catch (Exception e) { agentName.agentErr.fail("exception", e); // No I18N } } if (alert == null) break; comps[count++] = makeComData(alert); if (count == numalerts) break; } // end of while TabularParameterInfo tinfo = new TabularParameterInfo(null, null, null, null, null, parameterInfo, indexNames); td = new TabularData(tinfo, comps); } catch (Exception e) { agentName.agentErr.fail(" Exception in getTable(): ", e); // No I18N } return td; } // end of getTable