From 80bc114e36727776b311bbe7f5de6f461167ca14 Mon Sep 17 00:00:00 2001 From: Chris Lohfink Date: Wed, 23 Mar 2016 22:11:15 -0500 Subject: [PATCH] update README for hints tool --- README.md | 36 +++++ .../org/apache/cassandra/hints/HintsTool.java | 126 ++++++++++++------ 2 files changed, 121 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 45eb698..13dd539 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ since been merged into Cassandra starting with versions 3.0.4 and 3.4 as the `ss Example usage: java -jar sstable-tools.jar cqlsh + java -jar sstable-tools.jar hints 1458779867606-1.hints java -jar sstable-tools.jar describe ma-2-big-Data.db Example shell usage: @@ -112,6 +113,7 @@ Example shell usage: * [cqlsh](#cqlsh) - Drop into an interactive shell to make queries against SSTables. * [describe](#describe) - Describe SSTable data and metadata. +* [hints](#hints) - Dump hints from a hint file ## Building @@ -286,3 +288,37 @@ RegularColumns: {val:org.apache.cassandra.db.marshal.UTF8Type} java -jar sstable-tools.jar describe /path/to/file.db ``` +## hints + +Deserialize the mutations in a hints file and print them to standard out. To have the information necessary do deserialize +the mutations this tool requires the schema of the file. This is currently handled by connecting to the cluster and querying +the metadata. You can specify the host and (cql) port via the `-h` and `-p` options. + +Example Output: + +``` +java -jar sstable-tools.jar hints 1458786695234-1.hints +Loading schema from 127.0.0.1:9042 +/Users/clohfink/1458786695234-1.hints +===================================== +[test.t1] key=1 columns=[[] | [val]] + Row: EMPTY | val=1 +[[val=1 ts=1458786688691698]] + +``` + +### Usage + +``` +java -jar sstable-tools.jar hints + +usage: hints [-h ] [-p ] [-s] hintfile [hintfile ...] + +Hint Dump for Apache Cassandra 3.x +Options: + -h Host to extract schema frome. + -p CQL native port. + -s Only output mutations. + hintfile at least one file containing hints + +``` diff --git a/src/main/java/org/apache/cassandra/hints/HintsTool.java b/src/main/java/org/apache/cassandra/hints/HintsTool.java index 50b4b05..9b58937 100644 --- a/src/main/java/org/apache/cassandra/hints/HintsTool.java +++ b/src/main/java/org/apache/cassandra/hints/HintsTool.java @@ -2,7 +2,6 @@ import com.csforge.sstable.CassandraUtils; -import com.csforge.sstable.TableTransformer; import com.google.common.base.Strings; import org.apache.cassandra.config.Config; import org.apache.cassandra.db.Mutation; @@ -10,62 +9,107 @@ import org.apache.cassandra.db.rows.Row; import org.apache.cassandra.io.util.DataInputPlus; import org.apache.cassandra.net.MessagingService; +import org.apache.commons.cli.*; -import java.io.ByteArrayInputStream; -import java.io.File; +import java.io.*; import java.nio.ByteBuffer; import java.util.Iterator; +import static com.csforge.sstable.TableTransformer.*; + public class HintsTool { + private static final String HOST_OPTION = "h"; + private static final String PORT_OPTION = "p"; + private static final String SILENT_OPTION = "s"; + private static final Options options = new Options(); static { Config.setClientMode(true); + Option hostOption = new Option(HOST_OPTION, true, "Host to extract schema frome."); + hostOption.setRequired(false); + options.addOption(hostOption); + Option portOption = new Option(PORT_OPTION, true, "CQL native port."); + portOption.setRequired(false); + options.addOption(portOption); + Option silentOption = new Option(SILENT_OPTION, false, "Only output mutations."); + silentOption.setRequired(false); + options.addOption(silentOption); } - public static void main(String... args) { - String host = "127.0.0.1"; - int port = 9042; - File hint_file = null; + private static void dumpHints(File hint_file, PrintStream out, int version) throws IOException { + try (HintsReader reader = HintsReader.open(hint_file)) { + for (HintsReader.Page page : reader) { + Iterator hints = page.buffersIterator(); //hints iterator im pretty sure is busted + while (hints.hasNext()) { + ByteBuffer buf = hints.next(); + DataInputPlus in = new DataInputPlus.DataInputStreamPlus(new ByteArrayInputStream(buf.array())); + Hint hint = Hint.serializer.deserialize(in, version); + Mutation mutation = hint.mutation; + for (PartitionUpdate partition : mutation.getPartitionUpdates()) { + out.println(partition); + for (Row row : partition) { + out.println(row); + } + } + } + } + } + } - if (args.length == 1) { - hint_file = new File(args[0]); - } else if (args.length == 2) { - host = args[0]; - hint_file = new File(args[1]); - } else if (args.length == 3) { - host = args[0]; - port = Integer.parseInt(args[1]); - hint_file = new File(args[2]); - } else { - System.err.println("Usage: hints \n hints \n" + - " hints "); - System.exit(-1); + private static void printHelp() { + try (PrintWriter errWriter = new PrintWriter(System.err, true)) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(errWriter, 120, "hints hintfile [hintfile ...]", + String.format("%nHint Dump for Apache Cassandra 3.x%nOptions:"), + options, 2, 1, "", true); + errWriter.println(" hintfile at least one file containing hints"); + errWriter.println(); } + } + public static void main(String... args) { + CommandLineParser parser = new PosixParser(); + CommandLine cmd = null; try { - System.out.printf("%sLoading schema from %s:%s", TableTransformer.ANSI_RED, host, port); - System.out.flush(); - CassandraUtils.loadTablesFromRemote(host, port); - System.out.println("\r\u001B[1;34m" + hint_file.getAbsolutePath()); - System.out.println(TableTransformer.ANSI_CYAN + Strings.repeat("=", hint_file.getAbsolutePath().length())); - System.out.print(TableTransformer.ANSI_RESET); - int version = Integer.parseInt(System.getProperty("hints.version", "" + MessagingService.current_version)); + cmd = parser.parse(options, args); + } catch (ParseException e) { + System.err.format("%sFailure parsing arguments: %s%s%n%n", ANSI_RED, e.getMessage(), ANSI_RESET); + printHelp(); + System.exit(-1); - try (HintsReader reader = HintsReader.open(hint_file)) { - for (HintsReader.Page page : reader) { - Iterator hints = page.buffersIterator(); //hints iterator im pretty sure is busted - while (hints.hasNext()) { - ByteBuffer buf = hints.next(); - DataInputPlus in = new DataInputPlus.DataInputStreamPlus(new ByteArrayInputStream(buf.array())); - Hint hint = Hint.serializer.deserialize(in, version); - Mutation mutation = hint.mutation; - for (PartitionUpdate partition : mutation.getPartitionUpdates()) { - System.out.println(partition); - for (Row row : partition) { - System.out.println(row); - } - } + } + if(cmd.getArgs().length == 0) { + printHelp(); + System.exit(-2); + } + String host = cmd.getOptionValue(HOST_OPTION, "127.0.0.1"); + int port = Integer.parseInt(cmd.getOptionValue(PORT_OPTION, "9042")); + try { + int version = MessagingService.current_version; + try { + if (!cmd.hasOption(SILENT_OPTION)) { + System.out.printf("%sLoading schema from %s:%s%s", ANSI_RED, host, port, ANSI_RESET); + System.out.flush(); + } + CassandraUtils.loadTablesFromRemote(host, port); + version = Integer.parseInt(System.getProperty("hints.version", "" + MessagingService.current_version)); + } finally { + System.out.print(ANSI_RESET); + } + for (String hint : cmd.getArgs()) { + File hint_file = new File(hint); + if (!hint_file.exists()) { + if(!cmd.hasOption(SILENT_OPTION)) { + System.out.println("\r" + ANSI_RESET); + } + System.err.println("Non-existant hint file provided: " + hint); + } else { + if(!cmd.hasOption(SILENT_OPTION)) { + System.out.println("\r\u001B[1;34m" + hint_file.getAbsolutePath()); + System.out.println(ANSI_CYAN + Strings.repeat("=", hint_file.getAbsolutePath().length())); + System.out.print(ANSI_RESET); } + dumpHints(hint_file, System.out, version); } } } catch (Exception e) {