hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a...@apache.org
Subject hbase git commit: HBASE-16982 Better integrate Apache CLI in AbstractHBaseTool. - processOldArgs() in AbstractHBaseTool will make it possible to change existing tools to use Apache CLI in a backward compatible manner. - Changes ExportSnapshot tool as a p
Date Tue, 08 Nov 2016 20:21:34 GMT
Repository: hbase
Updated Branches:
  refs/heads/master 9afcb4366 -> 52241c90e


HBASE-16982 Better integrate Apache CLI in AbstractHBaseTool.
- processOldArgs() in AbstractHBaseTool will make it possible to change existing tools to
use Apache CLI in a backward compatible manner.
- Changes ExportSnapshot tool as a proof-of-concept
- Update version of Apache CLI from 1.2 to 1.3.1

Change-Id: I4bb2e7da4f2ed0e12e28621ab16459309fa36d03


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/52241c90
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/52241c90
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/52241c90

Branch: refs/heads/master
Commit: 52241c90e4eab19b6613278d2e8107ab56c8a57a
Parents: 9afcb43
Author: Apekshit Sharma <appy@apache.org>
Authored: Wed Oct 19 21:39:10 2016 -0700
Committer: Apekshit Sharma <appy@apache.org>
Committed: Tue Nov 8 12:21:29 2016 -0800

----------------------------------------------------------------------
 .../hadoop/hbase/util/AbstractHBaseTool.java    |  75 +++++--
 .../hbase/util/AbstractHBaseToolTest.java       | 150 ++++++++++++++
 .../hadoop/hbase/snapshot/ExportSnapshot.java   | 202 ++++++++++---------
 .../hbase/snapshot/TestExportSnapshot.java      |  21 +-
 4 files changed, 328 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/52241c90/hbase-common/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java
b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java
index 6e3dec6..b5beaae 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/AbstractHBaseTool.java
@@ -17,15 +17,21 @@
 package org.apache.hadoop.hbase.util;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
 
-import org.apache.commons.cli.BasicParser;
 import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.MissingOptionException;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configurable;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
@@ -37,7 +43,7 @@ import org.apache.hadoop.util.ToolRunner;
  * command-line argument parsing.
  */
 @InterfaceAudience.Private
-public abstract class AbstractHBaseTool implements Tool {
+public abstract class AbstractHBaseTool implements Tool, Configurable {
   protected static final int EXIT_SUCCESS = 0;
   protected static final int EXIT_FAILURE = 1;
 
@@ -52,6 +58,17 @@ public abstract class AbstractHBaseTool implements Tool {
 
   protected String[] cmdLineArgs = null;
 
+  // To print options in order they were added in help text.
+  private HashMap<Option, Integer> optionsOrder = new HashMap<>();
+  private int optionsCount = 0;
+
+  private class OptionsOrderComparator implements Comparator<Option> {
+    @Override
+    public int compare(Option o1, Option o2) {
+      return optionsOrder.get(o1) - optionsOrder.get(o2);
+    }
+  }
+
   /**
    * Override this to add command-line options using {@link #addOptWithArg}
    * and similar methods.
@@ -66,6 +83,20 @@ public abstract class AbstractHBaseTool implements Tool {
   /** The "main function" of the tool */
   protected abstract int doWork() throws Exception;
 
+  /**
+   * For backward compatibility. DO NOT use it for new tools.
+   * We have options in existing tools which can't be ported to Apache CLI's {@link Option}.
+   * (because they don't pass validation, for e.g. "-copy-to". "-" means short name
+   * which doesn't allow '-' in name). This function is to allow tools to have, for time
being,
+   * parameters which can't be parsed using {@link Option}.
+   * Overrides should consume all valid legacy arguments. If the param 'args' is not empty
on
+   * return, it means there were invalid options, in which case we'll exit from the tool.
+   * Note that it's called before {@link #processOptions(CommandLine)}, which means new options'
+   * values will override old ones'.
+   */
+  protected void processOldArgs(List<String> args) {
+  }
+
   @Override
   public Configuration getConf() {
     return conf;
@@ -85,17 +116,29 @@ public abstract class AbstractHBaseTool implements Tool {
     }
 
     CommandLine cmd;
+    List<String> argsList = new ArrayList<>();
+    for (String arg : args) {
+      argsList.add(arg);
+    }
+    // For backward compatibility of args which can't be parsed as Option. See javadoc for
+    // processOldArgs(..)
+    processOldArgs(argsList);
     try {
       addOptions();
       if (isHelpCommand(args)) {
         printUsage();
         return EXIT_SUCCESS;
       }
-      // parse the command line arguments
-      cmd = new BasicParser().parse(options, args);
+      String[] remainingArgs = new String[argsList.size()];
+      argsList.toArray(remainingArgs);
+      cmd = new DefaultParser().parse(options, remainingArgs);
+    } catch (MissingOptionException e) {
+      LOG.error(e.getMessage());
+      LOG.error("Use -h or --help for usage instructions.");
+      return EXIT_FAILURE;
     } catch (ParseException e) {
       LOG.error("Error when parsing command-line arguments", e);
-      printUsage();
+      LOG.error("Use -h or --help for usage instructions.");
       return EXIT_FAILURE;
     }
 
@@ -114,7 +157,7 @@ public abstract class AbstractHBaseTool implements Tool {
   private boolean isHelpCommand(String[] args) throws ParseException {
     Options helpOption = new Options().addOption(HELP_OPTION);
     // this parses the command line but doesn't throw an exception on unknown options
-    CommandLine cl = new BasicParser().parse(helpOption, args, true);
+    CommandLine cl = new DefaultParser().parse(helpOption, args, true);
     return cl.getOptions().length != 0;
   }
 
@@ -126,39 +169,46 @@ public abstract class AbstractHBaseTool implements Tool {
       final String usageFooter) {
     HelpFormatter helpFormatter = new HelpFormatter();
     helpFormatter.setWidth(120);
+    helpFormatter.setOptionComparator(new OptionsOrderComparator());
     helpFormatter.printHelp(usageStr, usageHeader, options, usageFooter);
   }
 
   protected void addOption(Option option) {
     options.addOption(option);
+    optionsOrder.put(option, optionsCount++);
+  }
+
+  protected void addRequiredOption(Option option) {
+    option.setRequired(true);
+    addOption(option);
   }
 
   protected void addRequiredOptWithArg(String opt, String description) {
     Option option = new Option(opt, true, description);
     option.setRequired(true);
-    options.addOption(option);
+    addOption(option);
   }
 
   protected void addRequiredOptWithArg(String shortOpt, String longOpt, String description)
{
     Option option = new Option(shortOpt, longOpt, true, description);
     option.setRequired(true);
-    options.addOption(option);
+    addOption(option);
   }
 
   protected void addOptNoArg(String opt, String description) {
-    options.addOption(opt, false, description);
+    addOption(new Option(opt, false, description));
   }
 
   protected void addOptNoArg(String shortOpt, String longOpt, String description) {
-    options.addOption(shortOpt, longOpt, false, description);
+    addOption(new Option(shortOpt, longOpt, false, description));
   }
 
   protected void addOptWithArg(String opt, String description) {
-    options.addOption(opt, true, description);
+    addOption(new Option(opt, true, description));
   }
 
   protected void addOptWithArg(String shortOpt, String longOpt, String description) {
-    options.addOption(shortOpt, longOpt, true, description);
+    addOption(new Option(shortOpt, longOpt, true, description));
   }
 
   public int getOptionAsInt(CommandLine cmd, String opt, int defaultValue) {
@@ -176,6 +226,7 @@ public abstract class AbstractHBaseTool implements Tool {
       return defaultValue;
     }
   }
+
   /**
    * Parse a number and enforce a range.
    */

http://git-wip-us.apache.org/repos/asf/hbase/blob/52241c90/hbase-common/src/test/java/org/apache/hadoop/hbase/util/AbstractHBaseToolTest.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/AbstractHBaseToolTest.java
b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/AbstractHBaseToolTest.java
new file mode 100644
index 0000000..c1edd5e
--- /dev/null
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/AbstractHBaseToolTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.util;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.hadoop.hbase.util.AbstractHBaseTool.EXIT_FAILURE;
+import static org.apache.hadoop.hbase.util.AbstractHBaseTool.EXIT_SUCCESS;
+import static org.junit.Assert.*;
+
+public class AbstractHBaseToolTest {
+  static final class Options {
+    static final Option REQUIRED = new Option(null, "required", true, "");
+    static final Option OPTIONAL = new Option(null, "optional", true, "");
+    static final Option BOOLEAN = new Option(null, "boolean", false, "");
+  }
+
+  /**
+   * Simple tool to test options parsing.
+   * 3 options: required, optional, and boolean
+   * 2 deprecated options to test backward compatibility: -opt (old version of --optional)
and
+   * -bool (old version of --boolean).
+   */
+  private class TestTool extends AbstractHBaseTool {
+    String requiredValue;
+    String optionalValue;
+    boolean booleanValue;
+
+    @Override
+    protected void addOptions() {
+      addRequiredOption(Options.REQUIRED);
+      addOption(Options.OPTIONAL);
+      addOption(Options.BOOLEAN);
+    }
+
+    @Override
+    protected void processOptions(CommandLine cmd) {
+      requiredValue = cmd.getOptionValue(Options.REQUIRED.getLongOpt());
+      if (cmd.hasOption(Options.OPTIONAL.getLongOpt())) {
+        optionalValue = cmd.getOptionValue(Options.OPTIONAL.getLongOpt());
+      }
+      booleanValue = booleanValue || cmd.hasOption(Options.BOOLEAN.getLongOpt());
+    }
+
+    @Override
+    protected void processOldArgs(List<String> args) {
+      List<String> invalidArgs = new ArrayList<>();
+      while(args.size() > 0) {
+        String cmd = args.remove(0);
+        if (cmd.equals("-opt")) {
+          optionalValue = args.remove(0);
+        } else if (cmd.equals("-bool")) {
+          booleanValue = true;
+        } else {
+          invalidArgs.add(cmd);
+        }
+      }
+      args.addAll(invalidArgs);
+    }
+
+    @Override
+    protected int doWork() throws Exception {
+      return EXIT_SUCCESS;
+    }
+  }
+
+  TestTool tool;
+
+  @Before
+  public void setup() {
+    tool = new TestTool();
+    tool.setConf(HBaseConfiguration.create());
+  }
+
+  @Test
+  public void testAllOptionsSet() throws Exception {
+    String[] args = new String[] { "--required=foo", "--optional=bar", "--boolean"};
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_SUCCESS, returnValue);
+    assertEquals("foo", tool.requiredValue);
+    assertEquals("bar", tool.optionalValue);
+    assertTrue(tool.booleanValue);
+  }
+
+  @Test
+  public void testOptionsNotSet() throws Exception {
+    String[] args = new String[] { "--required=foo" };
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_SUCCESS, returnValue);
+    assertEquals("foo", tool.requiredValue);
+    assertNull(tool.optionalValue);
+    assertFalse(tool.booleanValue);
+  }
+
+  @Test
+  public void testMissingRequiredOption() throws Exception {
+    String[] args = new String[0];
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_FAILURE, returnValue);
+  }
+
+  @Test
+  public void testFailureOnUnrecognizedOption() throws Exception {
+    String[] args = new String[] { "--required=foo", "-asdfs" };
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_FAILURE, returnValue);
+  }
+
+  @Test
+  public void testOldOptionsWork() throws Exception {
+    String[] args = new String[] { "--required=foo", "-opt", "bar", "-bool" };
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_SUCCESS, returnValue);
+    assertEquals("foo", tool.requiredValue);
+    assertEquals("bar", tool.optionalValue);
+    assertTrue(tool.booleanValue);
+  }
+
+  @Test
+  public void testNewOptionOverridesOldOption() throws Exception {
+    String[] args = new String[] { "--required=foo", "--optional=baz", "-opt", "bar", "-bool"
};
+    int returnValue = tool.run(args);
+    assertEquals(EXIT_SUCCESS, returnValue);
+    assertEquals("foo", tool.requiredValue);
+    assertEquals("baz", tool.optionalValue);
+    assertTrue(tool.booleanValue);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hbase/blob/52241c90/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java
index 8e31df0..6c7283a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java
@@ -31,12 +31,13 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
 
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.classification.InterfaceStability;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.conf.Configured;
 import org.apache.hadoop.fs.FSDataInputStream;
 import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileChecksum;
@@ -57,6 +58,7 @@ import org.apache.hadoop.hbase.mob.MobUtils;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.SnapshotDescription;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotFileInfo;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;
+import org.apache.hadoop.hbase.util.AbstractHBaseTool;
 import org.apache.hadoop.hbase.util.FSUtils;
 import org.apache.hadoop.hbase.util.HFileArchiveUtil;
 import org.apache.hadoop.hbase.util.Pair;
@@ -76,7 +78,6 @@ import org.apache.hadoop.mapreduce.security.TokenCache;
 import org.apache.hadoop.hbase.io.hadoopbackport.ThrottledInputStream;
 import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.util.Tool;
-import org.apache.hadoop.util.ToolRunner;
 
 /**
  * Export the specified snapshot to a given FileSystem.
@@ -87,7 +88,7 @@ import org.apache.hadoop.util.ToolRunner;
  */
 @InterfaceAudience.Public
 @InterfaceStability.Evolving
-public class ExportSnapshot extends Configured implements Tool {
+public class ExportSnapshot extends AbstractHBaseTool implements Tool {
   public static final String NAME = "exportsnapshot";
   /** Configuration prefix for overrides for the source filesystem */
   public static final String CONF_SOURCE_PREFIX = NAME + ".from.";
@@ -114,6 +115,34 @@ public class ExportSnapshot extends Configured implements Tool {
   static final String CONF_TEST_FAILURE = "test.snapshot.export.failure";
   static final String CONF_TEST_RETRY = "test.snapshot.export.failure.retry";
 
+
+  // Command line options and defaults.
+  static final class Options {
+    static final Option SNAPSHOT = new Option(null, "snapshot", true, "Snapshot to restore.");
+    static final Option TARGET_NAME = new Option(null, "target", true,
+        "Target name for the snapshot.");
+    static final Option COPY_TO = new Option(null, "copy-to", true, "Remote "
+        + "destination hdfs://");
+    static final Option COPY_FROM = new Option(null, "copy-from", true,
+        "Input folder hdfs:// (default hbase.rootdir)");
+    static final Option NO_CHECKSUM_VERIFY = new Option(null, "no-checksum-verify", false,
+        "Do not verify checksum, use name+length only.");
+    static final Option NO_TARGET_VERIFY = new Option(null, "no-target-verify", false,
+        "Do not verify the integrity of the exported snapshot.");
+    static final Option OVERWRITE = new Option(null, "overwrite", false,
+        "Rewrite the snapshot manifest if already exists.");
+    static final Option CHUSER = new Option(null, "chuser", true,
+        "Change the owner of the files to the specified one.");
+    static final Option CHGROUP = new Option(null, "chgroup", true,
+        "Change the group of the files to the specified one.");
+    static final Option CHMOD = new Option(null, "chmod", true,
+        "Change the permission of the files to the specified one.");
+    static final Option MAPPERS = new Option(null, "mappers", true,
+        "Number of mappers to use during the copy (mapreduce.job.maps).");
+    static final Option BANDWIDTH = new Option(null, "bandwidth", true,
+        "Limit bandwidth to this value in MB/second.");
+  }
+
   // Export Map-Reduce Counters, to keep track of the progress
   public enum Counter {
     MISSING_FILES, FILES_COPIED, FILES_SKIPPED, COPY_FAILED,
@@ -851,77 +880,70 @@ public class ExportSnapshot extends Configured implements Tool {
     }
   }
 
+  private boolean verifyTarget = true;
+  private boolean verifyChecksum = true;
+  private String snapshotName = null;
+  private String targetName = null;
+  private boolean overwrite = false;
+  private String filesGroup = null;
+  private String filesUser = null;
+  private Path outputRoot = null;
+  private Path inputRoot = null;
+  private int bandwidthMB = Integer.MAX_VALUE;
+  private int filesMode = 0;
+  private int mappers = 0;
+
+  @Override
+  protected void processOptions(CommandLine cmd) {
+    snapshotName = cmd.getOptionValue(Options.SNAPSHOT.getLongOpt(), snapshotName);
+    targetName = cmd.getOptionValue(Options.TARGET_NAME.getLongOpt(), targetName);
+    if (cmd.hasOption(Options.COPY_TO.getLongOpt())) {
+      outputRoot = new Path(cmd.getOptionValue(Options.COPY_TO.getLongOpt()));
+    }
+    if (cmd.hasOption(Options.COPY_FROM.getLongOpt())) {
+      inputRoot = new Path(cmd.getOptionValue(Options.COPY_FROM.getLongOpt()));
+    }
+    mappers = getOptionAsInt(cmd, Options.MAPPERS.getLongOpt(), mappers);
+    filesUser = cmd.getOptionValue(Options.CHUSER.getLongOpt(), filesUser);
+    filesGroup = cmd.getOptionValue(Options.CHGROUP.getLongOpt(), filesGroup);
+    filesMode = getOptionAsInt(cmd, Options.CHMOD.getLongOpt(), filesMode);
+    bandwidthMB = getOptionAsInt(cmd, Options.BANDWIDTH.getLongOpt(), bandwidthMB);
+    overwrite = cmd.hasOption(Options.OVERWRITE.getLongOpt());
+    // And verifyChecksum and verifyTarget with values read from old args in processOldArgs(...).
+    verifyChecksum = !cmd.hasOption(Options.NO_CHECKSUM_VERIFY.getLongOpt());
+    verifyTarget = !cmd.hasOption(Options.NO_TARGET_VERIFY.getLongOpt());
+  }
+
   /**
    * Execute the export snapshot by copying the snapshot metadata, hfiles and wals.
    * @return 0 on success, and != 0 upon failure.
    */
   @Override
-  public int run(String[] args) throws IOException {
-    boolean verifyTarget = true;
-    boolean verifyChecksum = true;
-    String snapshotName = null;
-    String targetName = null;
-    boolean overwrite = false;
-    String filesGroup = null;
-    String filesUser = null;
-    Path outputRoot = null;
-    int bandwidthMB = Integer.MAX_VALUE;
-    int filesMode = 0;
-    int mappers = 0;
-
+  public int doWork() throws IOException {
     Configuration conf = getConf();
-    Path inputRoot = FSUtils.getRootDir(conf);
-
-    // Process command line args
-    for (int i = 0; i < args.length; i++) {
-      String cmd = args[i];
-      if (cmd.equals("-snapshot")) {
-        snapshotName = args[++i];
-      } else if (cmd.equals("-target")) {
-        targetName = args[++i];
-      } else if (cmd.equals("-copy-to")) {
-        outputRoot = new Path(args[++i]);
-      } else if (cmd.equals("-copy-from")) {
-        inputRoot = new Path(args[++i]);
-        FSUtils.setRootDir(conf, inputRoot);
-      } else if (cmd.equals("-no-checksum-verify")) {
-        verifyChecksum = false;
-      } else if (cmd.equals("-no-target-verify")) {
-        verifyTarget = false;
-      } else if (cmd.equals("-mappers")) {
-        mappers = Integer.parseInt(args[++i]);
-      } else if (cmd.equals("-chuser")) {
-        filesUser = args[++i];
-      } else if (cmd.equals("-chgroup")) {
-        filesGroup = args[++i];
-      } else if (cmd.equals("-bandwidth")) {
-        bandwidthMB = Integer.parseInt(args[++i]);
-      } else if (cmd.equals("-chmod")) {
-        filesMode = Integer.parseInt(args[++i], 8);
-      } else if (cmd.equals("-overwrite")) {
-        overwrite = true;
-      } else if (cmd.equals("-h") || cmd.equals("--help")) {
-        printUsageAndExit();
-      } else {
-        System.err.println("UNEXPECTED: " + cmd);
-        printUsageAndExit();
-      }
-    }
 
     // Check user options
     if (snapshotName == null) {
       System.err.println("Snapshot name not provided.");
-      printUsageAndExit();
+      LOG.error("Use -h or --help for usage instructions.");
+      return 0;
     }
 
     if (outputRoot == null) {
-      System.err.println("Destination file-system not provided.");
-      printUsageAndExit();
+      System.err.println("Destination file-system (--" + Options.COPY_TO.getLongOpt()
+              + ") not provided.");
+      LOG.error("Use -h or --help for usage instructions.");
+      return 0;
     }
 
     if (targetName == null) {
       targetName = snapshotName;
     }
+    if (inputRoot == null) {
+      inputRoot = FSUtils.getRootDir(conf);
+    } else {
+      FSUtils.setRootDir(conf, inputRoot);
+    }
 
     Configuration srcConf = HBaseConfiguration.createClusterConf(conf, null, CONF_SOURCE_PREFIX);
     srcConf.setBoolean("fs." + inputRoot.toUri().getScheme() + ".impl.disable.cache", true);
@@ -1053,51 +1075,37 @@ public class ExportSnapshot extends Configured implements Tool {
     }
   }
 
-  // ExportSnapshot
-  private void printUsageAndExit() {
-    System.err.printf("Usage: bin/hbase %s [options]%n", getClass().getName());
-    System.err.println(" where [options] are:");
-    System.err.println("  -h|-help                Show this help and exit.");
-    System.err.println("  -snapshot NAME          Snapshot to restore.");
-    System.err.println("  -copy-to NAME           Remote destination hdfs://");
-    System.err.println("  -copy-from NAME         Input folder hdfs:// (default hbase.rootdir)");
-    System.err.println("  -no-checksum-verify     Do not verify checksum, use name+length
only.");
-    System.err.println("  -no-target-verify       Do not verify the integrity of the \\"
+
-        "exported snapshot.");
-    System.err.println("  -overwrite              Rewrite the snapshot manifest if already
exists");
-    System.err.println("  -chuser USERNAME        Change the owner of the files " +
-        "to the specified one.");
-    System.err.println("  -chgroup GROUP          Change the group of the files to " +
-        "the specified one.");
-    System.err.println("  -chmod MODE             Change the permission of the files " +
-        "to the specified one.");
-    System.err.println("  -mappers                Number of mappers to use during the " +
-        "copy (mapreduce.job.maps).");
-    System.err.println("  -bandwidth              Limit bandwidth to this value in MB/second.");
-    System.err.println();
-    System.err.println("Examples:");
-    System.err.println("  hbase snapshot export \\");
-    System.err.println("    -snapshot MySnapshot -copy-to hdfs://srv2:8082/hbase \\");
-    System.err.println("    -chuser MyUser -chgroup MyGroup -chmod 700 -mappers 16");
-    System.err.println();
-    System.err.println("  hbase snapshot export \\");
-    System.err.println("    -snapshot MySnapshot -copy-from hdfs://srv2:8082/hbase \\");
-    System.err.println("    -copy-to hdfs://srv1:50070/hbase \\");
+  @Override
+  protected void printUsage() {
+    super.printUsage();
+    System.out.println("\n"
+        + "Examples:\n"
+        + "  hbase snapshot export \\\n"
+        + "    --snapshot MySnapshot --copy-to hdfs://srv2:8082/hbase \\\n"
+        + "    --chuser MyUser --chgroup MyGroup --chmod 700 --mappers 16\n"
+        + "\n"
+        + "  hbase snapshot export \\\n"
+        + "    --snapshot MySnapshot --copy-from hdfs://srv2:8082/hbase \\\n"
+        + "    --copy-to hdfs://srv1:50070/hbase");
     System.exit(1);
   }
 
-  /**
-   * The guts of the {@link #main} method.
-   * Call this method to avoid the {@link #main(String[])} System.exit.
-   * @param args
-   * @return errCode
-   * @throws Exception
-   */
-  static int innerMain(final Configuration conf, final String [] args) throws Exception {
-    return ToolRunner.run(conf, new ExportSnapshot(), args);
+  @Override protected void addOptions() {
+    addRequiredOption(Options.SNAPSHOT);
+    addOption(Options.COPY_TO);
+    addOption(Options.COPY_FROM);
+    addOption(Options.TARGET_NAME);
+    addOption(Options.NO_CHECKSUM_VERIFY);
+    addOption(Options.NO_TARGET_VERIFY);
+    addOption(Options.OVERWRITE);
+    addOption(Options.CHUSER);
+    addOption(Options.CHGROUP);
+    addOption(Options.CHMOD);
+    addOption(Options.MAPPERS);
+    addOption(Options.BANDWIDTH);
   }
 
-  public static void main(String[] args) throws Exception {
-    System.exit(innerMain(HBaseConfiguration.create(), args));
+  public static void main(String[] args) {
+    new ExportSnapshot().doStaticMain(args);
   }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/52241c90/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java
index 7c81334..b78785b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java
@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.hbase.snapshot;
 
+import static org.apache.hadoop.util.ToolRunner.run;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -48,6 +49,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.Snapshot
 import org.apache.hadoop.hbase.testclassification.VerySlowMapReduceTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.util.ToolRunner;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -204,18 +206,18 @@ public class TestExportSnapshot {
     copyDir = copyDir.makeQualified(fs);
 
     List<String> opts = new ArrayList<String>();
-    opts.add("-snapshot");
+    opts.add("--snapshot");
     opts.add(Bytes.toString(snapshotName));
-    opts.add("-copy-to");
+    opts.add("--copy-to");
     opts.add(copyDir.toString());
     if (targetName != snapshotName) {
-      opts.add("-target");
+      opts.add("--target");
       opts.add(Bytes.toString(targetName));
     }
-    if (overwrite) opts.add("-overwrite");
+    if (overwrite) opts.add("--overwrite");
 
     // Export Snapshot
-    int res = ExportSnapshot.innerMain(conf, opts.toArray(new String[opts.size()]));
+    int res = run(conf, new ExportSnapshot(), opts.toArray(new String[opts.size()]));
     assertEquals(0, res);
 
     // Verify File-System state
@@ -273,12 +275,9 @@ public class TestExportSnapshot {
     }
     // Export Snapshot
     Path sourceDir = TEST_UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getRootDir();
-    int res = ExportSnapshot.innerMain(conf, new String[] {
-      "-snapshot", Bytes.toString(snapshotName),
-      "-copy-from", sourceDir.toString(),
-      "-copy-to", copyDir.toString()
-    });
-    return res;
+    String[] args = new String[] { "--snapshot", Bytes.toString(snapshotName),
+        "--copy-from", sourceDir.toString(), "--copy-to", copyDir.toString() };
+    return ToolRunner.run(conf, new ExportSnapshot(), args);
   }
 
   /*


Mime
View raw message