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); }
/** * Compare this MBeanParameterInfo to another. * * @param o the object to compare to. * @return true if and only if <code>o</code> is an MBeanParameterInfo such that its {@link * #getName()}, {@link #getType()}, {@link #getDescriptor()}, and {@link #getDescription()} * values are equal (not necessarily identical) to those of this MBeanParameterInfo. */ public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof MBeanParameterInfo)) return false; MBeanParameterInfo p = (MBeanParameterInfo) o; return (Objects.equals(p.getName(), getName()) && Objects.equals(p.getType(), getType()) && Objects.equals(p.getDescription(), getDescription()) && Objects.equals(p.getDescriptor(), getDescriptor())); }
/** * Tests correct MBean interface. * * @throws Exception Thrown if test fails. */ public void testCorrectMBeanInfo() throws Exception { StandardMBean mbean = new IgniteStandardMXBean(new GridMBeanImplementation(), GridMBeanInterface.class); MBeanInfo info = mbean.getMBeanInfo(); assert info.getDescription().equals("MBeanDescription.") == true; assert info.getOperations().length == 2; for (MBeanOperationInfo opInfo : info.getOperations()) { if (opInfo.getDescription().equals("MBeanOperation.")) assert opInfo.getSignature().length == 2; else { assert opInfo.getDescription().equals("MBeanSuperOperation.") == true; assert opInfo.getSignature().length == 1; } } for (MBeanParameterInfo paramInfo : info.getOperations()[0].getSignature()) { if (paramInfo.getName().equals("ignored")) assert paramInfo.getDescription().equals("MBeanOperationParameter1.") == true; else { assert paramInfo.getName().equals("someData") == true; assert paramInfo.getDescription().equals("MBeanOperationParameter2.") == true; } } assert info.getAttributes().length == 4 : "Expected 4 attributes but got " + info.getAttributes().length; for (MBeanAttributeInfo attrInfo : info.getAttributes()) { if (attrInfo.isWritable() == false) { assert (attrInfo.getDescription().equals("MBeanReadonlyGetter.") == true || attrInfo.getDescription().equals("MBeanROGetter.")); } else { assert (attrInfo.getDescription().equals("MBeanWritableGetter.") == true || attrInfo.getDescription().equals("MBeanWritableIsGetter.")); } } }
/** * Description of the operation. * * @param operation the operation to describe * @return pretty-printed description */ protected String describeOperation(MBeanOperationInfo operation) { StringBuilder buf = new StringBuilder(); buf.append(operation.getReturnType()).append(" ").append(operation.getName()).append("("); MBeanParameterInfo[] params = operation.getSignature(); for (int j = 0; j < params.length; j++) { MBeanParameterInfo param = params[j]; if (j != 0) { buf.append(", "); } buf.append(param.getType()).append(" ").append(param.getName()); } buf.append(")"); return buf.toString(); }
@Override protected Object handleRequestMessage(Message<?> requestMessage) { ObjectName objectName = this.resolveObjectName(requestMessage); String operationName = this.resolveOperationName(requestMessage); Map<String, Object> paramsFromMessage = this.resolveParameters(requestMessage); try { MBeanInfo mbeanInfo = this.server.getMBeanInfo(objectName); MBeanOperationInfo[] opInfoArray = mbeanInfo.getOperations(); boolean hasNoArgOption = false; for (MBeanOperationInfo opInfo : opInfoArray) { if (operationName.equals(opInfo.getName())) { MBeanParameterInfo[] paramInfoArray = opInfo.getSignature(); if (paramInfoArray.length == 0) { hasNoArgOption = true; } if (paramInfoArray.length == paramsFromMessage.size()) { int index = 0; Object values[] = new Object[paramInfoArray.length]; String signature[] = new String[paramInfoArray.length]; for (MBeanParameterInfo paramInfo : paramInfoArray) { Object value = paramsFromMessage.get(paramInfo.getName()); if (value == null) { /* * With Spring 3.2.3 and greater, the parameter names are * registered instead of the JVM's default p1, p2 etc. * Fall back to that naming style if not found. */ value = paramsFromMessage.get("p" + (index + 1)); } if (value != null && valueTypeMatchesParameterType(value, paramInfo)) { values[index] = value; signature[index] = paramInfo.getType(); index++; } } if (index == paramInfoArray.length) { return this.server.invoke(objectName, operationName, values, signature); } } } } if (hasNoArgOption) { return this.server.invoke(objectName, operationName, null, null); } throw new MessagingException( requestMessage, "failed to find JMX operation '" + operationName + "' on MBean [" + objectName + "] of type [" + mbeanInfo.getClassName() + "] with " + paramsFromMessage.size() + " parameters: " + paramsFromMessage); } catch (JMException e) { throw new MessageHandlingException( requestMessage, "failed to invoke JMX operation '" + operationName + "' on MBean [" + objectName + "]" + " with " + paramsFromMessage.size() + " parameters: " + paramsFromMessage, e); } catch (IOException e) { throw new MessageHandlingException(requestMessage, "IOException on MBeanServerConnection", e); } }