protected Result describeMbean( @Nonnull MBeanServerConnection mbeanServer, @Nonnull ObjectName objectName) throws IntrospectionException, ReflectionException, InstanceNotFoundException, IOException { MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(objectName); StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter(sw); out.println("# MBEAN"); out.println(objectName.toString()); out.println(); out.println("## OPERATIONS"); List<MBeanOperationInfo> operations = Arrays.asList(mbeanInfo.getOperations()); Collections.sort( operations, new Comparator<MBeanOperationInfo>() { @Override public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) { return o1.getName().compareTo(o1.getName()); } }); for (MBeanOperationInfo opInfo : operations) { out.print("* " + opInfo.getName() + "("); MBeanParameterInfo[] signature = opInfo.getSignature(); for (int i = 0; i < signature.length; i++) { MBeanParameterInfo paramInfo = signature[i]; out.print(paramInfo.getType() + " " + paramInfo.getName()); if (i < signature.length - 1) { out.print(", "); } } out.print("):" + opInfo.getReturnType() /* + " - " + opInfo.getDescription() */); out.println(); } out.println(); out.println("## ATTRIBUTES"); List<MBeanAttributeInfo> attributes = Arrays.asList(mbeanInfo.getAttributes()); Collections.sort( attributes, new Comparator<MBeanAttributeInfo>() { @Override public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2) { return o1.getName().compareTo(o2.getName()); } }); for (MBeanAttributeInfo attrInfo : attributes) { out.println( "* " + attrInfo.getName() + ": " + attrInfo.getType() + " - " + (attrInfo.isReadable() ? "r" : "") + (attrInfo.isWritable() ? "w" : "") /* + " - " + attrInfo.getDescription() */); } String description = sw.getBuffer().toString(); return new Result(objectName, description, description); }
public GroovyMBean(MBeanServerConnection server, ObjectName name, boolean ignoreErrors) throws JMException, IOException { this.server = server; this.name = name; this.ignoreErrors = ignoreErrors; this.beanInfo = server.getMBeanInfo(name); MBeanOperationInfo[] operationInfos = beanInfo.getOperations(); for (MBeanOperationInfo info : operationInfos) { String signature[] = createSignature(info); // Construct a simplistic key to support overloaded operations on the MBean. String operationKey = createOperationKey(info.getName(), signature.length); operations.put(operationKey, signature); } }
@Nullable public Result invokeOperation( @Nonnull MBeanServerConnection mBeanServer, @Nonnull ObjectName on, @Nonnull String operationName, @Nonnull String... arguments) throws JMException, IOException { logger.debug("invokeOperation({},{}, {}, {})...", on, operationName, Arrays.asList(arguments)); MBeanInfo mbeanInfo = mBeanServer.getMBeanInfo(on); List<MBeanOperationInfo> candidates = new ArrayList<MBeanOperationInfo>(); for (MBeanOperationInfo mbeanOperationInfo : mbeanInfo.getOperations()) { if (mbeanOperationInfo.getName().equals(operationName) && mbeanOperationInfo.getSignature().length == arguments.length) { candidates.add(mbeanOperationInfo); logger.debug("Select matching operation {}", mbeanOperationInfo); } else { logger.trace("Ignore non matching operation {}", mbeanOperationInfo); } } if (candidates.isEmpty()) { throw new IllegalArgumentException( "Operation '" + operationName + "(" + Strings2.join(arguments, ", ") + ")' NOT found on " + on); } else if (candidates.size() > 1) { throw new IllegalArgumentException( "More than 1 (" + candidates.size() + ") operation '" + operationName + "(" + Strings2.join(arguments, ", ") + ")' found on '" + on + "': " + candidates); } MBeanOperationInfo beanOperationInfo = candidates.get(0); MBeanParameterInfo[] mbeanParameterInfos = beanOperationInfo.getSignature(); List<String> signature = new ArrayList<String>(); for (MBeanParameterInfo mbeanParameterInfo : mbeanParameterInfos) { signature.add(mbeanParameterInfo.getType()); } Object[] convertedArguments = convertValues(arguments, signature); logger.debug("Invoke {}:{}({}) ...", on, operationName, Arrays.asList(convertedArguments)); Object result = mBeanServer.invoke(on, operationName, convertedArguments, signature.toArray(new String[0])); if ("void".equals(beanOperationInfo.getReturnType()) && result == null) { result = "void"; } logger.info( "Invoke {}:{}({}): {}", on, operationName, Arrays.asList(convertedArguments), result); String description = "Invoke operation " + on + ":" + operationName + "(" + Strings2.join(convertedArguments, ", ") + "): " + Strings2.toString(result); return new Result(on, result, description); }
/** * @param mbeanServer * @param objectName * @param attributeName * @param attributeValue if <code>null</code>, this is a read access. * @return if this is a read access, the returned value (may be null); if it is a write access, * return <code>void.class</code>. * @throws IOException * @throws JMException */ public Result invokeAttribute( @Nonnull MBeanServerConnection mbeanServer, @Nonnull ObjectName objectName, @Nonnull String attributeName, @Nullable String attributeValue) throws IOException, JMException { MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(objectName); MBeanAttributeInfo attributeInfo = null; for (MBeanAttributeInfo mai : mbeanInfo.getAttributes()) { if (mai.getName().equals(attributeName)) { attributeInfo = mai; break; } } if (attributeInfo == null) { throw new IllegalArgumentException( "No attribute '" + attributeName + "' found on '" + objectName + "'. Existing attributes: " + Arrays.asList(mbeanInfo.getAttributes())); } String description; Object resultValue; if (attributeValue == null) { if (attributeInfo.isReadable()) { Object attribute = mbeanServer.getAttribute(objectName, attributeName); logger.info("get attribute value {}:{}:{}", objectName, attributeName, attribute); resultValue = attribute; description = "Get attribute value " + objectName + ":" + attributeName + ": " + resultValue; } else { throw new IllegalArgumentException( "Attribute '" + attributeName + "' is not readable on '" + objectName + "': " + attributeInfo); } } else { if (attributeInfo.isWritable()) { Object value = convertValue(attributeValue, attributeInfo.getType()); mbeanServer.setAttribute(objectName, new Attribute(attributeName, value)); logger.info("set attribute value {}:{}:{}", objectName, attributeName, value); description = "Set attribute value " + objectName + ":" + attributeName + ": " + value; resultValue = void.class; } else { throw new IllegalArgumentException( "Attribute '" + attributeName + "' is not writable on '" + objectName + "': " + attributeInfo); } } return new Result(objectName, resultValue, description); }
private static boolean test(String proto, MBeanServer mbs, ObjectName on) throws Exception { System.out.println("Testing for protocol " + proto); JMXConnectorServer cs; JMXServiceURL url = new JMXServiceURL(proto, null, 0); try { cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); } catch (MalformedURLException e) { System.out.println("System does not recognize URL: " + url + "; ignoring"); return true; } cs.start(); JMXServiceURL addr = cs.getAddress(); JMXConnector client = JMXConnectorFactory.connect(addr); MBeanServerConnection mbsc = client.getMBeanServerConnection(); Object getAttributeExotic = mbsc.getAttribute(on, "Exotic"); AttributeList getAttrs = mbsc.getAttributes(on, new String[] {"Exotic"}); AttributeList setAttrs = new AttributeList(); setAttrs.add(new Attribute("Exotic", new Exotic())); setAttrs = mbsc.setAttributes(on, setAttrs); Object invokeExotic = mbsc.invoke(on, "anExotic", new Object[] {}, new String[] {}); MBeanInfo exoticMBI = mbsc.getMBeanInfo(on); mbsc.setAttribute(on, new Attribute("Exception", Boolean.TRUE)); Exception getAttributeException, setAttributeException, invokeException; try { try { mbsc.getAttribute(on, "Exotic"); throw noException("getAttribute"); } catch (Exception e) { getAttributeException = e; } try { mbsc.setAttribute(on, new Attribute("Exotic", new Exotic())); throw noException("setAttribute"); } catch (Exception e) { setAttributeException = e; } try { mbsc.invoke(on, "anExotic", new Object[] {}, new String[] {}); throw noException("invoke"); } catch (Exception e) { invokeException = e; } } finally { mbsc.setAttribute(on, new Attribute("Exception", Boolean.FALSE)); } client.close(); cs.stop(); boolean ok = true; ok &= checkAttrs("getAttributes", getAttrs); ok &= checkAttrs("setAttributes", setAttrs); ok &= checkType("getAttribute", getAttributeExotic, Exotic.class); ok &= checkType("getAttributes", attrValue(getAttrs), Exotic.class); ok &= checkType("setAttributes", attrValue(setAttrs), Exotic.class); ok &= checkType("invoke", invokeExotic, Exotic.class); ok &= checkType("getMBeanInfo", exoticMBI, ExoticMBeanInfo.class); ok &= checkExceptionType("getAttribute", getAttributeException, ExoticException.class); ok &= checkExceptionType("setAttribute", setAttributeException, ExoticException.class); ok &= checkExceptionType("invoke", invokeException, ExoticException.class); if (ok) System.out.println("Test passes for protocol " + proto); return ok; }