Command Line JMX Client

Command Line Parser: GNUCommandLine

 

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;

public class GNUCommandLine {
	private Options options = new Options();
	private String[] cmdlineArgs = null;
	private CommandLine cmdLine = null;
	private boolean isParsed = false;
 
	public GNUCommandLine(String cmdLineArgs[]) {
		this.cmdlineArgs = cmdLineArgs;
		this.addOption("help", "print this help message", false, false);
	}
 
	/**
	 * Adds an option into the command line parser
	 * @param optionName - the option name
	 * @param description - option description
	 * @param hasArg - if set to true, the option will accept argument: --optionName=value, otherwise, --optionName is a boolean
	 * @param isMandatory - if set to true, the option must be provided.
	 */
	public Option addOption(String optionName, String description, boolean hasArg, boolean isMandatory) {
		return addOption(optionName, null, description, hasArg, isMandatory);
	}
	
	/**
	 * Adds an option into the command line parser
	 * @param optionName - the option name
	 * @param argName - the name for the argument
	 * @param description - option description
	 * @param hasArg - if set to true, the option will accept argument: --optionName=value, otherwise, --optionName is a boolean
	 * @param isMandatory - if set to true, the option must be provided.
	 */
	@SuppressWarnings("static-access")
	public Option addOption(String optionName, String argName, String description, boolean hasArg, boolean isMandatory) {
		OptionBuilder opt = OptionBuilder.withLongOpt(optionName);
		opt = opt.withDescription(description);
		if (hasArg) {
			opt = opt.hasArg();
		}
		if (isMandatory) {
			opt = opt.isRequired();
		}
		if (argName != null) {
			opt = opt.withArgName(argName);
		}
		Option option = opt.create();
		options.addOption(option);
		return option;
	}
	
	/**
	 * Two options form a mutually exclusive option group
	 * @param option1
	 * @param option2
	 * @return
	 */
	public OptionGroup addOptionGroup(Option option1, Option option2) {
		OptionGroup optionGroup = new OptionGroup();
		optionGroup.addOption(option1);
		optionGroup.addOption(option2);
		options.addOptionGroup(optionGroup);
		return optionGroup;
	}
	
	/**
	 * Several options form a mutually exclusive option group
	 * @param optionList
	 * @return
	 */
	public OptionGroup addOptionGroup(List<Option> optionList) {
		OptionGroup optionGroup = new OptionGroup();
		for (Option option : optionList) {
			optionGroup.addOption(option);
		}
		options.addOptionGroup(optionGroup);
		return optionGroup;
	}
	
	/**
	 * Return all options
	 * @return
	 */
	public Options getOptions() {
		return this.options;
	}
 
	private void parse() throws Exception {
		CommandLineParser parser = new GnuParser();
		try {
			this.cmdLine = parser.parse(this.options, this.cmdlineArgs);
		} catch (MissingOptionException e) {
			printUsage();
		}
		this.isParsed = true;
		if (this.cmdLine.hasOption("help")) {
			printUsage();
		}
	}
 
	public void printUsage() {
		HelpFormatter formatter = new HelpFormatter();
		formatter.printHelp("options ", options);
		System.exit(1);
	}
	
	public String getString(String optionName) throws Exception {
		if (!this.isParsed) {
			this.parse();
		}
		return this.cmdLine.getOptionValue(optionName);
	}

	public Integer getInteger(String optionName) throws Exception {
		return Integer.parseInt(this.getString(optionName));
	}

	public Double getDouble(String optionName) throws Exception {
		return Double.parseDouble(this.getString(optionName));
	}
	
	public List<String> getList(String optionName, String delimiter) throws Exception {
		List<String> arrayList = new ArrayList<String>();
		StringTokenizer tkn = new StringTokenizer(this.getString(optionName), delimiter);
		while (tkn.hasMoreTokens()) {
			arrayList.add(tkn.nextToken());
		}
		return arrayList;
	}

	public boolean hasOption(String optionName) throws Exception {
		if (!this.isParsed) {
			this.parse();
		}
		return this.cmdLine.hasOption(optionName);
	}
}

 

JMXClient:

public class JmxClient {
	private static final String OPTION_HOSTNAME = "host-name";
	private static final String OPTION_PORT = "port";
	private static final String OPTION_USER_NAME = "user-name";
	private static final String OPTION_PASSWORD = "password";
	private static final String OPTION_MBEAN_DOMAIN = "mbean-domain";
	private static final String OPTION_MBEAN_NAME = "mbean-name";
	private static final String OPTION_MBEAN_OPERATION = "mbean-operation";

	public static void main(String[] args) {
		GNUCommandLine cli = new GNUCommandLine(args);
		cli.addOption(OPTION_HOSTNAME, "host name of remote mbean server", true, true);
		cli.addOption(OPTION_PORT, "port number of remote mbean server", true, true);
		cli.addOption(OPTION_USER_NAME, "user name for remote jmx connection", true, true);
		cli.addOption(OPTION_PASSWORD, "password for remote jmx connection", true, true);
		cli.addOption(OPTION_MBEAN_DOMAIN, "mbean domain to lookup from remote mbean server", true, true);
		cli.addOption(OPTION_MBEAN_NAME, "mbean name to lookup from remote mbean server", true, true);
		cli.addOption(OPTION_MBEAN_OPERATION, "mbean operation to lookup from remote  mbean server", true, true);
		
		String hostName = null;
		Integer port = null;
		String userName = null;
		String password = null;
		String mBeanDomain = null;
		String mBeanName = null;
		String mBeanOperation = null;
		try {
			hostName = cli.getString(OPTION_HOSTNAME);
			port = cli.getInteger(OPTION_PORT);
			userName = cli.getString(OPTION_USER_NAME);
			password = cli.getString(OPTION_PASSWORD);
			mBeanDomain = cli.getString(OPTION_MBEAN_DOMAIN);
			mBeanName = cli.getString(OPTION_MBEAN_NAME);
			mBeanOperation = cli.getString(OPTION_MBEAN_OPERATION);
		} catch (NumberFormatException e) {
			System.err.println("Number format error. " + e.getMessage());
			System.exit(1);
		} catch (Exception e) {
			System.err.println(e.getMessage());
			System.exit(1);
		}
		
		JmxClientWorker worker = new JmxClientWorker();
		worker.execute(hostName, port, userName, password, mBeanDomain, mBeanName, mBeanOperation);
	}
}

 

JMXClientWorker:

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanException;
import javax.management.MBeanFeatureInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JmxClientWorker {

	public void execute(String hostName, Integer port, String userName, String password, String mBeanDomain, String mBeanName, String mBeanOperation) {
		JMXConnector jmxc = null;
		try {
			JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + port + "/jmxrmi");
			
			Hashtable<String, Object[]> env = new Hashtable<String, Object[]>();
			String[] credentials = new String[]{userName, password};
			env.put(JMXConnector.CREDENTIALS, credentials);
			
			System.out.println("Connecting to server: [" + url + "]");
			 jmxc = JMXConnectorFactory.connect(url, env);
			 MBeanServerConnection mbs = jmxc.getMBeanServerConnection();
			 
			 System.out.println("Invoking operation: [" + mBeanDomain + ":" + mBeanName + " -> " + mBeanOperation + "]");
			 ObjectName objectName = new ObjectName(mBeanDomain + ":name=" + mBeanName);
			 Set<?> beans = mbs.queryMBeans(objectName, null);
			 if (beans.size() == 0) {
				 exit("Not a registered bean -> " + "[" + objectName.getCanonicalName() + "]");
			 } else if (beans.size() > 1) {
				 listOptions(beans);
				 exit("More than one beans are found. Please be more specific");
			 } else {
				 ObjectInstance instance = (ObjectInstance) beans.iterator().next();
				 MBeanOperationInfo[] operationInfos = mbs.getMBeanInfo(instance.getObjectName()).getOperations();
				 MBeanOperationInfo operationInfo = (MBeanOperationInfo) getFeatureInfo(operationInfos, mBeanOperation);
				 if (operationInfo != null) {
					 MBeanParameterInfo[] paramInfos = operationInfo.getSignature();
					 String[] params = getParameters(mBeanOperation);
					 int paramInfosLength = paramInfos != null ? paramInfos.length : 0;
			         int paramsLength = params != null ? params.length : 0;
			         if (paramInfosLength != paramsLength) {
			        	 exit("Parameters count passed doesn't match signature count");
			         } else {
			        	 Object[] paramObjects = paramInfosLength != 0 ? new Object[paramInfosLength] : null;
			        	 String[] signatures = paramInfosLength != 0 ? new String[paramInfosLength] : null;
			        	 for (int i = 0; i < paramInfos.length; i++) {
			        		 MBeanParameterInfo paramInfo = paramInfos[i];
			        		 Constructor<?> c = Class.forName(paramInfo.getType()).getConstructor(new Class[] {
			                         java.lang.String.class });
			        		 paramObjects[i] = c.newInstance(new Object[]{params[i]	});
			        		 signatures[i] = paramInfos[i].getType();
			        	 }
			        	 Object result = mbs.invoke(instance.getObjectName(), operationInfo.getName(), paramObjects, signatures);
			        	 System.out.println("Result: [" + result + "]");
			         }
			         
				 } else {
					 exit("Operation not found: [" + mBeanOperation + "]");
				 }
			 }
		} catch (InstanceNotFoundException e) {
			exit("Failed to find mbean", e);
		} catch (MalformedObjectNameException e) {
			exit("Invalid object name", e);
		} catch (ReflectionException e) {
			exit("No operation found", e);
		} catch (IOException e) {
			exit("Failed to connect to mbean server", e);
		} catch (SecurityException e) {
			exit("Authentication failed", e);
		} catch (IntrospectionException e) {
			exit("Failed to get mbean info", e);
		} catch (NoSuchMethodException e) {
			exit("Method is not found", e);
		} catch (ClassNotFoundException e) {
			exit("Parameter type is not found", e);
		} catch (IllegalArgumentException e) {
			exit("Invalid argument", e);
		} catch (InstantiationException e) {
			exit("Failed to initialize type", e);
		} catch (IllegalAccessException e) {
			exit("Invalid access", e);
		} catch (InvocationTargetException e) {
			exit("Failed to invoke target", e);
		} catch (MBeanException e) {
			exit("MBean exception", e);
		} finally {
			if (jmxc != null) {
				try {
					jmxc.close();
				} catch (IOException e) {
					exit("Failed to close JMXConnectorFactory" + e.getMessage());
				}
			}
		}
		
		System.out.println("Executed: [" + mBeanOperation + "]");
	}
	
	private void exit (String message) {
		System.err.println(message);
		System.exit(1);
	}
	
	private void exit (String message, Throwable e) {
		while (e.getCause() != null) {
			e = e.getCause();
		}
		System.err.println("Failed to execute operation, reason: [" + message + " -> " +  e.getMessage() + "]");
		System.exit(1);
	}
	
	private MBeanFeatureInfo getFeatureInfo(MBeanFeatureInfo infos[], String mBeanOperation) {
		 int index = mBeanOperation.indexOf('=');
	     String name = index <= 0 ? mBeanOperation : mBeanOperation.substring(0, index);
	     for(int i = 0; i < infos.length; i++) {
	            if(infos[i].getName().equals(name)) {
	                return infos[i];
	            }
	     }
	     return null;
	}
	
	private String[] getParameters (String mBeanOperation) {
		 int index = mBeanOperation.indexOf('=');
		 if (index <=0) {
			 return null;
		 } else {
			 return mBeanOperation.substring(index).split(",");
		 }
	}
	
	private void listOptions(Set<?> beans) {
		for (Iterator<?> iter = beans.iterator(); iter.hasNext();) {
			 Object obj = iter.next();
			 if (obj instanceof ObjectName) {
				 System.out.println(((ObjectName) obj).getCanonicalName());
			 } else if (obj instanceof ObjectInstance) {
				 System.out.println(((ObjectInstance) obj).getObjectName().getCanonicalName());
			 } else {
				 System.err.println("Unexpected object type: " + obj.toString());
			 }
		 }
	}

}

 

你可能感兴趣的:(command)