org.jumpmind.symmetric.JmxCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.jumpmind.symmetric.JmxCommand.java

Source

/**
 * Licensed to JumpMind Inc under one or more contributor
 * license agreements.  See the NOTICE file distributed
 * with this work for additional information regarding
 * copyright ownership.  JumpMind Inc licenses this file
 * to you under the GNU General Public License, version 3.0 (GPLv3)
 * (the "License"); you may not use this file except in compliance
 * with the License.
 *
 * You should have received a copy of the GNU General Public License,
 * version 3.0 (GPLv3) along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jumpmind.symmetric;

import static org.apache.commons.lang.StringUtils.isBlank;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.jumpmind.properties.TypedProperties;
import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.io.data.CsvUtils;

public class JmxCommand extends AbstractCommandLauncher {

    private static final String OPTION_LISTBEANS = "listbeans";
    private static final String OPTION_LISTMETHODS = "listmethods";
    private static final String OPTION_BEAN = "bean";
    private static final String OPTION_METHOD = "method";
    private static final String OPTION_ARGS = "args";
    private static final String OPTION_ARGS_DELIM = "args-delimiter";

    public JmxCommand() {
        super("jmx", "", "Jmx.Option.");
    }

    public static void main(String[] args) {
        new JmxCommand().execute(args);
    }

    @Override
    protected void printHelp(CommandLine cmd, Options options) {
        System.out.println(app + " version " + Version.version());
        System.out.println("Provides a command line interface to execute JMX methods for a specific engine");
        super.printHelp(cmd, options);
    }

    @Override
    protected void buildOptions(Options options) {
        super.buildOptions(options);
        addOption(options, null, OPTION_LISTBEANS, false);
        addOption(options, null, OPTION_LISTMETHODS, false);
        addOption(options, null, OPTION_BEAN, true);
        addOption(options, null, OPTION_METHOD, true);
        addOption(options, null, OPTION_ARGS, true);
        addOption(options, null, OPTION_ARGS_DELIM, true);

    }

    @Override
    protected boolean printHelpIfNoOptionsAreProvided() {
        return true;
    }

    @Override
    protected boolean requiresPropertiesFile() {
        return true;
    }

    @Override
    protected boolean executeWithOptions(final CommandLine line) throws Exception {
        if (line.hasOption(OPTION_LISTBEANS)) {
            execute(new IJmxTemplate<Object>() {
                @Override
                public Object execute(String engineName, MBeanServerConnection mbeanConn) throws Exception {
                    Set<ObjectName> beanSet = mbeanConn.queryNames(null, null);
                    for (ObjectName objectName : beanSet) {
                        if (objectName.getDomain().startsWith("org.jumpmind.symmetric." + engineName)) {
                            System.out.println(objectName.toString());
                        }
                    }
                    return null;
                }
            });
        } else if (line.hasOption(OPTION_LISTMETHODS) || line.hasOption(OPTION_METHOD)) {
            if (line.hasOption(OPTION_BEAN)) {

                execute(new IJmxTemplate<Object>() {
                    @Override
                    public Object execute(String engineName, MBeanServerConnection mbeanConn) throws Exception {
                        String beanName = line.getOptionValue(OPTION_BEAN);
                        MBeanInfo info = mbeanConn.getMBeanInfo(new ObjectName(beanName));
                        if (info != null) {
                            if (line.hasOption(OPTION_LISTMETHODS)) {
                                MBeanOperationInfo[] operations = info.getOperations();
                                Map<String, MBeanOperationInfo> orderedMap = new TreeMap<String, MBeanOperationInfo>();
                                for (MBeanOperationInfo methodInfo : operations) {
                                    orderedMap.put(methodInfo.getName(), methodInfo);
                                }
                                for (MBeanOperationInfo methodInfo : orderedMap.values()) {
                                    System.out.print(methodInfo.getName() + "(");
                                    MBeanParameterInfo[] params = methodInfo.getSignature();
                                    int index = 0;
                                    for (MBeanParameterInfo p : params) {
                                        if (index > 0) {
                                            System.out.print(", ");
                                        }
                                        System.out.print(p.getType() + " " + p.getName());
                                        index++;
                                    }
                                    System.out.print(")");
                                    if (methodInfo.getReturnType() != null
                                            && !methodInfo.getReturnType().equals("void")) {
                                        System.out.print(" : " + methodInfo.getReturnType());
                                    }
                                    System.out.println();
                                }
                            } else if (line.hasOption(OPTION_METHOD)) {
                                String argsDelimiter = line.getOptionValue(OPTION_ARGS_DELIM);
                                if (isBlank(argsDelimiter)) {
                                    argsDelimiter = ",";
                                } else {
                                    argsDelimiter = argsDelimiter.trim();
                                }
                                String methodName = line.getOptionValue(OPTION_METHOD);
                                String[] args = null;
                                if (line.hasOption(OPTION_ARGS)) {
                                    String argLine = line.getOptionValue(OPTION_ARGS);
                                    args = argsDelimiter == "," ? CsvUtils.tokenizeCsvData(argLine)
                                            : argLine.split(argsDelimiter);
                                    ;
                                } else {
                                    args = new String[0];
                                }

                                MBeanOperationInfo[] operations = info.getOperations();
                                for (MBeanOperationInfo methodInfo : operations) {
                                    MBeanParameterInfo[] paramInfos = methodInfo.getSignature();
                                    if (methodInfo.getName().equals(methodName)
                                            && paramInfos.length == args.length) {
                                        String[] signature = new String[args.length];
                                        Object[] objArgs = new Object[args.length];
                                        int index = 0;
                                        for (MBeanParameterInfo paramInfo : paramInfos) {
                                            signature[index] = paramInfo.getType();
                                            if (!paramInfo.getType().equals(String.class.getName())) {
                                                Class<?> clazz = Class.forName(paramInfo.getType());
                                                Constructor<?> constructor = clazz.getConstructor(String.class);
                                                objArgs[index] = constructor.newInstance(args[index]);
                                            } else {
                                                objArgs[index] = args[index];
                                            }
                                            index++;
                                        }
                                        Object returnValue = mbeanConn.invoke(new ObjectName(beanName), methodName,
                                                objArgs, signature);
                                        if (methodInfo.getReturnType() != null
                                                && !methodInfo.getReturnType().equals("void")) {
                                            System.out.println(returnValue);
                                        }
                                        System.exit(0);
                                    }
                                }

                                System.out.println("ERROR: Could not locate a JMX method named: " + methodName
                                        + " with " + args.length + " arguments on bean: " + beanName);
                                System.exit(1);

                                return null;

                            }
                        } else {
                            System.out.println("ERROR: Could not locate a JMX bean with the name of: " + beanName);
                            System.exit(1);
                        }
                        return null;
                    }
                });
            } else {
                System.out.println("ERROR: Must specifiy the --bean option.");
                System.exit(1);
            }
        } else {
            return false;
        }

        return true;
    }

    protected <T> T execute(IJmxTemplate<T> template) throws Exception {
        String host = "localhost";
        String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + System.getProperty("jmx.agent.port", "31418")
                + "/jmxrmi";
        JMXServiceURL serviceUrl = new JMXServiceURL(url);
        JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
        TypedProperties properties = getTypedProperties();
        String engineName = properties.get(ParameterConstants.ENGINE_NAME, "unknown");
        try {
            MBeanServerConnection mbeanConn = jmxConnector.getMBeanServerConnection();
            return template.execute(engineName, mbeanConn);
        } finally {
            jmxConnector.close();
        }
    }

    interface IJmxTemplate<T> {
        public T execute(String engineName, MBeanServerConnection mbeanConn) throws Exception;
    }

}