org.apache.hadoop.hdfs.AvatarShellCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hdfs.AvatarShellCommand.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 org.apache.hadoop.hdfs;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;

import org.apache.commons.cli.OptionBuilder;

import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

public class AvatarShellCommand {

    private static String WRONG = " - wrong arguments: ";
    private static String CMD = "Command: ";

    private static List<String> safeModeActions = new ArrayList<String>();
    static {
        safeModeActions.add("enter");
        safeModeActions.add("leave");
        safeModeActions.add("get");
        safeModeActions.add("initqueues");
        safeModeActions.add("prepfailover");
        safeModeActions.add("get");
    }

    // commands
    static final String waitTxIdCommand = "waittxid";
    static final String failoverCommand = "failover";
    static final String prepfailoverCommand = "prepfailover";
    static final String metasaveCommand = "metasave";
    static final String safemodeCommand = "safemode";
    static final String setAvatarCommand = "setAvatar";
    static final String isInitializedCommand = "isInitialized";
    static final String shutdownAvatarCommand = "shutdownAvatar";
    static final String showAvatarCommand = "showAvatar";
    static final String saveNamespaceCommand = "saveNamespace";

    // helpers
    static final String zeroCommand = "zero";
    static final String oneCommand = "one";
    static final String serviceCommand = "service";
    static final String addressCommand = "address";

    // commands
    boolean isWaitTxIdCommand;
    boolean isFailoverCommand;
    boolean isPrepfailoverCommand;

    boolean isMetasaveCommand;
    String[] metasageArgs;

    boolean isSafemodeCommand;
    String[] safemodeArgs;

    boolean isSetAvatarCommand;
    String[] setAvatarArgs;

    boolean isIsInitializedCommand;
    boolean isShutdownAvatarCommand;
    boolean isShowAvatarCommand;

    boolean isSaveNamespaceCommand;
    String[] saveNamespaceArgs;

    // helpers
    boolean isZeroCommand;
    boolean isOneCommand;

    boolean isServiceCommand;
    String[] serviceArgs;

    boolean isAddressCommand;
    String[] addressArgs;

    List<String> getSaveNamespaceArgs() {
        List<String> args = new ArrayList<String>();
        if (saveNamespaceArgs != null) {
            for (String arg : saveNamespaceArgs) {
                args.add(arg);
            }
        }
        return args;
    }

    void throwException(String msg) {
        System.err.println(msg);
        throw new IllegalArgumentException(msg);
    }

    /**
     * For commands that directly obtain information from zk
     */
    void noZeroOrOneOrAddress(String command) {
        if (isZeroCommand || isOneCommand) {
            throwException(CMD + command + " (zero|one) should not be specified");
        }
        if (isAddressCommand) {
            throwException(CMD + command + " address should not be specified");
        }
    }

    /**
     * Check if either -zero -one or -address are specified.
     */
    void eitherZeroOrOneOrAddress(String command) {
        if (!isAddressCommand && !(isZeroCommand ^ isOneCommand)) {
            throwException(CMD + command + ": (zero|one) specified incorrectly");
        }
        if (isAddressCommand && (isZeroCommand || isOneCommand)) {
            throwException(CMD + command + ": cannot specify address with (zero|one)");
        }
    }

    private void assertArgsSize(String command, String[] args, int maxSize, int requiredSize) {
        if (args == null && requiredSize == 0) {
            return;
        }
        if (args.length < requiredSize || args.length > maxSize) {
            throwException(CMD + command + WRONG + Arrays.toString(args));
        }
    }

    boolean validate(CommandLine cmd) {
        int commands = 0;
        commands += isWaitTxIdCommand ? 1 : 0;
        commands += isFailoverCommand ? 1 : 0;
        commands += isPrepfailoverCommand ? 1 : 0;
        commands += isMetasaveCommand ? 1 : 0;
        commands += isSafemodeCommand ? 1 : 0;
        commands += isSetAvatarCommand ? 1 : 0;
        commands += isIsInitializedCommand ? 1 : 0;
        commands += isShutdownAvatarCommand ? 1 : 0;
        commands += isShowAvatarCommand ? 1 : 0;
        commands += isSaveNamespaceCommand ? 1 : 0;

        if (commands > 1) {
            throwException("More than one command specified");
        }

        if (isZeroCommand && isOneCommand) {
            throwException("Both zero and one specified");
        }

        if ((isServiceCommand || isZeroCommand || isOneCommand) && isAddressCommand) {
            throwException("Both service|zero|one and address specified");
        }

        // /////////////////////// complext commands

        // -waittxid
        if (isWaitTxIdCommand) {
            noZeroOrOneOrAddress(waitTxIdCommand);
            assertArgsSize(waitTxIdCommand, cmd.getOptionValues(waitTxIdCommand), 0, 0);
        }

        // -failover
        if (isFailoverCommand) {
            noZeroOrOneOrAddress(failoverCommand);
            assertArgsSize(failoverCommand, cmd.getOptionValues(failoverCommand), 0, 0);
        }

        // -prepfalover
        if (isPrepfailoverCommand) {
            noZeroOrOneOrAddress(prepfailoverCommand);
            assertArgsSize(prepfailoverCommand, cmd.getOptionValues(prepfailoverCommand), 0, 0);
        }

        // /////////////// per-avatar node commands

        // -showAvatar
        if (isShowAvatarCommand) {
            eitherZeroOrOneOrAddress(showAvatarCommand);
            assertArgsSize(showAvatarCommand, cmd.getOptionValues(showAvatarCommand), 0, 0);
        }

        // -shutDownAvatar
        if (isShutdownAvatarCommand) {
            eitherZeroOrOneOrAddress(shutdownAvatarCommand);
            assertArgsSize(shutdownAvatarCommand, cmd.getOptionValues(shutdownAvatarCommand), 0, 0);
        }

        // -isInitialized
        if (isIsInitializedCommand) {
            eitherZeroOrOneOrAddress(isInitializedCommand);
            assertArgsSize(isInitializedCommand, cmd.getOptionValues(isInitializedCommand), 0, 0);
        }

        // -setAvatar
        if (isSetAvatarCommand) {
            eitherZeroOrOneOrAddress(setAvatarCommand);
            setAvatarArgs = cmd.getOptionValues(setAvatarCommand);
            assertArgsSize(setAvatarCommand, setAvatarArgs, 2, 1);
            if (setAvatarArgs != null) {
                boolean hasPrimary = false;
                for (String arg : setAvatarArgs) {
                    if (!(arg.equals("primary") || arg.equals("force")))
                        throwException(CMD + setAvatarCommand + WRONG + Arrays.toString(setAvatarArgs));
                    if (arg.equals("primary"))
                        hasPrimary = true;
                }
                if (!hasPrimary) {
                    throwException(CMD + setAvatarCommand + WRONG + Arrays.toString(setAvatarArgs));
                }
            }
        }

        // -metasave
        if (isMetasaveCommand) {
            eitherZeroOrOneOrAddress(metasaveCommand);
            metasageArgs = cmd.getOptionValues(metasaveCommand);
            assertArgsSize(metasaveCommand, metasageArgs, 1, 1);
        }

        // -safemode
        if (isSafemodeCommand) {
            eitherZeroOrOneOrAddress(safemodeCommand);
            safemodeArgs = cmd.getOptionValues(safemodeCommand);
            assertArgsSize(safemodeCommand, safemodeArgs, 1, 1);
            for (String arg : safemodeArgs) {
                if (!safeModeActions.contains(arg))
                    throwException(CMD + safemodeCommand + " - safemode action: " + arg + " unknown");
            }
        }

        // -saveNamespace
        if (isSaveNamespaceCommand) {
            eitherZeroOrOneOrAddress(saveNamespaceCommand);
            saveNamespaceArgs = cmd.getOptionValues(saveNamespaceCommand);
            assertArgsSize(saveNamespaceCommand, saveNamespaceArgs, 2, 0);
            if (saveNamespaceArgs != null) {
                for (String arg : saveNamespaceArgs) {
                    if (!(arg.equals("uncompressed") || arg.equals("force")))
                        throwException(CMD + saveNamespaceCommand + WRONG + Arrays.toString(saveNamespaceArgs));
                }
            }
        }

        // -service
        if (isServiceCommand) {
            serviceArgs = cmd.getOptionValues(serviceCommand);
            assertArgsSize(serviceCommand, serviceArgs, 1, 1);
        }

        // -address
        if (isAddressCommand) {
            addressArgs = cmd.getOptionValues(addressCommand);
            assertArgsSize(addressCommand, addressArgs, 1, 1);
            int i = addressArgs[0].indexOf(":");
            if (i < 1)
                throwException(addressCommand + ": wrong host:port pair");
            try {
                Integer.valueOf(addressArgs[0].substring(i + 1));
            } catch (Exception e) {
                throwException(addressCommand + ": wrong host:port pair");
            }
        }

        // -zero -one
        assertArgsSize(zeroCommand, cmd.getOptionValues(zeroCommand), 0, 0);
        assertArgsSize(oneCommand, cmd.getOptionValues(oneCommand), 0, 0);

        return true;
    }

    static AvatarShellCommand parseCommand(String[] argv) {
        CommandLine cmd = parseOptions(argv);
        if (cmd == null)
            return null;

        AvatarShellCommand asc = new AvatarShellCommand();

        asc.isWaitTxIdCommand = cmd.hasOption(waitTxIdCommand);
        asc.isFailoverCommand = cmd.hasOption(failoverCommand);
        asc.isPrepfailoverCommand = cmd.hasOption(prepfailoverCommand);
        asc.isMetasaveCommand = cmd.hasOption(metasaveCommand);
        asc.isSafemodeCommand = cmd.hasOption(safemodeCommand);
        asc.isSetAvatarCommand = cmd.hasOption(setAvatarCommand);
        asc.isIsInitializedCommand = cmd.hasOption(isInitializedCommand);
        asc.isShutdownAvatarCommand = cmd.hasOption(shutdownAvatarCommand);
        asc.isShowAvatarCommand = cmd.hasOption(showAvatarCommand);
        asc.isSaveNamespaceCommand = cmd.hasOption(saveNamespaceCommand);

        asc.isZeroCommand = cmd.hasOption(zeroCommand);
        asc.isOneCommand = cmd.hasOption(oneCommand);
        asc.isServiceCommand = cmd.hasOption(serviceCommand);
        asc.isAddressCommand = cmd.hasOption(addressCommand);

        try {
            asc.validate(cmd);
        } catch (Exception e) {
            return null;
        }
        return asc;
    }

    private static CommandLine parseOptions(String[] argv) {
        Options options = buildOptions();
        CommandLineParser parser = new PosixParser();
        try {
            return parser.parse(options, argv);
        } catch (ParseException e) {
            System.out.println("Error parsing command-line options");
            return null;
        }
    }

    /**
     * Build command-line options and descriptions
     */
    @SuppressWarnings("static-access")
    public static Options buildOptions() {
        Options options = new Options();

        // actual commands
        options.addOption(OptionBuilder.hasOptionalArgs().create(waitTxIdCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(failoverCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(prepfailoverCommand));

        options.addOption(OptionBuilder.hasOptionalArgs().create(metasaveCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(safemodeCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(saveNamespaceCommand));

        options.addOption(OptionBuilder.hasOptionalArgs().create(setAvatarCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(isInitializedCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(shutdownAvatarCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(showAvatarCommand));

        // helper commands
        options.addOption(OptionBuilder.hasOptionalArgs().create(zeroCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(oneCommand));

        options.addOption(OptionBuilder.hasOptionalArgs().create(serviceCommand));
        options.addOption(OptionBuilder.hasOptionalArgs().create(addressCommand));

        return options;
    }
}