diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupCommands.java hbase-client/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupCommands.java index 8a4d48a..0d7b1e7 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupCommands.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupCommands.java @@ -49,66 +49,80 @@ import com.google.common.collect.Lists; @InterfaceAudience.Private @InterfaceStability.Evolving public final class BackupCommands { + + public final static String IGNORE = "ignore"; - private static final String USAGE = "Usage: hbase backup COMMAND\n" + public static final String USAGE = "Usage: hbase backup COMMAND [command-specific arguments]\n" + "where COMMAND is one of:\n" + " create create a new backup image\n" - + " cancel cancel an ongoing backup\n" + " delete delete an existing backup image\n" + " describe show the detailed information of a backup image\n" + " history show history of all successful backups\n" + " progress show the progress of the latest backup request\n" + " set backup set management\n" - + "Enter \'help COMMAND\' to see help message for each command\n"; - - private static final String CREATE_CMD_USAGE = - "Usage: hbase backup create [tables] [-s name] [-convert] " - + "[-silent] [-w workers][-b bandwith]\n" - + " type \"full\" to create a full backup image;\n" - + " \"incremental\" to create an incremental backup image\n" - + " BACKUP_ROOT The full root path to store the backup image,\n" - + " the prefix can be hdfs, webhdfs or gpfs\n" + " Options:\n" - + " tables If no tables (\"\") are specified, all tables are backed up. " - + "Otherwise it is a\n" + " comma separated list of tables.\n" - + " -w number of parallel workers.\n" - + " -b bandwith per one worker (in MB sec)\n" - + " -set name of backup set" ; - - private static final String PROGRESS_CMD_USAGE = "Usage: hbase backup progress \n" - + " backupId backup image id;\n"; - - private static final String DESCRIBE_CMD_USAGE = "Usage: hbase backup decsribe \n" - + " backupId backup image id\n"; - - private static final String HISTORY_CMD_USAGE = + + "Run \'hbase backup help COMMAND\' to see help message for each command\n"; + + public static final String CREATE_CMD_USAGE = + "Usage: hbase backup create [tables] [-set name] " + + "[-w workers][-b bandwith]\n" + + " type \"full\" to create a full backup image\n" + + " \"incremental\" to create an incremental backup image\n" + + " BACKUP_ROOT The full root path to store the backup image,\n" + + " the prefix can be hdfs, webhdfs or gpfs\n" + + "Options:\n" + + " tables If no tables (\"\") are specified, all tables are backed up.\n" + + " Otherwise it is a comma separated list of tables.\n" + + " -w number of parallel workers (MapReduce tasks).\n" + + " -b bandwith per one worker (MapReduce task) in MBs per sec\n" + + " -set name of backup set to use (mutually exclusive with [tables])" ; + + public static final String PROGRESS_CMD_USAGE = "Usage: hbase backup progress \n" + + " backupId backup image id\n"; + + public static final String DESCRIBE_CMD_USAGE = "Usage: hbase backup decsribe \n" + + " backupId backup image id\n"; + + public static final String HISTORY_CMD_USAGE = "Usage: hbase backup history [-path BACKUP_ROOT] [-n N] [-t table]\n" - + " -n N show up to N last backup sessions, default - 10;\n" - + " -path backup root path;\n" - + " -t table name; "; + + " -n N show up to N last backup sessions, default - 10\n" + + " -path backup root path\n" + + " -t table table name. If specified, only backup images, which contain this table\n" + + " will be listed." ; - private static final String DELETE_CMD_USAGE = "Usage: hbase backup delete \n" - + " backupId backup image id;\n"; + public static final String DELETE_CMD_USAGE = "Usage: hbase backup delete \n" + + " backupId backup image id\n"; - private static final String CANCEL_CMD_USAGE = "Usage: hbase backup cancel \n" - + " backupId backup image id;\n"; + public static final String CANCEL_CMD_USAGE = "Usage: hbase backup cancel \n" + + " backupId backup image id\n"; - private static final String SET_CMD_USAGE = "Usage: hbase backup set COMMAND [name] [tables]\n" - + " name Backup set name\n" - + " tables If no tables (\"\") are specified, all tables will belong to the set. " - + "Otherwise it is a\n" + " comma separated list of tables.\n" - + "where COMMAND is one of:\n" - + " add add tables to a set, crete set if needed\n" - + " remove remove tables from set\n" - + " list list all sets\n" - + " describe describes set\n" - + " delete delete backup set\n"; + public static final String SET_CMD_USAGE = "Usage: hbase backup set COMMAND [name] [tables]\n" + + " name Backup set name\n" + + " tables If no tables (\"\") are specified, all tables will belong to the set.\n" + + " Otherwise it is a comma separated list of tables.\n" + + "COMMAND is one of:\n" + + " add add tables to a set, create a set if needed\n" + + " remove remove tables from a set\n" + + " list list all backup sets in the system\n" + + " describe describe set\n" + + " delete delete backup set\n"; public static abstract class Command extends Configured { + CommandLine cmdline; + Command(Configuration conf) { super(conf); } - public abstract void execute() throws IOException; + + public void execute() throws IOException + { + if(cmdline.hasOption("h") || cmdline.hasOption("help")) { + printUsage(); + throw new IOException(IGNORE); + } + } + + protected abstract void printUsage(); } private BackupCommands() { @@ -149,7 +163,6 @@ public final class BackupCommands { public static class CreateCommand extends Command { - CommandLine cmdline; CreateCommand(Configuration conf, CommandLine cmdline) { super(conf); @@ -158,25 +171,26 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); if (cmdline == null || cmdline.getArgs() == null) { - System.out.println("ERROR: missing arguments"); - System.out.println(CREATE_CMD_USAGE); + System.err.println("ERROR: missing arguments"); + printUsage(); System.exit(-1); } String[] args = cmdline.getArgs(); if (args.length < 3 || args.length > 4) { - System.out.println("ERROR: wrong number of arguments"); - System.out.println(CREATE_CMD_USAGE); + System.err.println("ERROR: wrong number of arguments: "+ args.length); + printUsage(); System.exit(-1); } if (!BackupType.FULL.toString().equalsIgnoreCase(args[1]) && !BackupType.INCREMENTAL.toString().equalsIgnoreCase(args[1])) { - System.out.println("ERROR: invalid backup type"); - System.out.println(CREATE_CMD_USAGE); + System.err.println("ERROR: invalid backup type: "+ args[1]); + printUsage(); System.exit(-1); } - + String tables = null; Configuration conf = getConf() != null? getConf(): HBaseConfiguration.create(); @@ -185,8 +199,11 @@ public final class BackupCommands { String setName = cmdline.getOptionValue("set"); tables = getTablesForSet(setName, conf); - if (tables == null) throw new IOException("Backup set '" + setName - + "' is either empty or does not exist"); + if (tables == null) { + System.err.println("ERROR: Backup set '" + setName+ "' is either empty or does not exist"); + printUsage(); + throw new IOException(IGNORE); + } } else { tables = (args.length == 4) ? args[3] : null; } @@ -216,10 +233,14 @@ public final class BackupCommands { return StringUtils.join(tables, BackupRestoreConstants.TABLENAME_DELIMITER_IN_COMMAND); } } + + @Override + protected void printUsage() { + System.err.println(CREATE_CMD_USAGE); + } } private static class HelpCommand extends Command { - CommandLine cmdline; HelpCommand(Configuration conf, CommandLine cmdline) { super(conf); @@ -228,21 +249,22 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); if (cmdline == null) { - System.out.println(USAGE); - System.exit(0); + printUsage(); + System.exit(-1); } String[] args = cmdline.getArgs(); if (args == null || args.length == 0) { - System.out.println(USAGE); - System.exit(0); + printUsage(); + System.exit(-1); } if (args.length != 2) { - System.out.println("Only support check help message of a single command type"); - System.out.println(USAGE); - System.exit(0); + System.err.println("Only supports help message of a single command type"); + printUsage(); + System.exit(-1); } String type = args[1]; @@ -263,14 +285,18 @@ public final class BackupCommands { System.out.println(SET_CMD_USAGE); } else { System.out.println("Unknown command : " + type); - System.out.println(USAGE); + printUsage(); } System.exit(0); } + + @Override + protected void printUsage() { + System.err.println(USAGE); + } } private static class DescribeCommand extends Command { - CommandLine cmdline; DescribeCommand(Configuration conf, CommandLine cmdline) { super(conf); @@ -279,18 +305,19 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); if (cmdline == null || cmdline.getArgs() == null) { - System.out.println("ERROR: missing arguments"); - System.out.println(DESCRIBE_CMD_USAGE); + System.err.println("ERROR: missing arguments"); + printUsage(); System.exit(-1); } String[] args = cmdline.getArgs(); if (args.length != 2) { - System.out.println("ERROR: wrong number of arguments"); - System.out.println(DESCRIBE_CMD_USAGE); + System.err.println("ERROR: wrong number of arguments"); + printUsage(); System.exit(-1); } - + String backupId = args[1]; Configuration conf = getConf() != null ? getConf() : HBaseConfiguration.create(); try (final Connection conn = ConnectionFactory.createConnection(conf); @@ -299,10 +326,14 @@ public final class BackupCommands { System.out.println(info.getShortDescription()); } } + + @Override + protected void printUsage() { + System.err.println(DESCRIBE_CMD_USAGE); + } } private static class ProgressCommand extends Command { - CommandLine cmdline; ProgressCommand(Configuration conf, CommandLine cmdline) { super(conf); @@ -311,6 +342,8 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); + if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length != 2) { System.out.println("No backup id was specified, " @@ -318,11 +351,12 @@ public final class BackupCommands { } String[] args = cmdline.getArgs(); if (args.length > 2) { - System.out.println("ERROR: wrong number of arguments: " + args.length); - System.out.println(PROGRESS_CMD_USAGE); + System.err.println("ERROR: wrong number of arguments: " + args.length); + printUsage(); System.exit(-1); } - + + String backupId = args == null ? null : args[1]; Configuration conf = getConf() != null? getConf(): HBaseConfiguration.create(); try(final Connection conn = ConnectionFactory.createConnection(conf); @@ -335,11 +369,15 @@ public final class BackupCommands { } } } + + @Override + protected void printUsage() { + System.err.println(PROGRESS_CMD_USAGE); + } } private static class DeleteCommand extends Command { - CommandLine cmdline; DeleteCommand(Configuration conf, CommandLine cmdline) { super(conf); this.cmdline = cmdline; @@ -347,11 +385,13 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length < 2) { - System.out.println("No backup id(s) was specified"); - System.out.println(PROGRESS_CMD_USAGE); + System.err.println("No backup id(s) was specified"); + printUsage(); System.exit(-1); } + String[] args = cmdline.getArgs(); String[] backupIds = new String[args.length - 1]; @@ -364,12 +404,16 @@ public final class BackupCommands { } } + + @Override + protected void printUsage() { + System.err.println(DELETE_CMD_USAGE); + } } // TODO Cancel command private static class CancelCommand extends Command { - CommandLine cmdline; CancelCommand(Configuration conf, CommandLine cmdline) { super(conf); @@ -378,6 +422,7 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length < 2) { System.out.println("No backup id(s) was specified, will use the most recent one"); } @@ -389,10 +434,16 @@ public final class BackupCommands { // TODO cancel backup } } + + @Override + protected void printUsage() { + // TODO Auto-generated method stub + + } } private static class HistoryCommand extends Command { - CommandLine cmdline; + private final static int DEFAULT_HISTORY_LENGTH = 10; HistoryCommand(Configuration conf, CommandLine cmdline) { @@ -403,6 +454,8 @@ public final class BackupCommands { @Override public void execute() throws IOException { + super.execute(); + int n = parseHistoryLength(); TableName tableName = getTableName(); Path backupRootPath = getBackupRootPath(); @@ -424,9 +477,17 @@ public final class BackupCommands { } private Path getBackupRootPath() { - String value = cmdline.getOptionValue("path"); - if (value == null) return null; - return new Path(value); + String value = null; + try{ + value = cmdline.getOptionValue("path"); + if (value == null) return null; + return new Path(value); + } catch (IllegalArgumentException e) { + System.err.println("ERROR: Illegal argument for backup root path: "+ value); + printUsage(); + System.exit(-1); + } + return null; } private TableName getTableName() { @@ -435,15 +496,29 @@ public final class BackupCommands { try{ return TableName.valueOf(value); } catch (IllegalArgumentException e){ - System.out.println("Illegal argument: "+ value); - return null; + System.err.println("Illegal argument for table name: "+ value); + printUsage(); + System.exit(-1); } + return null; } private int parseHistoryLength() { String value = cmdline.getOptionValue("n"); - if (value == null) return DEFAULT_HISTORY_LENGTH; - return Integer.parseInt(value); + try{ + if (value == null) return DEFAULT_HISTORY_LENGTH; + return Integer.parseInt(value); + } catch(NumberFormatException e) { + System.err.println("Illegal argument for history length: "+ value); + printUsage(); + System.exit(-1); + } + return 0; + } + + @Override + protected void printUsage() { + System.err.println(HISTORY_CMD_USAGE); } } @@ -454,8 +529,6 @@ public final class BackupCommands { private final static String SET_DESCRIBE_CMD = "describe"; private final static String SET_LIST_CMD = "list"; - CommandLine cmdline; - BackupSetCommand(Configuration conf, CommandLine cmdline) { super(conf); this.cmdline = cmdline; @@ -463,11 +536,14 @@ public final class BackupCommands { @Override public void execute() throws IOException { - + super.execute(); // Command-line must have at least one element if (cmdline == null || cmdline.getArgs() == null || cmdline.getArgs().length < 2) { - throw new IOException("command line format"); + System.err.println("ERROR: Command line format"); + printUsage(); + System.exit(-1); } + String[] args = cmdline.getArgs(); String cmdStr = args[1]; BackupCommand cmd = getCommand(cmdStr); @@ -509,7 +585,9 @@ public final class BackupCommands { private void processSetDescribe(String[] args) throws IOException { if (args == null || args.length != 3) { - throw new RuntimeException("Wrong number of args: "+args.length); + System.err.println("ERROR: Wrong number of args for 'set describe' command: "+args.length); + printUsage(); + System.exit(-1); } String setName = args[2]; Configuration conf = getConf() != null? getConf(): HBaseConfiguration.create(); @@ -526,7 +604,9 @@ public final class BackupCommands { private void processSetDelete(String[] args) throws IOException { if (args == null || args.length != 3) { - throw new RuntimeException("Wrong number of args"); + System.err.println("ERROR: Wrong number of args for 'set delete' command: "+args.length); + printUsage(); + System.exit(-1); } String setName = args[2]; Configuration conf = getConf() != null? getConf(): HBaseConfiguration.create(); @@ -543,8 +623,11 @@ public final class BackupCommands { private void processSetRemove(String[] args) throws IOException { if (args == null || args.length != 4) { - throw new RuntimeException("Wrong args"); + System.err.println("ERROR: Wrong number of args for 'set remove' command: "+args.length); + printUsage(); + System.exit(-1); } + String setName = args[2]; String[] tables = args[3].split(","); Configuration conf = getConf() != null? getConf(): HBaseConfiguration.create(); @@ -556,7 +639,9 @@ public final class BackupCommands { private void processSetAdd(String[] args) throws IOException { if (args == null || args.length != 4) { - throw new RuntimeException("Wrong args"); + System.err.println("ERROR: Wrong number of args for 'set add' command: "+args.length); + printUsage(); + System.exit(-1); } String setName = args[2]; String[] tables = args[3].split(","); @@ -584,9 +669,17 @@ public final class BackupCommands { } else if (cmdStr.equals(SET_LIST_CMD)) { return BackupCommand.SET_LIST; } else { - throw new IOException("Unknown command for 'set' :" + cmdStr); + System.err.println("ERROR: Unknown command for 'set' :" + cmdStr); + printUsage(); + System.exit(-1); + return null; } } + @Override + protected void printUsage() { + System.err.println(SET_CMD_USAGE); + } + } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/backup/BackupDriver.java hbase-server/src/main/java/org/apache/hadoop/hbase/backup/BackupDriver.java index 8eb2ff8..8499d0b 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/backup/BackupDriver.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/backup/BackupDriver.java @@ -25,7 +25,6 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.backup.impl.BackupCommands; -import org.apache.hadoop.hbase.backup.impl.BackupRestoreConstants; import org.apache.hadoop.hbase.backup.impl.BackupRestoreConstants.BackupCommand; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; @@ -52,9 +51,9 @@ public class BackupDriver extends AbstractHBaseTool { addOptNoArg("debug", "Enable debug loggings"); addOptNoArg("all", "All tables"); addOptWithArg("t", "Table name"); - addOptWithArg("b", "Bandwidth (MB/s)"); - addOptWithArg("w", "Number of workers"); - addOptWithArg("n", "History length"); + addOptWithArg("b", "Bandwidth per worker (M/R task) in MB/s"); + addOptWithArg("w", "Number of workers (M/R tasks)"); + addOptWithArg("n", "History of backup length"); addOptWithArg("set", "Backup set name"); addOptWithArg("path", "Backup destination root directory path"); @@ -67,8 +66,8 @@ public class BackupDriver extends AbstractHBaseTool { String cmd = null; String[] remainArgs = null; if (args == null || args.length == 0) { - BackupCommands.createCommand(getConf(), - BackupRestoreConstants.BackupCommand.HELP, null).execute(); + printToolUsage(); + return -1; } else { cmd = args[0]; remainArgs = new String[args.length - 1]; @@ -93,7 +92,8 @@ public class BackupDriver extends AbstractHBaseTool { } else if (BackupCommand.SET.name().equalsIgnoreCase(cmd)) { type = BackupCommand.SET; } else { - System.out.println("Unsupported command for backup: " + cmd); + System.err.println("Unsupported command for backup: " + cmd); + printToolUsage(); return -1; } @@ -110,7 +110,14 @@ public class BackupDriver extends AbstractHBaseTool { if( type == BackupCommand.CREATE && conf != null) { ((BackupCommands.CreateCommand) command).setConf(conf); } - command.execute(); + try{ + command.execute(); + } catch(IOException e) { + if(e.getMessage().equals(BackupCommands.IGNORE)){ + return -1; + } + throw e; + } return 0; } @@ -134,5 +141,53 @@ public class BackupDriver extends AbstractHBaseTool { System.exit(ret); } + @Override + public int run(String[] args) throws IOException { + if (conf == null) { + LOG.error("Tool configuration is not initialized"); + throw new NullPointerException("conf"); + } + + CommandLine cmd; + try { + // parse the command line arguments + cmd = parseArgs(args); + cmdLineArgs = args; + } catch (Exception e) { + System.err.println("Error when parsing command-line arguments: "+e.getMessage()); + printToolUsage(); + return EXIT_FAILURE; + } + + if (!sanityCheckOptions(cmd)) { + printToolUsage(); + return EXIT_FAILURE; + } + processOptions(cmd); + + int ret = EXIT_FAILURE; + try { + ret = doWork(); + } catch (Exception e) { + LOG.error("Error running command-line tool", e); + return EXIT_FAILURE; + } + return ret; + } + + protected boolean sanityCheckOptions(CommandLine cmd) { + boolean success = true; + for (String reqOpt : requiredOptions) { + if (!cmd.hasOption(reqOpt)) { + System.err.println("Required option -" + reqOpt + " is missing"); + success = false; + } + } + return success; + } + + protected void printToolUsage() throws IOException { + System.err.println(BackupCommands.USAGE); + } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/backup/RestoreDriver.java hbase-server/src/main/java/org/apache/hadoop/hbase/backup/RestoreDriver.java index 32ef218..d3237f7 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/backup/RestoreDriver.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/backup/RestoreDriver.java @@ -47,14 +47,13 @@ public class RestoreDriver extends AbstractHBaseTool { private static final String OPTION_OVERWRITE = "overwrite"; private static final String OPTION_CHECK = "check"; - private static final String OPTION_AUTOMATIC = "automatic"; private static final String OPTION_SET = "set"; private static final String OPTION_DEBUG = "debug"; private static final String USAGE = "Usage: hbase restore [-set set_name] [tableMapping] \n" - + " [-overwrite] [-check] [-automatic]\n" + + " [-overwrite] [-check]\n" + " backup_root_path The parent location where the backup images are stored\n" + " backup_id The id identifying the backup image\n" + " table(s) Table(s) from the backup image to be restored.\n" @@ -65,8 +64,8 @@ public class RestoreDriver extends AbstractHBaseTool { + " -overwrite With this option, restore overwrites to the existing table " + "if there's any in\n" + " restore target. The existing table must be online before restore.\n" - + " -check With this option, restore sequence and dependencies are checked\n" - + " and verified without executing the restore\n" + + " -check With this option, sequence and dependencies are checked\n" + + " and verified without executing the restore command\n" + " -set set_name Backup set to restore, mutually exclusive with table list ."; @@ -80,7 +79,6 @@ public class RestoreDriver extends AbstractHBaseTool { addOptNoArg(OPTION_OVERWRITE, "Overwrite the data if any of the restore target tables exists"); addOptNoArg(OPTION_CHECK, "Check restore sequence and dependencies"); - addOptNoArg(OPTION_AUTOMATIC, "Restore all dependencies"); addOptNoArg(OPTION_DEBUG, "Enable debug logging"); addOptWithArg(OPTION_SET, "Backup set name"); @@ -88,7 +86,7 @@ public class RestoreDriver extends AbstractHBaseTool { LogUtils.disableUselessLoggers(LOG); } - private int parseAndRun(String[] args) { + private int parseAndRun(String[] args) throws IOException{ // enable debug logging Logger backupClientLogger = Logger.getLogger("org.apache.hadoop.hbase.backup"); @@ -116,8 +114,8 @@ public class RestoreDriver extends AbstractHBaseTool { String[] remainArgs = cmd.getArgs(); if (remainArgs.length < 3 && !cmd.hasOption(OPTION_SET) || (cmd.hasOption(OPTION_SET) && remainArgs.length < 2)) { - System.out.println("ERROR: remain args length="+ remainArgs.length); - System.out.println(USAGE); + System.err.println("ERROR: remain args length="+ remainArgs.length); + printToolUsage(); return -1; } @@ -133,12 +131,14 @@ public class RestoreDriver extends AbstractHBaseTool { try{ tables = getTablesForSet(conn, setName, conf); } catch(IOException e){ - System.out.println("ERROR: "+ e.getMessage()+" for setName="+setName); + System.err.println("ERROR: "+ e.getMessage()+" for setName="+setName); + printToolUsage(); return -2; } if (tables == null) { - System.out.println("ERROR: Backup set '" + setName + System.err.println("ERROR: Backup set '" + setName + "' is either empty or does not exist"); + printToolUsage(); return -3; } tableMapping = (remainArgs.length > 2) ? remainArgs[2] : null; @@ -151,8 +151,8 @@ public class RestoreDriver extends AbstractHBaseTool { TableName[] tTableArray = BackupServerUtil.parseTableNames(tableMapping); if (sTableArray != null && tTableArray != null && (sTableArray.length != tTableArray.length)){ - System.out.println("ERROR: table mapping mismatch: " + tables + " : " + tableMapping); - System.out.println(USAGE); + System.err.println("ERROR: table mapping mismatch: " + tables + " : " + tableMapping); + printToolUsage(); return -4; } @@ -193,4 +193,55 @@ public class RestoreDriver extends AbstractHBaseTool { int ret = ToolRunner.run(conf, new RestoreDriver(), args); System.exit(ret); } + + @Override + public int run(String[] args) throws IOException { + if (conf == null) { + LOG.error("Tool configuration is not initialized"); + throw new NullPointerException("conf"); + } + + CommandLine cmd; + try { + // parse the command line arguments + cmd = parseArgs(args); + cmdLineArgs = args; + } catch (Exception e) { + System.err.println("Error when parsing command-line arguments: " + e.getMessage()); + printToolUsage(); + return EXIT_FAILURE; + } + + if (!sanityCheckOptions(cmd) || cmd.hasOption(SHORT_HELP_OPTION) || + cmd.hasOption(LONG_HELP_OPTION)) { + printToolUsage(); + return EXIT_FAILURE; + } + + processOptions(cmd); + + int ret = EXIT_FAILURE; + try { + ret = doWork(); + } catch (Exception e) { + LOG.error("Error running command-line tool", e); + return EXIT_FAILURE; + } + return ret; + } + + protected boolean sanityCheckOptions(CommandLine cmd) { + boolean success = true; + for (String reqOpt : requiredOptions) { + if (!cmd.hasOption(reqOpt)) { + System.err.println("Required option -" + reqOpt + " is missing"); + success = false; + } + } + return success; + } + + protected void printToolUsage() throws IOException { + System.err.println(USAGE); + } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java hbase-server/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java index a876aef..485eef7 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java @@ -44,8 +44,8 @@ public abstract class AbstractHBaseTool implements Tool { protected static final int EXIT_SUCCESS = 0; protected static final int EXIT_FAILURE = 1; - private static final String SHORT_HELP_OPTION = "h"; - private static final String LONG_HELP_OPTION = "help"; + public static final String SHORT_HELP_OPTION = "h"; + public static final String LONG_HELP_OPTION = "help"; private static final Log LOG = LogFactory.getLog(AbstractHBaseTool.class); @@ -53,7 +53,7 @@ public abstract class AbstractHBaseTool implements Tool { protected Configuration conf = null; - private static final Set requiredOptions = new TreeSet(); + protected static final Set requiredOptions = new TreeSet(); protected String[] cmdLineArgs = null; @@ -82,7 +82,7 @@ public abstract class AbstractHBaseTool implements Tool { } @Override - public final int run(String[] args) throws IOException { + public int run(String[] args) throws IOException { if (conf == null) { LOG.error("Tool configuration is not initialized"); throw new NullPointerException("conf"); @@ -117,7 +117,7 @@ public abstract class AbstractHBaseTool implements Tool { return ret; } - private boolean sanityCheckOptions(CommandLine cmd) { + protected boolean sanityCheckOptions(CommandLine cmd) { boolean success = true; for (String reqOpt : requiredOptions) { if (!cmd.hasOption(reqOpt)) { diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java new file mode 100644 index 0000000..80974fa --- /dev/null +++ hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestBackupCommandLineTool.java @@ -0,0 +1,189 @@ +/** + * 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.hbase.backup; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.util.ToolRunner; +import org.junit.Before; +import org.junit.Test; + +public class TestBackupCommandLineTool { + + Configuration conf; + @Before + public void setUpBefore() throws Exception { + conf = HBaseConfiguration.create(); + } + + + @Test + public void backupDriverDescribeHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"describe", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup decsribe ") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"describe", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup decsribe ") >= 0); + + } + + @Test + public void backupDriverCreateHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"create", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup create") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"create", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup create") >= 0); + + } + + @Test + public void backupDriverHistoryHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"history", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup history") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"history", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup history") >= 0); + + } + + @Test + public void backupDriverDeleteHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"delete", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup delete") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"delete", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup delete") >= 0); + + } + + @Test + public void backupDriverProgressHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"progress", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup progress") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"progress", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup progress") >= 0); + + } + + @Test + public void backupDriverSetHelp () throws Exception { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + String[] args = new String[]{"set", "-help" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + String output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup set") >= 0); + + baos = new ByteArrayOutputStream(); + System.setErr(new PrintStream(baos)); + args = new String[]{"set", "-h" }; + // Run backup + ToolRunner.run(conf, new BackupDriver(), args); + + output = baos.toString(); + System.out.println(baos.toString()); + assertTrue(output.indexOf("Usage: hbase backup set") >= 0); + + } +} diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java index 85ff4f7..67ec4a2 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackupSet.java @@ -91,7 +91,7 @@ public class TestFullBackupSet extends TestBackupBase { @Test public void testFullBackupSetDoesNotExist() throws Exception { - LOG.info("TFBSE test full backup, backup set does not exist"); + LOG.info("test full backup, backup set does not exist"); String name = "name1"; String[] args = new String[]{"create", "full", BACKUP_ROOT_DIR, "-set", name }; // Run backup