001package crash.commands.base;
002
003import org.crsh.cli.Argument;
004import org.crsh.cli.Command;
005import org.crsh.cli.Option;
006import org.crsh.cli.Usage;
007import org.crsh.command.BaseCommand;
008import org.crsh.command.InvocationContext;
009import org.crsh.command.PipeCommand;
010import org.crsh.command.ScriptException;
011
012import javax.management.JMException;
013import javax.management.MBeanAttributeInfo;
014import javax.management.MBeanInfo;
015import javax.management.MBeanServer;
016import javax.management.ObjectInstance;
017import javax.management.ObjectName;
018import java.io.IOException;
019import java.lang.management.ManagementFactory;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025/** @author Julien Viet */
026@Usage("Java Management Extensions")
027public class jmx extends BaseCommand {
028
029  @Usage("find mbeans")
030  @Command
031  public void find(
032      InvocationContext<ObjectName> context,
033      @Usage("The object name pattern")
034      @Option(names = {"p", "pattern"})
035      String pattern) throws Exception {
036
037    //
038    ObjectName patternName = pattern != null ? ObjectName.getInstance(pattern) : null;
039    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
040    Set<ObjectInstance> instances = server.queryMBeans(patternName, null);
041    for (ObjectInstance instance : instances) {
042      context.provide(instance.getObjectName());
043    }
044/*
045    if (context.piped) {
046    } else {
047      UIBuilder ui = new UIBuilder()
048      ui.table(columns: [1,3]) {
049        row(bold: true, fg: black, bg: white) {
050          label("CLASS NAME"); label("OBJECT NAME")
051        }
052        instances.each { instance ->
053          row() {
054            label(foreground: red, instance.getClassName()); label(instance.objectName)
055          }
056        }
057      }
058      out << ui;
059    }
060*/
061  }
062
063  @Command
064  @Usage("return the attributes info of an MBean")
065  public void attributes(InvocationContext<Map> context, @Argument ObjectName name) throws IOException {
066    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
067    try {
068      MBeanInfo info = server.getMBeanInfo(name);
069      for (MBeanAttributeInfo attributeInfo : info.getAttributes()) {
070        HashMap<String, Object> tuple = new HashMap<String, Object>();
071        tuple.put("name", attributeInfo.getName());
072        tuple.put("type", attributeInfo.getType());
073        tuple.put("description", attributeInfo.getDescription());
074        context.provide(tuple);
075      }
076    }
077    catch (JMException e) {
078      throw new ScriptException("Could not access MBean meta data", e);
079    }
080  }
081
082  @Usage("get attributes of an MBean")
083  @Command
084  public PipeCommand<ObjectName, Map> get(@Argument final List<String> attributes) {
085
086    // Determine common attributes from all names
087    if (attributes == null || attributes.isEmpty()) {
088      throw new ScriptException("Must provide JMX attributes");
089    }
090
091    //
092    return new PipeCommand<ObjectName, Map>() {
093
094      /** . */
095      private MBeanServer server;
096
097      @Override
098      public void open() throws ScriptException {
099        server = ManagementFactory.getPlatformMBeanServer();
100      }
101
102      @Override
103      public void provide(ObjectName name) throws IOException {
104        try {
105          HashMap<String, Object> tuple = new HashMap<String, Object>();
106          for (String attribute : attributes) {
107            String prop = name.getKeyProperty(attribute);
108            if (prop != null) {
109              tuple.put(attribute, prop);
110            }
111            else {
112              tuple.put(attribute, server.getAttribute(name, attribute));
113            }
114          }
115          context.provide(tuple);
116        }
117        catch (JMException ignore) {
118          //
119        }
120      }
121    };
122  }
123}