private Object invokeAttribute(PropertyDescriptor pd, MethodInvocation invocation)
      throws JMException, IOException {

    String attributeName = JmxUtils.getAttributeName(pd, this.useStrictCasing);
    MBeanAttributeInfo inf = (MBeanAttributeInfo) this.allowedAttributes.get(attributeName);

    // If no attribute is returned, we know that it is not defined in the
    // management interface.
    if (inf == null) {
      throw new InvalidInvocationException(
          "Attribute '" + pd.getName() + "' is not exposed on the management interface");
    }
    if (invocation.getMethod().equals(pd.getReadMethod())) {
      if (inf.isReadable()) {
        return this.server.getAttribute(this.objectName, attributeName);
      } else {
        throw new InvalidInvocationException("Attribute '" + attributeName + "' is not readable");
      }
    } else if (invocation.getMethod().equals(pd.getWriteMethod())) {
      if (inf.isWritable()) {
        server.setAttribute(
            this.objectName, new Attribute(attributeName, invocation.getArguments()[0]));
        return null;
      } else {
        throw new InvalidInvocationException("Attribute '" + attributeName + "' is not writable");
      }
    } else {
      throw new IllegalStateException(
          "Method [" + invocation.getMethod() + "] is neither a bean property getter nor a setter");
    }
  }
  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);
  }
示例#3
0
 /**
  * Description of the specified attribute name.
  *
  * @param attr - the attribute
  * @return String the description
  */
 protected String describeAttribute(MBeanAttributeInfo attr) {
   StringBuilder buf = new StringBuilder();
   buf.append("(");
   if (attr.isReadable()) {
     buf.append("r");
   }
   if (attr.isWritable()) {
     buf.append("w");
   }
   buf.append(") ").append(attr.getType()).append(" ").append(attr.getName());
   return buf.toString();
 }
  public Object getPropertyValue(Object id) {
    if ("name".equals(id)) { // $NON-NLS-1$
      return attrInfo.getName();
    }
    if ("description".equals(id)) { // $NON-NLS-1$
      return attrInfo.getDescription();
    }
    if ("type".equals(id)) { // $NON-NLS-1$
      Object obj = attrInfo.getType();
      if (obj instanceof Object[]) {
        return Arrays.asList((Object[]) obj).toString();
      }
      return obj;
    }
    if ("readable".equals(id)) { // $NON-NLS-1$
      return Boolean.valueOf(attrInfo.isReadable());
    }
    if ("writable".equals(id)) { // $NON-NLS-1$
      return Boolean.valueOf(attrInfo.isWritable());
    }
    if ("value".equals(id)) { // $NON-NLS-1$
      try {
        if (mbsc != null) {
          Object obj = mbsc.getAttribute(on, attrInfo.getName());
          if (obj instanceof Object[]) {
            return Arrays.asList((Object[]) obj).toString();
          }
          return obj;
        } else {
          conn.run(
              new IJMXRunnable() {
                final Object[] ret = new Object[1];

                @Override
                public void run(MBeanServerConnection connection) throws Exception {
                  Object obj = connection.getAttribute(on, attrInfo.getName());
                  if (obj instanceof Object[]) {
                    ret[0] = Arrays.asList((Object[]) obj).toString();
                  }
                  ret[0] = obj;
                }
              });
        }
      } catch (Exception e) {
        JMXUIActivator.log(
            IStatus.WARNING, NLS.bind(Messages.MBeanAttributeValue_Warning, attrInfo.getName()), e);
        return null;
      }
    }
    return null;
  }
示例#5
0
 private String getType(String attName, boolean read, boolean write) {
   boolean allowed = true;
   if (attributes.containsKey(attName)) {
     MBeanAttributeInfo temp = (MBeanAttributeInfo) attributes.get(attName);
     if (read) {
       if (!temp.isReadable()) allowed = false;
     }
     if (write) {
       if (!temp.isWritable()) allowed = false;
     }
     if (!allowed) return null;
     else return temp.getType();
   } else return null;
 }
示例#6
0
  /**
   * Exports all the numeric attributes of beans matching the supplied MXBean name pattern. Also,
   * discovers the numeric properties of the attributes of type CompositeData and registers them as
   * well.
   *
   * @param beanNamePattern the bean name pattern used to discover the beans.
   * @see javax.management.ObjectName for bean name pattern syntax
   * @see java.lang.management for the list of java platform mbeans
   * @throws JMException if there are errors querying MBeans or information on them
   */
  public void exportNumericAttributes(ObjectName beanNamePattern) throws JMException {
    MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
    Set<ObjectName> beanNames = beanServer.queryNames(beanNamePattern, null);

    // Iterate through all beans and register their numeric properties with Stats
    for (ObjectName beanName : beanNames) {
      MBeanInfo beanInfo = beanServer.getMBeanInfo(beanName);

      // Iterate through all bean attributes
      for (MBeanAttributeInfo attributeInfo : beanInfo.getAttributes()) {
        if (attributeInfo.isReadable()) {
          // Figure out the open type for the attribute
          OpenType<?> openType = null;
          if (attributeInfo instanceof OpenMBeanAttributeInfo) {
            openType = ((OpenMBeanAttributeInfo) attributeInfo).getOpenType();
          } else {
            // Sometimes the open mbean info is available in the descriptor
            Object obj = attributeInfo.getDescriptor().getFieldValue("openType");
            if (obj != null && obj instanceof OpenType) {
              openType = (OpenType) obj;
            }
          }
          // once the open type is found, figure out if it's a numeric or composite type
          if (openType != null) {
            if (NUMERIC_TYPES.contains(openType)) {
              // numeric attribute types are registered with callbacks that simply
              // return their value
              addStatIfMatches(
                  getStatName(beanName, attributeInfo.getName()),
                  new MBeanLongAttributeFetcher(beanServer, beanName, attributeInfo.getName()));
            } else if (openType instanceof CompositeType) {
              // for composite types, we figure out which properties of the composite type
              // are numeric and register callbacks to fetch those composite type attributes
              CompositeType compositeType = (CompositeType) openType;

              for (String key : compositeType.keySet()) {
                if (NUMERIC_TYPES.contains(compositeType.getType(key))) {
                  addStatIfMatches(
                      getStatName(beanName, attributeInfo.getName(), key),
                      new MBeanLongCompositeValueFetcher(
                          beanServer, beanName, attributeInfo.getName(), key));
                }
              }
            }
          }
        }
      }
    }
  }
  @Test(dataProvider = "fixtures")
  public void testGetterAttributeInfo(
      String attribute, boolean isIs, Object[] values, Class<?> clazz) throws Exception {
    String methodName = "set" + attribute.replace(".", "");
    for (T t : objects) {
      String attributeName = toFeatureName(attribute, t);
      SimpleInterface simpleInterface = toSimpleInterface(t);
      Method setter = getMethod(simpleInterface.getClass(), methodName, clazz);

      MBeanInfo info = getMBeanInfo(t);
      MBeanAttributeInfo attributeInfo = getAttributeInfo(info, attributeName);
      assertNotNull(attributeInfo, "AttributeInfo for " + attributeName);
      assertEquals(attributeInfo.getName(), attributeName, "Attribute Name for " + attributeName);
      assertEquals(
          attributeInfo.getType(),
          setter.getParameterTypes()[0].getName(),
          "Attribute type for " + attributeName);
      assertEquals(attributeInfo.isIs(), isIs, "Attribute isIs for " + attributeName);
      assertTrue(attributeInfo.isReadable(), "Attribute Readable for " + attributeName);
      assertFalse(attributeInfo.isWritable(), "Attribute Writable for " + attributeName);
    }
  }
  /**
   * @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 MBeanAttributeInfo[] createMBeanAttributeInfo(
      MBeanMetaData metadata, MBeanDescription description) {
    Logger logger = getLogger();

    HashMap attributes = new HashMap();
    HashMap getterNames = new HashMap();

    Method[] methods = metadata.management.getMethods();
    for (int j = 0; j < methods.length; ++j) {
      Method method = methods[j];
      if (Utils.isAttributeGetter(method)) {
        String name = method.getName();
        boolean isIs = name.startsWith("is");

        String attribute = null;
        if (isIs) attribute = name.substring(2);
        else attribute = name.substring(3);

        String descr = description == null ? null : description.getAttributeDescription(attribute);

        MBeanAttributeInfo info = (MBeanAttributeInfo) attributes.get(attribute);

        if (info != null) {
          // JMX spec does not allow overloading attributes.
          // If an attribute with the same name already exists the MBean is not compliant
          if (!info.getType().equals(method.getReturnType().getName())) {
            if (logger.isEnabledFor(Logger.DEBUG))
              logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
            return null;
          } else {
            // They return the same value,
            if (getterNames.get(name) != null) {
              // This is the case of an attribute being present in multiple interfaces
              // Ignore all but the first, since they resolve to the same method anyways
              continue;
            }

            // there is a chance that one is a get-getter and one is a is-getter
            // for a boolean attribute. In this case, the MBean is not compliant.
            if (info.isReadable()) {
              if (logger.isEnabledFor(Logger.DEBUG))
                logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
              return null;
            }

            // MBeanAttributeInfo is already present due to a setter method, just update its
            // readability
            info =
                new MBeanAttributeInfo(
                    attribute,
                    info.getType(),
                    info.getDescription(),
                    true,
                    info.isWritable(),
                    isIs);
          }
        } else {
          info =
              new MBeanAttributeInfo(
                  attribute, method.getReturnType().getName(), descr, true, false, isIs);
        }

        // Replace if exists
        attributes.put(attribute, info);
        getterNames.put(name, method);
      } else if (Utils.isAttributeSetter(method)) {
        String name = method.getName();
        String attribute = name.substring(3);

        String descr = description == null ? null : description.getAttributeDescription(attribute);

        MBeanAttributeInfo info = (MBeanAttributeInfo) attributes.get(attribute);

        if (info != null) {
          // JMX spec does not allow overloading attributes.
          // If an attribute with the same name already exists the MBean is not compliant
          if (!info.getType().equals(method.getParameterTypes()[0].getName())) {
            if (logger.isEnabledFor(Logger.DEBUG))
              logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
            return null;
          } else {
            // MBeanAttributeInfo is already present due to a getter method, just update its
            // writability
            info =
                new MBeanAttributeInfo(
                    info.getName(),
                    info.getType(),
                    info.getDescription(),
                    info.isReadable(),
                    true,
                    info.isIs());
          }
        } else {
          info =
              new MBeanAttributeInfo(
                  attribute, method.getParameterTypes()[0].getName(), descr, false, true, false);
        }

        // Replace if exists
        attributes.put(attribute, info);
      }
    }

    return (MBeanAttributeInfo[])
        attributes.values().toArray(new MBeanAttributeInfo[attributes.size()]);
  }
 private void assertNickName(MBeanAttributeInfo attr) {
   assertNotNull("Nick Name should not be null", attr);
   assertTrue("Nick Name should be writable", attr.isWritable());
   assertTrue("Nick Name should be readable", attr.isReadable());
 }
  private void renderJsonDomain(
      final PrintWriter pw,
      final ObjectName objectName,
      final MBeanInfo mBeanInfo,
      boolean renderDetails)
      throws IOException, AttributeNotFoundException, InstanceNotFoundException {
    pw.write("{");
    jsonKey(pw, "mbean");
    // using toString to make shure that type is set before any other
    // property
    String canonicalName = objectName.toString();
    String[] split = canonicalName.split(":");
    jsonValue(pw, split[1]);

    if (renderDetails) {
      pw.write(',');
      jsonKey(pw, "attributes");
      pw.write("[{");

      final MBeanAttributeInfo[] attrs = mBeanInfo.getAttributes();
      for (int i = 0; i < attrs.length; i++) {
        final MBeanAttributeInfo attr = attrs[i];
        if (!attr.isReadable()) continue; // skip non readable properties
        // jsonValue(pw, attr.getName() + ":writable=" +
        // attr.isWritable());
        jsonKey(pw, attr.getName());
        pw.write("[");
        jsonValue(pw, "writable=" + attr.isWritable());
        Object value = null;
        try {
          // Descriptor descriptor = attr.getDescriptor();
          // descriptor.get
          value = (mBeanServer.getAttribute(objectName, attr.getName()));
        } catch (ReflectionException e) {
          // Munch skip this attribute then
        } catch (MBeanException e) {
          // Munch skip this attribute then
        } catch (RuntimeMBeanException e) {
          // Munch skip this attribute then
        }
        if (value != null) {
          pw.write(",");
          if (!value.getClass().isArray()) {
            jsonValue(pw, "value=" + value.toString());
          } else {
            jsonValue(pw, "value=" + Arrays.toString((Object[]) value));
          }
        }
        pw.write("]");
        if (i < attrs.length) {
          pw.write(',');
        }
      }
      pw.write("}]");
      pw.write(',');
      jsonKey(pw, "operations");
      pw.write("[");
      final MBeanOperationInfo[] ops = mBeanInfo.getOperations();
      for (int i = 0; i < ops.length; i++) {
        final MBeanOperationInfo op = ops[i];
        // jsonValue(pw, op.getDescription() + ": " + op.getName() +
        // " - "
        // + op.getReturnType());
        jsonValue(pw, op.getName());
        if (i < ops.length) {
          pw.write(',');
        }
      }
      pw.write("]");
    }
    pw.write("},");
  }