You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2011/02/28 16:17:01 UTC
svn commit: r1075371 -
/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java
Author: brandonwilliams
Date: Mon Feb 28 15:16:59 2011
New Revision: 1075371
URL: http://svn.apache.org/viewvc?rev=1075371&view=rev
Log:
Modernize nodecmd option handling.
Patch by Pavel Yaskevich, reviewed by Sylvain Lebresne for
CASSANDRA-2219
Modified:
cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java
Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java?rev=1075371&r1=1075370&r2=1075371&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/tools/NodeCmd.java Mon Feb 28 15:16:59 2011
@@ -30,6 +30,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
+import org.apache.cassandra.utils.Pair;
import org.apache.commons.cli.*;
import org.apache.cassandra.cache.JMXInstrumentedCacheMBean;
@@ -40,29 +41,26 @@ import org.apache.cassandra.dht.Token;
import org.apache.cassandra.net.MessagingServiceMBean;
import org.apache.cassandra.utils.EstimatedHistogram;
-public class NodeCmd {
- private static final String HOST_OPT_LONG = "host";
- private static final String HOST_OPT_SHORT = "h";
- private static final String PORT_OPT_LONG = "port";
- private static final String PORT_OPT_SHORT = "p";
- private static final String USERNAME_OPT_LONG = "username";
- private static final String USERNAME_OPT_SHORT = "u";
- private static final String PASSWORD_OPT_LONG = "password";
- private static final String PASSWORD_OPT_SHORT = "pw";
- private static final int defaultPort = 8080;
- private static Options options = null;
+public class NodeCmd
+{
+ private static final Pair<String, String> HOST_OPT = new Pair<String, String>("h", "host");
+ private static final Pair<String, String> PORT_OPT = new Pair<String, String>("p", "port");
+ private static final Pair<String, String> USERNAME_OPT = new Pair<String, String>("u", "username");
+ private static final Pair<String, String> PASSWORD_OPT = new Pair<String, String>("pw", "password");
+ private static final int DEFAULT_PORT = 8080;
+
+ private static ToolOptions options = null;
private NodeProbe probe;
static
{
- options = new Options();
- Option optHost = new Option(HOST_OPT_SHORT, HOST_OPT_LONG, true, "node hostname or ip address");
- optHost.setRequired(true);
- options.addOption(optHost);
- options.addOption(PORT_OPT_SHORT, PORT_OPT_LONG, true, "remote jmx agent port number");
- options.addOption(USERNAME_OPT_SHORT, USERNAME_OPT_LONG, true, "remote jmx agent username");
- options.addOption(PASSWORD_OPT_SHORT, PASSWORD_OPT_LONG, true, "remote jmx agent password");
+ options = new ToolOptions();
+
+ options.addOption(HOST_OPT, true, "node hostname or ip address", true);
+ options.addOption(PORT_OPT, true, "remote jmx agent port number");
+ options.addOption(USERNAME_OPT, true, "remote jmx agent username");
+ options.addOption(PASSWORD_OPT, true, "remote jmx agent password");
}
public NodeCmd(NodeProbe probe)
@@ -70,7 +68,8 @@ public class NodeCmd {
this.probe = probe;
}
- public enum NodeCommand {
+ public enum NodeCommand
+ {
RING, INFO, CFSTATS, SNAPSHOT, CLEARSNAPSHOT, VERSION, TPSTATS, FLUSH, DRAIN,
DECOMMISSION, MOVE, LOADBALANCE, REMOVETOKEN, REPAIR, CLEANUP, COMPACT, SCRUB,
SETCACHECAPACITY, GETCOMPACTIONTHRESHOLD, SETCOMPACTIONTHRESHOLD, NETSTATS, CFHISTOGRAMS,
@@ -469,21 +468,21 @@ public class NodeCmd {
public static void main(String[] args) throws IOException, InterruptedException, ParseException
{
CommandLineParser parser = new PosixParser();
- CommandLine cmd = null;
-
+ ToolCommandLine cmd = null;
+
try
{
- cmd = parser.parse(options, args);
+ cmd = new ToolCommandLine(parser.parse(options, args));
}
- catch (ParseException parseExcep)
+ catch (ParseException p)
{
- badUse(parseExcep.toString());
+ badUse(p.getMessage());
}
- String host = cmd.getOptionValue(HOST_OPT_LONG);
- int port = defaultPort;
+ String host = cmd.getOptionValue(HOST_OPT.left);
+ int port = DEFAULT_PORT;
- String portNum = cmd.getOptionValue(PORT_OPT_LONG);
+ String portNum = cmd.getOptionValue(PORT_OPT.left);
if (portNum != null)
{
try
@@ -495,8 +494,9 @@ public class NodeCmd {
throw new ParseException("Port must be a number");
}
}
- String username = cmd.getOptionValue(USERNAME_OPT_LONG);
- String password = cmd.getOptionValue(PASSWORD_OPT_LONG);
+
+ String username = cmd.getOptionValue(USERNAME_OPT.left);
+ String password = cmd.getOptionValue(PASSWORD_OPT.left);
NodeProbe probe = null;
try
@@ -507,28 +507,25 @@ public class NodeCmd {
{
err(ioe, "Error connection to remote JMX agent!");
}
-
- if (cmd.getArgs().length < 1)
- badUse("Missing argument for command.");
- NodeCmd nodeCmd = new NodeCmd(probe);
-
- // Execute the requested command.
- String[] arguments = cmd.getArgs();
- String cmdName = arguments[0];
+ NodeCommand command = null;
- boolean validCommand = false;
- for (NodeCommand n : NodeCommand.values())
+ try
+ {
+ command = cmd.getCommand();
+ }
+ catch (IllegalArgumentException e)
{
- if (cmdName.toUpperCase().equals(n.name()))
- validCommand = true;
+ badUse(e.getMessage());
}
- if (!validCommand)
- badUse("Unrecognized command: " + cmdName);
- NodeCommand nc = NodeCommand.valueOf(cmdName.toUpperCase());
- switch (nc)
+ NodeCmd nodeCmd = new NodeCmd(probe);
+
+ // Execute the requested command.
+ String[] arguments = cmd.getCommandArguments();
+
+ switch (command)
{
case RING : nodeCmd.printRing(System.out); break;
case INFO : nodeCmd.printInfo(System.out); break;
@@ -550,25 +547,25 @@ public class NodeCmd {
break;
case NETSTATS :
- if (arguments.length > 1) { nodeCmd.printNetworkStats(InetAddress.getByName(arguments[1]), System.out); }
+ if (arguments.length > 0) { nodeCmd.printNetworkStats(InetAddress.getByName(arguments[0]), System.out); }
else { nodeCmd.printNetworkStats(null, System.out); }
break;
case SNAPSHOT :
- if (arguments.length > 1) { probe.takeSnapshot(arguments[1]); }
+ if (arguments.length > 0) { probe.takeSnapshot(arguments[0]); }
else { probe.takeSnapshot(""); }
break;
case MOVE :
- if (arguments.length != 2) { badUse("Missing token argument for move."); }
- probe.move(arguments[1]);
+ if (arguments.length != 1) { badUse("Missing token argument for move."); }
+ probe.move(arguments[0]);
break;
case REMOVETOKEN :
- if (arguments.length != 2) { badUse("Missing an argument for removetoken (either status, force, or a token)"); }
- else if (arguments[1].equals("status")) { nodeCmd.printRemovalStatus(System.out); }
- else if (arguments[1].equals("force")) { nodeCmd.printRemovalStatus(System.out); probe.forceRemoveCompletion(); }
- else { probe.removeToken(arguments[1]); }
+ if (arguments.length != 1) { badUse("Missing an argument for removetoken (either status, force, or a token)"); }
+ else if (arguments[0].equals("status")) { nodeCmd.printRemovalStatus(System.out); }
+ else if (arguments[0].equals("force")) { nodeCmd.printRemovalStatus(System.out); probe.forceRemoveCompletion(); }
+ else { probe.removeToken(arguments[0]); }
break;
case CLEANUP :
@@ -578,32 +575,32 @@ public class NodeCmd {
case SCRUB :
case INVALIDATEKEYCACHE :
case INVALIDATEROWCACHE :
- optionalKSandCFs(nc, arguments, probe);
+ optionalKSandCFs(command, arguments, probe);
break;
case GETCOMPACTIONTHRESHOLD :
- if (arguments.length != 3) { badUse("getcompactionthreshold requires ks and cf args."); }
- probe.getCompactionThreshold(System.out, arguments[1], arguments[2]);
+ if (arguments.length != 2) { badUse("getcompactionthreshold requires ks and cf args."); }
+ probe.getCompactionThreshold(System.out, arguments[0], arguments[1]);
break;
case CFHISTOGRAMS :
- if (arguments.length != 3) { badUse("cfhistograms requires ks and cf args"); }
- nodeCmd.printCfHistograms(arguments[1], arguments[2], System.out);
+ if (arguments.length != 2) { badUse("cfhistograms requires ks and cf args"); }
+ nodeCmd.printCfHistograms(arguments[0], arguments[1], System.out);
break;
case SETCACHECAPACITY :
- if (arguments.length != 5) { badUse("setcachecapacity requires ks, cf, keycachecap, and rowcachecap args."); }
- probe.setCacheCapacities(arguments[1], arguments[2], Integer.parseInt(arguments[3]), Integer.parseInt(arguments[4]));
+ if (arguments.length != 4) { badUse("setcachecapacity requires ks, cf, keycachecap, and rowcachecap args."); }
+ probe.setCacheCapacities(arguments[0], arguments[1], Integer.parseInt(arguments[2]), Integer.parseInt(arguments[3]));
break;
case SETCOMPACTIONTHRESHOLD :
- if (arguments.length != 5) { badUse("setcompactionthreshold requires ks, cf, min, and max threshold args."); }
- int minthreshold = Integer.parseInt(arguments[3]);
- int maxthreshold = Integer.parseInt(arguments[4]);
+ if (arguments.length != 4) { badUse("setcompactionthreshold requires ks, cf, min, and max threshold args."); }
+ int minthreshold = Integer.parseInt(arguments[2]);
+ int maxthreshold = Integer.parseInt(arguments[3]);
if ((minthreshold < 0) || (maxthreshold < 0)) { badUse("Thresholds must be positive integers"); }
if (minthreshold > maxthreshold) { badUse("Min threshold cannot be greater than max."); }
if (minthreshold < 2 && maxthreshold != 0) { badUse("Min threshold must be at least 2"); }
- probe.setCompactionThreshold(arguments[1], arguments[2], minthreshold, maxthreshold);
+ probe.setCompactionThreshold(arguments[0], arguments[1], minthreshold, maxthreshold);
break;
default :
@@ -630,9 +627,8 @@ public class NodeCmd {
private static void optionalKSandCFs(NodeCommand nc, String[] cmdArgs, NodeProbe probe) throws InterruptedException, IOException
{
- // cmdArgs[0] is "scrub"
// if there is one additional arg, it's the keyspace; more are columnfamilies
- List<String> keyspaces = cmdArgs.length == 1 ? probe.getKeyspaces() : Arrays.asList(cmdArgs[1]);
+ List<String> keyspaces = cmdArgs.length == 0 ? probe.getKeyspaces() : Arrays.asList(cmdArgs[0]);
for (String keyspace : keyspaces)
{
if (!probe.getKeyspaces().contains(keyspace))
@@ -645,7 +641,7 @@ public class NodeCmd {
// second loop so we're less likely to die halfway through due to invalid keyspace
for (String keyspace : keyspaces)
{
- String[] columnFamilies = cmdArgs.length <= 2 ? new String[0] : Arrays.copyOfRange(cmdArgs, 2, cmdArgs.length);
+ String[] columnFamilies = cmdArgs.length <= 1 ? new String[0] : Arrays.copyOfRange(cmdArgs, 1, cmdArgs.length);
switch (nc)
{
case REPAIR : probe.forceTableRepair(keyspace, columnFamilies); break;
@@ -673,4 +669,82 @@ public class NodeCmd {
}
}
}
+
+
+ private static class ToolOptions extends Options
+ {
+ public void addOption(Pair<String, String> opts, boolean hasArgument, String description)
+ {
+ addOption(opts, hasArgument, description, false);
+ }
+
+ public void addOption(Pair<String, String> opts, boolean hasArgument, String description, boolean required)
+ {
+ addOption(opts.left, opts.right, hasArgument, description, required);
+ }
+
+ public void addOption(String opt, String longOpt, boolean hasArgument, String description, boolean required)
+ {
+ Option option = new Option(opt, longOpt, hasArgument, description);
+ option.setRequired(required);
+ addOption(option);
+ }
+ }
+
+ private static class ToolCommandLine
+ {
+ private final CommandLine commandLine;
+
+ public ToolCommandLine(CommandLine commands)
+ {
+ commandLine = commands;
+ }
+
+ public Option[] getOptions()
+ {
+ return commandLine.getOptions();
+ }
+
+ public boolean hasOption(String opt)
+ {
+ return commandLine.hasOption(opt);
+ }
+
+ public String getOptionValue(String opt)
+ {
+ return commandLine.getOptionValue(opt);
+ }
+
+ public NodeCommand getCommand()
+ {
+ if (commandLine.getArgs().length == 0)
+ throw new IllegalArgumentException("Command was not specified.");
+
+ String command = commandLine.getArgs()[0];
+
+ try
+ {
+ return NodeCommand.valueOf(command.toUpperCase());
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalArgumentException("Unrecognized command: " + command);
+ }
+ }
+
+ public String[] getCommandArguments()
+ {
+ List params = commandLine.getArgList();
+
+ if (params.size() < 2) // command parameters are empty
+ return new String[0];
+
+ String[] toReturn = new String[params.size() - 1];
+
+ for (int i = 1; i < params.size(); i++)
+ toReturn[i - 1] = (String) params.get(i);
+
+ return toReturn;
+ }
+ }
}