HBASE-10903 HBASE-10740 regression; cannot pass commands for zk to run

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1584407 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2014-04-03 21:34:11 +00:00
parent 60079f0cd0
commit c6042a57e4
2 changed files with 129 additions and 11 deletions

View File

@ -19,6 +19,7 @@
package org.apache.hadoop.hbase.zookeeper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
@ -26,6 +27,7 @@ import java.util.Properties;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeperMain;
/**
@ -33,6 +35,8 @@ import org.apache.zookeeper.ZooKeeperMain;
* from HBase XML configuration.
*/
public class ZooKeeperMainServer {
private static final String SERVER_ARG = "-server";
public String parse(final Configuration c) {
// Note that we do not simply grab the property
// HConstants.ZOOKEEPER_QUORUM from the HBaseConfiguration because the
@ -61,20 +65,72 @@ public class ZooKeeperMainServer {
return host.toString();
}
/**
* ZooKeeper 3.4.6 broke being able to pass commands on command line.
* See ZOOKEEPER-1897. This class is a hack to restore this faclity.
*/
private static class HACK_UNTIL_ZOOKEEPER_1897_ZooKeeperMain extends ZooKeeperMain {
public HACK_UNTIL_ZOOKEEPER_1897_ZooKeeperMain(String[] args)
throws IOException, InterruptedException {
super(args);
}
/**
* Run the command-line args passed. Calls System.exit when done.
* @throws KeeperException
* @throws IOException
* @throws InterruptedException
*/
void runCmdLine() throws KeeperException, IOException, InterruptedException {
processCmd(this.cl);
System.exit(0);
}
}
/**
* @param args
* @return True if argument strings have a '-server' in them.
*/
private static boolean hasServer(final String args[]) {
return args.length > 0 && args[0].equals(SERVER_ARG);
}
/**
* @param args
* @return True if command-line arguments were passed.
*/
private static boolean hasCommandLineArguments(final String args[]) {
if (hasServer(args)) {
if (args.length < 2) throw new IllegalStateException("-server param but no value");
return args.length > 2;
}
return args.length > 0;
}
/**
* Run the tool.
* @param args Command line arguments. First arg is path to zookeepers file.
*/
public static void main(String args[]) throws Exception {
Configuration conf = HBaseConfiguration.create();
String hostport = new ZooKeeperMainServer().parse(conf);
String[] newArgs = args;
if (hostport != null && hostport.length() > 0) {
newArgs = new String[args.length + 2];
System.arraycopy(args, 0, newArgs, 2, args.length);
newArgs[0] = "-server";
newArgs[1] = hostport;
String [] newArgs = args;
if (!hasServer(args)) {
// Add the zk ensemble from configuration if none passed on command-line.
Configuration conf = HBaseConfiguration.create();
String hostport = new ZooKeeperMainServer().parse(conf);
if (hostport != null && hostport.length() > 0) {
newArgs = new String[args.length + 2];
System.arraycopy(args, 0, newArgs, 2, args.length);
newArgs[0] = "-server";
newArgs[1] = hostport;
}
}
// If command-line arguments, run our hack so they are executed.
if (hasCommandLineArguments(args)) {
HACK_UNTIL_ZOOKEEPER_1897_ZooKeeperMain zkm =
new HACK_UNTIL_ZOOKEEPER_1897_ZooKeeperMain(newArgs);
zkm.runCmdLine();
} else {
ZooKeeperMain.main(newArgs);
}
ZooKeeperMain.main(newArgs);
}
}

View File

@ -21,6 +21,8 @@ package org.apache.hadoop.hbase.zookeeper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.security.Permission;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.junit.Test;
@ -28,9 +30,69 @@ import org.junit.experimental.categories.Category;
@Category(SmallTests.class)
public class TestZooKeeperMainServer {
private final ZooKeeperMainServer parser = new ZooKeeperMainServer();
// ZKMS calls System.exit. Catch the call and prevent exit using trick described up in
// http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit
protected static class ExitException extends SecurityException {
private static final long serialVersionUID = 1L;
public final int status;
public ExitException(int status) {
super("There is no escape!");
this.status = status;
}
}
@Test public void test() {
private static class NoExitSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
// allow anything.
}
@Override
public void checkPermission(Permission perm, Object context) {
// allow anything.
}
@Override
public void checkExit(int status) {
super.checkExit(status);
throw new ExitException(status);
}
}
/**
* We need delete of a znode to work at least.
* @throws Exception
*/
@Test
public void testCommandLineWorks() throws Exception {
System.setSecurityManager(new NoExitSecurityManager());
HBaseTestingUtility htu = new HBaseTestingUtility();
htu.getConfiguration().setInt(HConstants.ZK_SESSION_TIMEOUT, 1000);
htu.startMiniZKCluster();
try {
ZooKeeperWatcher zkw = htu.getZooKeeperWatcher();
String znode = "/testCommandLineWorks";
ZKUtil.createWithParents(zkw, znode, HConstants.EMPTY_BYTE_ARRAY);
ZKUtil.checkExists(zkw, znode);
boolean exception = false;
try {
ZooKeeperMainServer.main(new String [] {"-server",
"localhost:" + htu.getZkCluster().getClientPort(), "delete", znode});
} catch (ExitException ee) {
// ZKMS calls System.exit which should trigger this exception.
exception = true;
}
assertTrue(exception);
assertEquals(-1, ZKUtil.checkExists(zkw, znode));
} finally {
htu.shutdownMiniZKCluster();
System.setSecurityManager(null); // or save and restore original
}
}
@Test
public void testHostPortParse() {
ZooKeeperMainServer parser = new ZooKeeperMainServer();
Configuration c = HBaseConfiguration.create();
assertEquals("localhost:" + c.get(HConstants.ZOOKEEPER_CLIENT_PORT), parser.parse(c));
final String port = "1234";