private Long getFieldTimeValue(Descriptor descriptor, Descriptor mbean, String field) { Logger logger = getLogger(); Object value = descriptor.getFieldValue(field); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Descriptor's " + field + " field: " + value); if (value == null && mbean != null) { value = mbean.getFieldValue(field); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean's " + field + " field: " + value); if (value == null) return null; } if (value instanceof Number) return Long.valueOf(((Number) value).longValue()); if (value instanceof String) { try { long ctl = Long.parseLong((String) value); return Long.valueOf(ctl); } catch (NumberFormatException x) { return Long.valueOf(0); } } return Long.valueOf(0); }
private <T> OpenMBeanParameterInfoSupport( String name, String description, OpenType<T> openType, T defaultValue, T[] legalValues, Comparable<T> minValue, Comparable<T> maxValue) throws OpenDataException { super( name, (openType == null) ? null : openType.getClassName(), description, makeDescriptor(openType, defaultValue, legalValues, minValue, maxValue)); this.openType = openType; Descriptor d = getDescriptor(); this.defaultValue = defaultValue; this.minValue = minValue; this.maxValue = maxValue; // We already converted the array into an unmodifiable Set // in the descriptor. this.legalValues = (Set<?>) d.getFieldValue("legalValues"); check(this); }
// Not in the spec but needed private void removeAttributeChangeNotificationListener( NotificationListener listener, String attributeName, Object handback) throws MBeanException, RuntimeOperationsException, ListenerNotFoundException { if (listener == null) throw new RuntimeOperationsException( new IllegalArgumentException( LocalizedStrings.MX4JModelMBean_LISTENER_CANNOT_BE_NULL.toLocalizedString())); AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter(); if (attributeName != null) { filter.enableAttribute(attributeName); } else { MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes(); for (int i = 0; i < ai.length; i++) { Descriptor d = ((ModelMBeanAttributeInfo) ai[i]).getDescriptor(); filter.enableAttribute((String) d.getFieldValue("name")); } } getAttributeChangeBroadcaster().removeNotificationListener(listener, filter, handback); Logger logger = getLogger(); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug( "Listener " + listener + " for attribute " + attributeName + " removed successfully, handback is " + handback); }
private int getPersistPolicy(Descriptor descriptor, Descriptor mbean) { Logger logger = getLogger(); String persist = (String) descriptor.getFieldValue("persistPolicy"); if (persist == null && mbean != null) persist = (String) mbean.getFieldValue("persistPolicy"); if (persist == null) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("No persist policy defined, assuming Never"); return PERSIST_NEVER; } else { if (persist.equals("Never")) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist never"); return PERSIST_NEVER; } else if (persist.equals("OnUpdate")) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist on update"); return PERSIST_ON_UPDATE; } else if (persist.equals("OnTimer")) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist on update"); return PERSIST_ON_TIMER; } else if (persist.equals("NoMoreOftenThan")) { if (logger.isEnabledFor(Logger.TRACE)) { Long period = getFieldTimeValue(descriptor, mbean, "persistPeriod"); logger.trace("Persist no more often than " + period); } return PERSIST_NO_MORE_OFTEN_THAN; } else { // Garbage, assuming Never if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invalid persist policy, assuming persist never"); return PERSIST_NEVER; } } }
/** * Adds descriptor fields from the <code>ManagedAttribute</code> attribute to the attribute * descriptor. Specifically, adds the <code>currencyTimeLimit</code>, <code>default</code>, <code> * persistPolicy</code> and <code>persistPeriod</code> descriptor fields if they are present in * the metadata. */ protected void populateAttributeDescriptor( Descriptor desc, Method getter, Method setter, String beanKey) { ManagedAttribute gma = (getter == null) ? ManagedAttribute.EMPTY : this.attributeSource.getManagedAttribute(getter); ManagedAttribute sma = (setter == null) ? ManagedAttribute.EMPTY : this.attributeSource.getManagedAttribute(setter); applyCurrencyTimeLimit( desc, resolveIntDescriptor(gma.getCurrencyTimeLimit(), sma.getCurrencyTimeLimit())); Object defaultValue = resolveObjectDescriptor(gma.getDefaultValue(), sma.getDefaultValue()); desc.setField(FIELD_DEFAULT, defaultValue); String persistPolicy = resolveStringDescriptor(gma.getPersistPolicy(), sma.getPersistPolicy()); if (StringUtils.hasLength(persistPolicy)) { desc.setField(FIELD_PERSIST_POLICY, persistPolicy); } int persistPeriod = resolveIntDescriptor(gma.getPersistPeriod(), sma.getPersistPeriod()); if (persistPeriod >= 0) { desc.setField(FIELD_PERSIST_PERIOD, Integer.toString(persistPeriod)); } }
private static void test(Object child, String name, boolean mxbean) throws Exception { final ObjectName childName = new ObjectName("test:type=Child,name=" + name); final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); server.registerMBean(child, childName); try { final MBeanInfo info = server.getMBeanInfo(childName); System.out.println(name + ": " + info.getDescriptor()); final int len = info.getOperations().length; if (len == OPCOUNT) { System.out.println(name + ": OK, only " + OPCOUNT + " operations here..."); } else { final String qual = (len > OPCOUNT) ? "many" : "few"; System.err.println( name + ": Too " + qual + " foos! Found " + len + ", expected " + OPCOUNT); for (MBeanOperationInfo op : info.getOperations()) { System.err.println("public " + op.getReturnType() + " " + op.getName() + "();"); } throw new RuntimeException("Too " + qual + " foos for " + name); } final Descriptor d = info.getDescriptor(); final String mxstr = String.valueOf(d.getFieldValue("mxbean")); final boolean mxb = (mxstr == null) ? false : Boolean.valueOf(mxstr).booleanValue(); System.out.println(name + ": mxbean=" + mxb); if (mxbean && !mxb) throw new AssertionError("MXBean is not OpenMBean?"); for (MBeanOperationInfo mboi : info.getOperations()) { // Sanity check if (mxbean && !mboi.getName().equals("foo")) { // The spec doesn't guarantee that the MBeanOperationInfo // of an MXBean will be an OpenMBeanOperationInfo, and in // some circumstances in our implementation it will not. // However, in thsi tests, for all methods but foo(), // it should. // if (!(mboi instanceof OpenMBeanOperationInfo)) throw new AssertionError("Operation " + mboi.getName() + "() is not Open?"); } final String exp = EXPECTED_TYPES.get(mboi.getName()); // For MXBeans, we need to compare 'exp' with the original // type - because mboi.getReturnType() returns the OpenType // String type = (String) mboi.getDescriptor().getFieldValue("originalType"); if (type == null) type = mboi.getReturnType(); if (type.equals(exp)) continue; System.err.println( "Bad return type for " + mboi.getName() + "! Found " + type + ", expected " + exp); throw new RuntimeException("Bad return type for " + mboi.getName()); } } finally { server.unregisterMBean(childName); } }
public void testAttributeInfoHasDescriptors() throws Exception { ModelMBeanInfo info = getMBeanInfoFromAssembler(); ModelMBeanAttributeInfo attr = info.getAttribute(NAME_ATTRIBUTE); Descriptor desc = attr.getDescriptor(); assertNotNull("getMethod field should not be null", desc.getFieldValue("getMethod")); assertNotNull("setMethod field should not be null", desc.getFieldValue("setMethod")); assertEquals("getMethod field has incorrect value", "getName", desc.getFieldValue("getMethod")); assertEquals("setMethod field has incorrect value", "setName", desc.getFieldValue("setMethod")); }
/* Check that all descriptors have been returned */ private static void checkDescriptors( ModelMBeanInfo modelMBeanInfo, Descriptor[] descriptors, String string) { int errCount = 0; final ArrayList<Descriptor> list = new ArrayList<Descriptor>(descriptors.length); list.addAll(Arrays.asList(descriptors)); System.out.println("Got " + list.size() + " descriptors for " + string); // checks that MBean's descriptor is returned. // final Descriptor mbd = ((MBeanInfo) modelMBeanInfo).getDescriptor(); if (!mbd.equals(remove(list, mbd))) { System.err.println("modelMBeanInfo.getDescriptor(): not found"); errCount++; } // checks that MBean's attributes descriptors are returned. // final MBeanAttributeInfo[] attrs = modelMBeanInfo.getAttributes(); for (MBeanAttributeInfo att : attrs) { final Descriptor ad = att.getDescriptor(); final String name = att.getName(); if (!ad.equals(remove(list, ad))) { System.err.println("attInfo.getDescriptor(): not found for " + name); errCount++; } } // checks that MBean's operations descriptors are returned. // final MBeanOperationInfo[] ops = modelMBeanInfo.getOperations(); for (MBeanOperationInfo op : ops) { final Descriptor od = op.getDescriptor(); final String name = op.getName(); if (!od.equals(remove(list, od))) { System.err.println("opInfo.getDescriptor(): not found for " + name); errCount++; } } // checks that MBean's notifications descriptors are returned. // final MBeanNotificationInfo[] ntfs = modelMBeanInfo.getNotifications(); for (MBeanNotificationInfo ntf : ntfs) { final Descriptor nd = ntf.getDescriptor(); final String name = ntf.getName(); if (!nd.equals(remove(list, nd))) { System.err.println("notifInfo.getDescriptor(): not found for " + name); errCount++; } } if (errCount > 0) { throw new RuntimeException(string + ": failed with " + errCount + " errors"); } else if (list.size() != 0) { // Check that there are no additional descriptors // throw new RuntimeException(string + ": Unexpected remaining descriptors: " + list); } else System.out.println(string + ": PASSED"); }
static <T> Set<T> valuesFrom(Descriptor d, String name, OpenType<T> openType) { Object x = d.getFieldValue(name); if (x == null) return null; Collection<?> coll; if (x instanceof Set<?>) { Set<?> set = (Set<?>) x; boolean asis = true; for (Object element : set) { if (!openType.isValue(element)) { asis = false; break; } } if (asis) return cast(set); coll = set; } else if (x instanceof Object[]) { coll = Arrays.asList((Object[]) x); } else { final String msg = "Descriptor value for " + name + " must be a Set or " + "an array: " + x.getClass().getName(); throw new IllegalArgumentException(msg); } Set<T> result = new HashSet<T>(); for (Object element : coll) result.add(convertFrom(element, openType)); return result; }
static boolean equal(OpenMBeanParameterInfo x1, OpenMBeanParameterInfo x2) { if (x1 instanceof DescriptorRead) { if (!(x2 instanceof DescriptorRead)) return false; Descriptor d1 = ((DescriptorRead) x1).getDescriptor(); Descriptor d2 = ((DescriptorRead) x2).getDescriptor(); if (!d1.equals(d2)) return false; } else if (x2 instanceof DescriptorRead) return false; return x1.getName().equals(x2.getName()) && x1.getOpenType().equals(x2.getOpenType()) && (x1.hasDefaultValue() ? x1.getDefaultValue().equals(x2.getDefaultValue()) : !x2.hasDefaultValue()) && (x1.hasMinValue() ? x1.getMinValue().equals(x2.getMinValue()) : !x2.hasMinValue()) && (x1.hasMaxValue() ? x1.getMaxValue().equals(x2.getMaxValue()) : !x2.hasMaxValue()) && (x1.hasLegalValues() ? x1.getLegalValues().equals(x2.getLegalValues()) : !x2.hasLegalValues()); }
static <T> T valueFrom(Descriptor d, String name, OpenType<T> openType) { Object x = d.getFieldValue(name); if (x == null) return null; try { return convertFrom(x, openType); } catch (Exception e) { final String msg = "Cannot convert descriptor field " + name + " to " + openType.getTypeName(); throw EnvHelp.initCause(new IllegalArgumentException(msg), e); } }
private Object resolveTargetObject(Descriptor descriptor) throws MBeanException { Logger logger = getLogger(); Object target = descriptor.getFieldValue("targetObject"); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("targetObject is: " + target); if (target == null) { target = getManagedResource(); } else { String targetObjectType = (String) descriptor.getFieldValue("targetObjectType"); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("targetObjectType is: " + targetObjectType); if (targetObjectType == null) { // Not defined, assume object reference targetObjectType = OBJECT_RESOURCE_TYPE; } if (!isResourceTypeSupported(targetObjectType)) throw new MBeanException(new InvalidTargetObjectTypeException(targetObjectType)); } return target; }
/** * Adds descriptor fields from the <code>ManagedResource</code> attribute to the MBean descriptor. * Specifically, adds the <code>currencyTimeLimit</code>, <code>persistPolicy</code>, <code> * persistPeriod</code>, <code>persistLocation</code> and <code>persistName</code> descriptor * fields if they are present in the metadata. */ protected void populateMBeanDescriptor(Descriptor desc, Object managedBean, String beanKey) { ManagedResource mr = this.attributeSource.getManagedResource(getClassToExpose(managedBean)); if (mr == null) { throw new InvalidMetadataException( "No ManagedResource attribute found for class: " + getClassToExpose(managedBean)); } applyCurrencyTimeLimit(desc, mr.getCurrencyTimeLimit()); if (mr.isLog()) { desc.setField(FIELD_LOG, "true"); } if (StringUtils.hasLength(mr.getLogFile())) { desc.setField(FIELD_LOG_FILE, mr.getLogFile()); } if (StringUtils.hasLength(mr.getPersistPolicy())) { desc.setField(FIELD_PERSIST_POLICY, mr.getPersistPolicy()); } if (mr.getPersistPeriod() >= 0) { desc.setField(FIELD_PERSIST_PERIOD, Integer.toString(mr.getPersistPeriod())); } if (StringUtils.hasLength(mr.getPersistName())) { desc.setField(FIELD_PERSIST_NAME, mr.getPersistName()); } if (StringUtils.hasLength(mr.getPersistLocation())) { desc.setField(FIELD_PERSIST_LOCATION, mr.getPersistLocation()); } }
private int getStaleness(Descriptor attribute, Descriptor mbean, String lastUpdateField) { Logger logger = getLogger(); Long currencyTimeLimit = getFieldTimeValue(attribute, mbean, "currencyTimeLimit"); if (currencyTimeLimit == null) { // No time limit defined if (logger.isEnabledFor(Logger.TRACE)) logger.trace("No currencyTimeLimit defined, assuming always stale"); return ALWAYS_STALE; } else { long ctl = currencyTimeLimit.longValue() * 1000; if (logger.isEnabledFor(Logger.TRACE)) logger.trace("currencyTimeLimit is (ms): " + ctl); if (ctl == 0) { // Never stale if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Never stale"); return NEVER_STALE; } else if (ctl < 0) // this should be == -1 but the other cases are in the air { // Always stale if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Always stale"); return ALWAYS_STALE; } else { Long timestamp = (Long) attribute.getFieldValue(lastUpdateField); long luts = 0; if (timestamp != null) luts = timestamp.longValue(); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug(lastUpdateField + " is: " + luts); long now = System.currentTimeMillis(); if (now < luts + ctl) { // Seems to be not stale, but has been set at least once ? if (timestamp == null) { // Return stale to call it the first time if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Stale since was never set"); return STALE; } else { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Not stale"); return NOT_STALE; } } else { // Stale if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Stale"); return STALE; } } } }
private boolean shouldPersistNow(Descriptor attribute, Descriptor mbean, String lastUpdateField) { int persist = getPersistPolicy(attribute, mbean); if (persist == PERSIST_NO_MORE_OFTEN_THAN) { Long period = getFieldTimeValue(attribute, mbean, "persistPeriod"); long now = System.currentTimeMillis(); Long lastUpdate = (Long) attribute.getFieldValue(lastUpdateField); if (now - lastUpdate.longValue() < period.longValue()) return false; else return true; } else if (persist == PERSIST_NEVER) { return false; } else if (persist == PERSIST_ON_TIMER) { return false; } else if (persist == PERSIST_ON_UPDATE) { return true; } else { throw new ImplementationException( LocalizedStrings.MX4JModelMBean_INVALID_PERSIST_VALUE.toLocalizedString()); } }
public static final String getTypeName(String rawTypeName, Descriptor typeDescriptor) { String name = rawTypeName; if (name == null) { return null; } Class<?> type = null; try { type = Class.forName(name); } catch (Throwable t) { } if (type != null) { name = type.getCanonicalName(); if ((CompositeData.class.equals(type) || (type.isArray() && CompositeData.class.equals(type.getComponentType()))) && typeDescriptor != null) { String originalTypeName = (String) typeDescriptor.getFieldValue(JMX.ORIGINAL_TYPE_FIELD); if (originalTypeName != null && !originalTypeName.isEmpty()) { Class<?> originalType = null; try { originalType = Class.forName(originalTypeName); } catch (Throwable t) { } if (originalType != null) { name = originalType.getCanonicalName(); } } } } if (name.startsWith(PACKAGE_NAME_JAVA_LANG) && REGEX_PATTERN_PERIOD.split(name).length == 3) { name = name.substring(PACKAGE_NAME_JAVA_LANG.length()); } return name; }
private PersisterMBean findPersister() throws MBeanException, InstanceNotFoundException { Logger logger = getLogger(); ModelMBeanInfo info = getModelMBeanInfo(); if (info == null) { // Not yet initialized if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find persister, ModelMBeanInfo is null"); return null; } Descriptor mbeanDescriptor = info.getMBeanDescriptor(); if (mbeanDescriptor == null) { // This is normally should not happen if ModelMBeanInfoSupport is used if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find persister, MBean descriptor is null"); return null; } String location = (String) mbeanDescriptor.getFieldValue("persistLocation"); String name = (String) mbeanDescriptor.getFieldValue("persistName"); String mbeanName = (String) mbeanDescriptor.getFieldValue("name"); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence fields: location=" + location + ", name=" + name); if (mbeanName == null && name == null) { if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is not supported by this ModelMBean"); return null; } // Try to see if this mbean should delegate to another mbean if (name != null) { try { ObjectName objectName = new ObjectName(name.trim()); // OK, a valid object name MBeanServer server = getMBeanServer(); if (server == null) throw new MBeanException( new IllegalStateException( LocalizedStrings.MX4JModelMBean_MX4JMODELMBEAN_IS_NOT_REGISTERED .toLocalizedString())); if (server.isRegistered(objectName) && server.isInstanceOf(objectName, PersisterMBean.class.getName())) { // OK, the given mbean is registered with this mbean server PersisterMBean persister = new MBeanPersister(server, objectName); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is delegated to this MBean: " + objectName); return persister; } else { throw new InstanceNotFoundException(objectName.toString()); } } catch (MalformedObjectNameException ignored) { // It does not delegates to another mbean, use default if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persistence is not delegated to another MBean"); } // Default is serialization to file FilePersister persister = new FilePersister(location, name); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is realized through file system in " + persister.getFileName()); return persister; } else { // Only location given, use MBean name FilePersister persister = new FilePersister(location, mbeanName); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is realized through file system in " + persister.getFileName()); return persister; } }
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; } }
public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (attribute == null) throw new RuntimeOperationsException( new IllegalArgumentException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_NAME_CANNOT_BE_NULL.toLocalizedString())); Logger logger = getLogger(); // I want the real info, not its clone ModelMBeanInfo info = getModelMBeanInfo(); if (info == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString()); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info); // This is a clone, we use it read only ModelMBeanAttributeInfo attrInfo = info.getAttribute(attribute); if (attrInfo == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANATTRIBUTEINFO_FOR_ATTRIBUTE_0 .toLocalizedString(attribute)); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute info is: " + attrInfo); if (!attrInfo.isReadable()) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_0_IS_NOT_READABLE.toLocalizedString(attribute)); // This returns a clone of the mbean descriptor, we use it read only Descriptor mbeanDescriptor = info.getMBeanDescriptor(); if (mbeanDescriptor == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString()); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor); // This descriptor is a clone Descriptor attributeDescriptor = attrInfo.getDescriptor(); if (attributeDescriptor == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_DESCRIPTOR_FOR_ATTRIBUTE_0_CANNOT_BE_NULL .toLocalizedString(attribute)); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute descriptor is: " + attributeDescriptor); Object returnValue = null; String lastUpdateField = "lastUpdatedTimeStamp"; int staleness = getStaleness(attributeDescriptor, mbeanDescriptor, lastUpdateField); if (staleness == ALWAYS_STALE || staleness == STALE) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Value is stale"); String getter = (String) attributeDescriptor.getFieldValue("getMethod"); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getMethod field is: " + getter); if (getter == null) { // No getter, use default value returnValue = attributeDescriptor.getFieldValue("default"); if (returnValue != null) { // Check if the return type is of the same type // As an extension allow covariant return type Class returned = returnValue.getClass(); Class declared = loadClassWithContextClassLoader(attrInfo.getType()); checkAssignability(returned, declared); } if (logger.isEnabledFor(Logger.DEBUG)) logger.debug( "getAttribute for attribute " + attribute + " returns default value: " + returnValue); } else { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invoking attribute getter..."); // As an extension, allow attributes to be called on target objects also Object target = resolveTargetObject(attributeDescriptor); returnValue = invokeMethod(target, getter, new Class[0], new Object[0]); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Returned value is: " + returnValue); if (returnValue != null) { // Check if the return type is of the same type // As an extension allow covariant return type Class returned = returnValue.getClass(); Class declared = loadClassWithContextClassLoader(attrInfo.getType()); checkAssignability(returned, declared); } // Cache the new value only if caching is needed if (staleness != ALWAYS_STALE) { attributeDescriptor.setField("value", returnValue); attributeDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis())); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Returned value has been cached"); // And now replace the descriptor with the updated clone info.setDescriptor(attributeDescriptor, "attribute"); } if (logger.isEnabledFor(Logger.DEBUG)) logger.debug( "getAttribute for attribute " + attribute + " returns invoked value: " + returnValue); } } else { // Return cached value returnValue = attributeDescriptor.getFieldValue("value"); if (returnValue != null) { // Check if the return type is of the same type // As an extension allow covariant return type Class returned = returnValue.getClass(); Class declared = loadClassWithContextClassLoader(attrInfo.getType()); checkAssignability(returned, declared); } if (logger.isEnabledFor(Logger.DEBUG)) logger.debug( "getAttribute for attribute " + attribute + " returns cached value: " + returnValue); } // Puff, everything went ok return returnValue; }
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { if (attribute == null) throw new RuntimeOperationsException( new IllegalArgumentException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_CANNOT_BE_NULL.toLocalizedString())); Logger logger = getLogger(); // No need to synchronize: I work mostly on clones // I want the real info, not its clone ModelMBeanInfo info = getModelMBeanInfo(); if (info == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString()); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info); String attrName = attribute.getName(); Object attrValue = attribute.getValue(); // This is a clone, we use it read only ModelMBeanAttributeInfo attrInfo = info.getAttribute(attrName); if (attrInfo == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANATTRIBUTEINFO_FOR_ATTRIBUTE_0 .toLocalizedString(attrName)); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute info is: " + attrInfo); if (!attrInfo.isWritable()) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_0_IS_NOT_WRITABLE.toLocalizedString(attrName)); // This returns a clone of the mbean descriptor, we use it read only Descriptor mbeanDescriptor = info.getMBeanDescriptor(); if (mbeanDescriptor == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString()); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor); // This descriptor is a clone Descriptor attributeDescriptor = attrInfo.getDescriptor(); if (attributeDescriptor == null) throw new AttributeNotFoundException( LocalizedStrings.MX4JModelMBean_ATTRIBUTE_DESCRIPTOR_FOR_ATTRIBUTE_0_CANNOT_BE_NULL .toLocalizedString(attrName)); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute descriptor is: " + attributeDescriptor); String lastUpdateField = "lastUpdatedTimeStamp"; Object oldValue = null; try { oldValue = getAttribute(attrName); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Previous value of attribute " + attrName + ": " + oldValue); } catch (Exception x) { if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot get previous value of attribute " + attrName, x); } // Check if setMethod is present String method = (String) attributeDescriptor.getFieldValue("setMethod"); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("setMethod field is: " + method); if (method != null) { Class declared = loadClassWithContextClassLoader(attrInfo.getType()); if (attrValue != null) { Class parameter = attrValue.getClass(); checkAssignability(parameter, declared); } // As an extension, allow attributes to be called on target objects also Object target = resolveTargetObject(attributeDescriptor); invokeMethod(target, method, new Class[] {declared}, new Object[] {attrValue}); // Cache the value only if currencyTimeLimit is not 0, ie it is not always stale int staleness = getStaleness(attributeDescriptor, mbeanDescriptor, lastUpdateField); if (staleness != ALWAYS_STALE) { attributeDescriptor.setField("value", attrValue); attributeDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis())); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Attribute's value has been cached"); } else { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Always stale, avoiding to cache attribute's value"); } } else { if (attrValue != null) { Class parameter = attrValue.getClass(); Class declared = loadClassWithContextClassLoader(attrInfo.getType()); checkAssignability(parameter, declared); } // Always store the value in the descriptor: no setMethod attributeDescriptor.setField("value", attrValue); } // And now replace the descriptor with the updated clone info.setDescriptor(attributeDescriptor, "attribute"); // Send notifications to listeners if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Sending attribute change notifications"); sendAttributeChangeNotification(new Attribute(attrName, oldValue), attribute); // Persist this ModelMBean boolean persistNow = shouldPersistNow(attributeDescriptor, mbeanDescriptor, lastUpdateField); if (persistNow) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persisting this ModelMBean..."); try { store(); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("ModelMBean persisted successfully"); } catch (Exception x) { logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_STORE_MODELMBEAN_AFTER_SETATTRIBUTE, x); if (x instanceof MBeanException) throw (MBeanException) x; else throw new MBeanException(x); } } }
private Logger findLogger(Descriptor descriptor) { Logger logger = getLogger(); if (descriptor == null) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find MBean logger, descriptor is null"); return null; } String log = (String) descriptor.getFieldValue("log"); String location = (String) descriptor.getFieldValue("logFile"); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Log fields: log=" + log + ", file=" + location); if (log == null || !Boolean.valueOf(log).booleanValue()) { if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Logging is not supported by this ModelMBean"); return null; } // Logger is supported, where log to ? if (location == null) { // As an extension, see if the field logMBean has been defined location = (String) descriptor.getFieldValue("logMBean"); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Log fields: mbean=" + location); if (location == null) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Logging is not supported by this ModelMBean"); return null; } // It seems that the user wants to delegate a registered mbean to log try { ObjectName objectName = new ObjectName(location); MBeanServer server = getMBeanServer(); if (server == null) throw new MBeanException( new IllegalStateException( LocalizedStrings.MX4JModelMBean_MX4JMODELMBEAN_IS_NOT_REGISTERED .toLocalizedString())); if (server.isRegistered(objectName)) { MBeanLogger l = new MBeanLogger(server, objectName); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBean log supported by delegating to this MBean: " + objectName); return l; } return null; } catch (MalformedObjectNameException x) { // Ah, was not a correct object name if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Specified logMBean field does not contain a valid ObjectName: " + location); return null; } catch (MBeanException x) { if (logger.isEnabledFor(Logger.DEBUG)) logger.debug( "logMBean field does not specify an MBean that supports logging delegation", x); return null; } } else { // User decided to log to a file if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBean log supported on file system"); return new FileLogger(location); } }
public Object invoke(String method, Object[] arguments, String[] params) throws MBeanException, ReflectionException { if (method == null) throw new RuntimeOperationsException( new IllegalArgumentException( LocalizedStrings.MX4JModelMBean_METHOD_NAME_CANNOT_BE_NULL.toLocalizedString())); if (arguments == null) arguments = new Object[0]; if (params == null) params = new String[0]; Logger logger = getLogger(); // Find operation descriptor ModelMBeanInfo info = getModelMBeanInfo(); if (info == null) throw new MBeanException( new ServiceNotFoundException( LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString())); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info); // This is a clone, we use it read only ModelMBeanOperationInfo operInfo = info.getOperation(method); if (operInfo == null) throw new MBeanException( new ServiceNotFoundException( LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANOPERATIONINFO_FOR_OPERATION_0 .toLocalizedString(method))); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Operation info is: " + operInfo); // This descriptor is a clone Descriptor operationDescriptor = operInfo.getDescriptor(); if (operationDescriptor == null) throw new MBeanException( new ServiceNotFoundException( LocalizedStrings.MX4JModelMBean_OPERATION_DESCRIPTOR_FOR_OPERATION_0_CANNOT_BE_NULL .toLocalizedString(method))); String role = (String) operationDescriptor.getFieldValue("role"); if (role == null || !role.equals("operation")) throw new MBeanException( new ServiceNotFoundException( LocalizedStrings .MX4JModelMBean_OPERATION_DESCRIPTOR_FIELD_ROLE_MUST_BE_OPERATION_NOT_0 .toLocalizedString(role))); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Operation descriptor is: " + operationDescriptor); // This returns a clone of the mbean descriptor, we use it read only Descriptor mbeanDescriptor = info.getMBeanDescriptor(); if (mbeanDescriptor == null) throw new MBeanException( new ServiceNotFoundException( LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString())); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor); Object returnValue = null; String lastUpdateField = "lastReturnedTimeStamp"; // Check if the method should be invoked given the cache settings int staleness = getStaleness(operationDescriptor, mbeanDescriptor, lastUpdateField); if (staleness == ALWAYS_STALE || staleness == STALE) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Value is stale"); // Find parameters classes Class[] parameters = null; try { parameters = Utils.loadClasses(Thread.currentThread().getContextClassLoader(), params); } catch (ClassNotFoundException x) { logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_OPERATIONS_PARAMETER_CLASSES, x); throw new ReflectionException(x); } if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invoking operation..."); // Find target object Object target = resolveTargetObject(operationDescriptor); returnValue = invokeMethod(target, method, parameters, arguments); if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Returned value is: " + returnValue); if (returnValue != null) { Class parameter = returnValue.getClass(); Class declared = loadClassWithContextClassLoader(operInfo.getReturnType()); checkAssignability(parameter, declared); } // Cache the new value only if caching is needed if (staleness != ALWAYS_STALE) { operationDescriptor.setField("lastReturnedValue", returnValue); operationDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis())); if (logger.isEnabledFor(Logger.TRACE)) { logger.trace("Returned value has been cached"); } // And now replace the descriptor with the updated clone info.setDescriptor(operationDescriptor, "operation"); } if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("invoke for operation " + method + " returns invoked value: " + returnValue); } else { // Return cached value returnValue = operationDescriptor.getFieldValue("lastReturnedValue"); if (returnValue != null) { Class parameter = returnValue.getClass(); Class declared = loadClassWithContextClassLoader(operInfo.getReturnType()); checkAssignability(parameter, declared); } if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("invoke for operation " + method + " returns cached value: " + returnValue); } // As an extension, persist this model mbean also after operation invocation, but using only // settings provided in the operation descriptor, without falling back to defaults set in // the MBean descriptor boolean persistNow = shouldPersistNow(operationDescriptor, null, lastUpdateField); int impact = operInfo.getImpact(); if (persistNow && impact != MBeanOperationInfo.INFO) { if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persisting this ModelMBean..."); try { store(); if (logger.isEnabledFor(Logger.TRACE)) logger.trace("ModelMBean persisted successfully"); } catch (Exception x) { logger.error( LocalizedStrings.MX4JModelMBean_CANNOT_STORE_MODELMBEAN_AFTER_OPERATION_INVOCATION, x); if (x instanceof MBeanException) throw (MBeanException) x; else throw new MBeanException(x); } } return returnValue; }