diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a0d1516a86c..1f1397ebcc3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -132,6 +132,8 @@ New Features * SOLR-5556: Allow class of CollectionsHandler and InfoHandler to be specified in solr.xml. (Gregory Chanan, Alan Woodward) +* SOLR-5581: Give ZkCLI the ability to get files. (Gregory Chanan via Mark Miller) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java b/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java index 0222102f3e2..63d02dd88ba 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java @@ -3,6 +3,7 @@ package org.apache.solr.cloud; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; @@ -48,6 +49,8 @@ public class ZkCLI { private static final String MAKEPATH = "makepath"; private static final String PUT = "put"; private static final String PUT_FILE = "putfile"; + private static final String GET = "get"; + private static final String GET_FILE = "getfile"; private static final String DOWNCONFIG = "downconfig"; private static final String ZK_CLI_NAME = "ZkCLI"; private static final String HELP = "help"; @@ -92,7 +95,7 @@ public class ZkCLI { .withDescription( "cmd to run: " + BOOTSTRAP + ", " + UPCONFIG + ", " + DOWNCONFIG + ", " + LINKCONFIG + ", " + MAKEPATH + ", " + PUT + ", " + PUT_FILE + "," - + LIST + ", " + CLEAR).create(CMD)); + + GET + "," + GET_FILE + ", " + LIST + ", " + CLEAR).create(CMD)); Option zkHostOption = new Option("z", ZKHOST, true, "ZooKeeper host address"); @@ -137,6 +140,8 @@ public class ZkCLI { System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + MAKEPATH + " /apache/solr"); System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + PUT + " /solr.conf 'conf data'"); System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + PUT_FILE + " /solr.xml /User/myuser/solr/solr.xml"); + System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + GET + " /solr.xml"); + System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + GET_FILE + " /solr.xml solr.xml.file"); System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + CLEAR + " /solr"); System.out.println("zkcli.sh -zkhost localhost:9983 -cmd " + LIST); return; @@ -264,6 +269,22 @@ public class ZkCLI { IOUtils.closeQuietly(is); } + } else if (line.getOptionValue(CMD).equals(GET)) { + List arglist = line.getArgList(); + if (arglist.size() != 1) { + System.out.println("-" + GET + " requires one arg - the path to get"); + System.exit(1); + } + byte [] data = zkClient.getData(arglist.get(0).toString(), null, null, true); + System.out.println(new String(data, "UTF-8")); + } else if (line.getOptionValue(CMD).equals(GET_FILE)) { + List arglist = line.getArgList(); + if (arglist.size() != 2) { + System.out.println("-" + GET_FILE + "requires two args - the path to get and the file to save it to"); + System.exit(1); + } + byte [] data = zkClient.getData(arglist.get(0).toString(), null, null, true); + FileUtils.writeByteArrayToFile(new File(arglist.get(1).toString()), data); } } finally { if (solrPort != null) { diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkCLITest.java b/solr/core/src/test/org/apache/solr/cloud/ZkCLITest.java index 79711ec8044..71f66a84da9 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkCLITest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkCLITest.java @@ -33,6 +33,8 @@ import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.util.ExternalPaths; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -262,6 +264,47 @@ public class ZkCLITest extends SolrTestCaseJ4 { assertEquals(0, zkClient.getChildren("/", null, true).size()); } + @Test + public void testGet() throws Exception { + String getNode = "/getNode"; + byte [] data = new String("getNode-data").getBytes("UTF-8"); + this.zkClient.create(getNode, data, CreateMode.PERSISTENT, true); + String[] args = new String[] {"-zkhost", zkServer.getZkAddress(), "-cmd", + "get", getNode}; + ZkCLI.main(args); + } + + @Test + public void testGetFile() throws Exception { + String getNode = "/getFileNode"; + byte [] data = new String("getFileNode-data").getBytes("UTF-8"); + this.zkClient.create(getNode, data, CreateMode.PERSISTENT, true); + + File file = new File(TEMP_DIR, + "solrtest-getfile-" + this.getClass().getName() + "-" + System.currentTimeMillis()); + String[] args = new String[] {"-zkhost", zkServer.getZkAddress(), "-cmd", + "getfile", getNode, file.getAbsolutePath()}; + ZkCLI.main(args); + + byte [] readData = FileUtils.readFileToByteArray(file); + assertArrayEquals(data, readData); + } + + @Test + public void testGetFileNotExists() throws Exception { + String getNode = "/getFileNotExistsNode"; + + File file = new File(TEMP_DIR, + "solrtest-getfilenotexists-" + this.getClass().getName() + "-" + System.currentTimeMillis()); + String[] args = new String[] {"-zkhost", zkServer.getZkAddress(), "-cmd", + "getfile", getNode, file.getAbsolutePath()}; + try { + ZkCLI.main(args); + fail("Expected NoNodeException"); + } catch (KeeperException.NoNodeException ex) { + } + } + @Override public void tearDown() throws Exception { if (VERBOSE) {