gobblin.cli.Cli.java Source code

Java tutorial

Introduction

Here is the source code for gobblin.cli.Cli.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 gobblin.cli;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import com.google.common.collect.ImmutableMap;

/**
 * A command line interface for interacting with Gobblin.
 * From this tool, you should be able to:
 *  * Check the status of Gobblin jobs
 *  * View ...
 *
 * @author ahollenbach@nerdwallet.com
 */
public class Cli {
    private static final Map<String, Command> commandList = ImmutableMap.of("jobs", (Command) new JobCommand());

    static class GlobalOptions {
        private final String adminServerHost;
        private final int adminServerPort;

        public GlobalOptions(String adminServerHost, int adminServerPort) {
            this.adminServerHost = adminServerHost;
            this.adminServerPort = adminServerPort;
        }

        public String getAdminServerHost() {
            return adminServerHost;
        }

        public int getAdminServerPort() {
            return adminServerPort;
        }
    }

    /**
     * Get the list of valid command names
     * @return List of command names
     */
    public static Collection<String> getCommandNames() {
        return commandList.keySet();
    }

    // Option long codes
    private static final String HOST_OPT = "host";
    private static final String PORT_OPT = "port";

    private static final String DEFAULT_REST_SERVER_HOST = "localhost";
    private static final int DEFAULT_REST_SERVER_PORT = 8080;

    private String[] args;
    private Options options;

    public static void main(String[] args) {
        Cli cli = new Cli(args);
        cli.parseAndExecuteCommand();
    }

    /**
     * Create a new Cli object.
     * @param args Command line arguments
       */
    public Cli(String[] args) {
        this.args = args;

        this.options = new Options();

        this.options.addOption("H", HOST_OPT, true, "Specify host (default:" + DEFAULT_REST_SERVER_HOST + ")");
        this.options.addOption("P", PORT_OPT, true, "Specify port (default:" + DEFAULT_REST_SERVER_PORT + ")");
    }

    /**
     * Parse and execute the appropriate command based on the args.
     * The general flow looks like this:
     *
     * 1. Parse a set of global options (eg host/port for the admin server)
     * 2. Parse out the command name
     * 3. Pass the global options and any left over parameters to a command handler
     */
    public void parseAndExecuteCommand() {
        CommandLineParser parser = new DefaultParser();
        try {
            CommandLine parsedOpts = parser.parse(this.options, this.args, true);
            GlobalOptions globalOptions = createGlobalOptions(parsedOpts);

            // Fetch the command and fail if there is ambiguity
            String[] remainingArgs = parsedOpts.getArgs();
            if (remainingArgs.length == 0) {
                printHelpAndExit("Command not specified!");
            }

            String commandName = remainingArgs[0].toLowerCase();
            remainingArgs = remainingArgs.length > 1 ? Arrays.copyOfRange(remainingArgs, 1, remainingArgs.length)
                    : new String[] {};

            Command command = commandList.get(commandName);
            if (command == null) {
                System.out.println("Command " + commandName + " not known.");
                printHelpAndExit();
            } else {
                command.execute(globalOptions, remainingArgs);
            }
        } catch (ParseException e) {
            printHelpAndExit("Ran into an error parsing args.");
        }
    }

    /**
     * Build the GlobalOptions information from the raw parsed options
     * @param parsedOpts Options parsed from the cmd line
     * @return
       */
    private GlobalOptions createGlobalOptions(CommandLine parsedOpts) {
        String host = parsedOpts.hasOption(HOST_OPT) ? parsedOpts.getOptionValue(HOST_OPT)
                : DEFAULT_REST_SERVER_HOST;
        int port = DEFAULT_REST_SERVER_PORT;
        try {
            if (parsedOpts.hasOption(PORT_OPT)) {
                port = Integer.parseInt(parsedOpts.getOptionValue(PORT_OPT));
            }
        } catch (NumberFormatException e) {
            printHelpAndExit("The port must be a valid integer.");
        }

        return new GlobalOptions(host, port);
    }

    /**
     * Print help and exit with a success code (0).
     */
    private void printHelpAndExit() {
        System.out.println("Common usages:");
        System.out.println("  gobblin-admin.sh jobs --list");
        System.out.println("  gobblin-admin.sh jobs --list --name JobName");
        System.out.println("  gobblin-admin.sh jobs --details --id job_id");
        System.out.println("  gobblin-admin.sh jobs --properties --<id|name> <job_id|JobName>");
        System.out.println();

        printHelpAndExit(0);
    }

    /**
     * Prints an error message, then prints the help and exits with an error code.
     */
    private void printHelpAndExit(String errorMessage) {
        System.err.println(errorMessage);
        printHelpAndExit(1);
    }

    /**
     * Print help and exit with the specified code.
     * @param exitCode The code to exit with
     */
    private void printHelpAndExit(int exitCode) {
        HelpFormatter hf = new HelpFormatter();

        hf.printHelp("gobblin-admin.sh <command> [options]", this.options);
        System.out.println("Valid commands:");
        for (String command : getCommandNames()) {
            System.out.println(command);
        }

        System.exit(exitCode);
    }
}