| /** |
| * 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.cassandra.stress.settings; |
| |
| import java.io.Serializable; |
| import java.util.*; |
| |
| import org.apache.commons.cli.*; |
| import org.apache.commons.cli.Option; |
| |
| public class Legacy implements Serializable |
| { |
| |
| // command line options |
| public static final Options availableOptions = new Options(); |
| |
| private static final String SSL_TRUSTSTORE = "truststore"; |
| private static final String SSL_TRUSTSTORE_PW = "truststore-password"; |
| private static final String SSL_PROTOCOL = "ssl-protocol"; |
| private static final String SSL_ALGORITHM = "ssl-alg"; |
| private static final String SSL_STORE_TYPE = "store-type"; |
| private static final String SSL_CIPHER_SUITES = "ssl-ciphers"; |
| |
| static |
| { |
| availableOptions.addOption("h", "help", false, "Show this help message and exit"); |
| availableOptions.addOption("n", "num-keys", true, "Number of keys, default:1000000"); |
| availableOptions.addOption("F", "num-different-keys", true, "Number of different keys (if < NUM-KEYS, the same key will re-used multiple times), default:NUM-KEYS"); |
| availableOptions.addOption("t", "threadCount", true, "Number of threadCount to use, default:50"); |
| availableOptions.addOption("c", "columns", true, "Number of columns per key, default:5"); |
| availableOptions.addOption("S", "column-size", true, "Size of column values in bytes, default:34"); |
| availableOptions.addOption("C", "unique columns", true, "Max number of unique columns per key, default:50"); |
| availableOptions.addOption("RC", "unique rows", true, "Max number of unique rows, default:50"); |
| availableOptions.addOption("d", "nodes", true, "Host nodes (comma separated), default:locahost"); |
| availableOptions.addOption("D", "nodesfile", true, "File containing host nodes (one per line)"); |
| availableOptions.addOption("s", "stdev", true, "Standard Deviation for gaussian read key generation, default:0.1"); |
| availableOptions.addOption("r", "random", false, "Use random key generator for read key generation (STDEV will have no effect), default:false"); |
| availableOptions.addOption("f", "file", true, "Write output to given file"); |
| availableOptions.addOption("o", "operation", true, "Operation to perform (WRITE, READ, READWRITE, RANGE_SLICE, INDEXED_RANGE_SLICE, MULTI_GET, COUNTERWRITE, COUNTER_GET), default:WRITE"); |
| availableOptions.addOption("u", "supercolumns", true, "Number of super columns per key, default:1"); |
| availableOptions.addOption("y", "family-type", true, "Column Family Type (Super, Standard), default:Standard"); |
| availableOptions.addOption("K", "keep-trying", true, "Retry on-going operation N times (in case of failure). positive integer, default:10"); |
| availableOptions.addOption("k", "keep-going", false, "Ignore errors inserting or reading (when set, --keep-trying has no effect), default:false"); |
| availableOptions.addOption("i", "progress-interval", true, "Progress Report Interval (seconds), default:10"); |
| availableOptions.addOption("g", "keys-per-call", true, "Number of keys to get_range_slices or multiget per call, default:1000"); |
| availableOptions.addOption("l", "replication-factor", true, "Replication Factor to use when creating needed column families, default:1"); |
| availableOptions.addOption("P", "use-prepared-statements", false, "Perform queries using prepared statements (only applicable to CQL)."); |
| availableOptions.addOption("e", "consistency-level", true, "Consistency Level to use (ONE, QUORUM, LOCAL_QUORUM, EACH_QUORUM, ALL, ANY), default:ONE"); |
| availableOptions.addOption("x", "create-index", true, "Type of index to create on needed column families (KEYS)"); |
| availableOptions.addOption("R", "replication-strategy", true, "Replication strategy to use (only on insert if keyspace does not exist), default:org.apache.cassandra.locator.SimpleStrategy"); |
| availableOptions.addOption("O", "strategy-properties", true, "Replication strategy properties in the following format <dc_name>:<num>,<dc_name>:<num>,..."); |
| availableOptions.addOption("V", "average-size-values", false, "Generate column values of average rather than specific size"); |
| availableOptions.addOption("I", "compression", true, "Specify the compression to use for sstable, default:no compression"); |
| availableOptions.addOption("Q", "query-names", true, "Comma-separated list of column names to retrieve from each row."); |
| availableOptions.addOption("Z", "compaction-strategy", true, "CompactionStrategy to use."); |
| availableOptions.addOption("U", "comparator", true, "Column Comparator to use. Currently supported types are: TimeUUIDType, AsciiType, UTF8Type."); |
| availableOptions.addOption("ns", "no-statistics", false, "Turn off the aggegate statistics that is normally output after completion."); |
| availableOptions.addOption("ts", SSL_TRUSTSTORE, true, "SSL: full path to truststore"); |
| availableOptions.addOption("tspw", SSL_TRUSTSTORE_PW, true, "SSL: full path to truststore"); |
| availableOptions.addOption("prtcl", SSL_PROTOCOL, true, "SSL: connections protocol to use (default: TLS)"); |
| availableOptions.addOption("alg", SSL_ALGORITHM, true, "SSL: algorithm"); |
| availableOptions.addOption("st", SSL_STORE_TYPE, true, "SSL: type of store"); |
| availableOptions.addOption("ciphers", SSL_CIPHER_SUITES, true, "SSL: comma-separated list of encryption suites to use"); |
| availableOptions.addOption("th", "throttle", true, "Throttle the total number of operations per second to a maximum amount."); |
| } |
| |
| public static StressSettings build(String[] arguments) |
| { |
| CommandLineParser parser = new PosixParser(); |
| |
| final Converter r = new Converter(); |
| try |
| { |
| CommandLine cmd = parser.parse(availableOptions, arguments); |
| |
| if (cmd.getArgs().length > 0) |
| { |
| System.err.println("Application does not allow arbitrary arguments: " + Arrays.asList(cmd.getArgList())); |
| System.exit(1); |
| } |
| |
| if (cmd.hasOption("h")) |
| printHelpMessage(); |
| |
| if (cmd.hasOption("C")) |
| System.out.println("Ignoring deprecated option -C"); |
| |
| if (cmd.hasOption("o")) |
| r.setCommand(cmd.getOptionValue("o").toLowerCase()); |
| else |
| r.setCommand("insert"); |
| |
| if (cmd.hasOption("K")) |
| r.add("command", "tries=" + cmd.getOptionValue("K")); |
| |
| if (cmd.hasOption("k")) |
| { |
| if (!cmd.hasOption("K")) |
| r.add("command", "retry=1"); |
| r.add("command", "ignore_errors"); |
| } |
| |
| if (cmd.hasOption("g")) |
| r.add("command", "at-once=" + cmd.getOptionValue("g")); |
| |
| if (cmd.hasOption("e")) |
| r.add("command", "cl=" + cmd.getOptionValue("e")); |
| |
| String numKeys; |
| if (cmd.hasOption("n")) |
| numKeys = cmd.getOptionValue("n"); |
| else |
| numKeys = "1000000"; |
| r.add("command", "n=" + numKeys); |
| |
| String uniqueKeys; |
| if (cmd.hasOption("F")) |
| uniqueKeys = cmd.getOptionValue("F"); |
| else |
| uniqueKeys = numKeys; |
| |
| if (r.opts.containsKey("write") || r.opts.containsKey("counterwrite")) |
| { |
| if (!uniqueKeys.equals(numKeys)) |
| r.add("-key", "populate=1.." + uniqueKeys); |
| } |
| else if (cmd.hasOption("r")) |
| { |
| r.add("-key", "dist=uniform(1.." + uniqueKeys + ")"); |
| } |
| else |
| { |
| if (!cmd.hasOption("s")) |
| r.add("-key", "dist=gauss(1.." + uniqueKeys + ",5)"); |
| else |
| r.add("-key", String.format("dist=gauss(1..%s,%.2f)", uniqueKeys, |
| 0.5 / Float.parseFloat(cmd.getOptionValue("s")))); |
| } |
| |
| String colCount; |
| if (cmd.hasOption("c")) |
| colCount = cmd.getOptionValue("c"); |
| else |
| colCount = "5"; |
| |
| String colSize; |
| if (cmd.hasOption("S")) |
| colSize = cmd.getOptionValue("S"); |
| else |
| colSize = "34"; |
| |
| r.add("-col", "n=fixed(" + colCount + ")"); |
| if (cmd.hasOption("V")) |
| { |
| r.add("-col", "size=uniform(1.." + Integer.parseInt(colSize) * 2 + ")"); |
| r.add("-col", "data=rand()"); |
| } |
| else |
| { |
| r.add("-col", "size=fixed(" + colSize + ")"); |
| r.add("-col", "data=repeat(1)"); |
| } |
| if (cmd.hasOption("Q")) |
| r.add("-col", "names=" + cmd.getOptionValue("Q")); |
| |
| if (cmd.hasOption("U")) |
| r.add("-col", "comparator=" + cmd.getOptionValue("U")); |
| |
| if (cmd.hasOption("y") && cmd.getOptionValue("y").equals("Super")) |
| r.add("-col", "super=" + (cmd.hasOption("u") ? cmd.getOptionValue("u") : "1")); |
| |
| if (cmd.hasOption("t")) |
| r.add("-rate", "threads=" + cmd.getOptionValue("t")); |
| else |
| r.add("-rate", "threads=50"); |
| |
| if (cmd.hasOption("th")) |
| r.add("-rate", "limit=" + cmd.getOptionValue("th") + "/s"); |
| |
| if (cmd.hasOption("f")) |
| r.add("-log", "file=" + cmd.getOptionValue("f")); |
| |
| if (cmd.hasOption("p")) |
| r.add("-port", cmd.getOptionValue("p")); |
| |
| if (cmd.hasOption("i")) |
| r.add("-log", "interval=" + cmd.getOptionValue("i")); |
| else |
| r.add("-log", "interval=10"); |
| |
| if (cmd.hasOption("x")) |
| r.add("-schema", "index=" + cmd.getOptionValue("x")); |
| |
| if (cmd.hasOption("R") || cmd.hasOption("l") || cmd.hasOption("O")) |
| { |
| StringBuilder rep = new StringBuilder(); |
| if (cmd.hasOption("R")) |
| rep.append("strategy=").append(cmd.getOptionValue("R")); |
| if (cmd.hasOption("l")) |
| { |
| if (rep.length() > 0) |
| rep.append(","); |
| rep.append("factor=").append(cmd.getOptionValue("l")); |
| } |
| if (cmd.hasOption("O")) |
| { |
| if (rep.length() > 0) |
| rep.append(","); |
| rep.append(cmd.getOptionValue("O").replace(':','=')); |
| } |
| r.add("-schema", "replication(" + rep + ")"); |
| } |
| |
| r.add("-mode", (cmd.hasOption("P") ? "prepared" : "") + "native" + "cql3"); |
| |
| if (cmd.hasOption("I")) |
| r.add("-schema", "compression=" + cmd.getOptionValue("I")); |
| |
| if (cmd.hasOption("d")) |
| r.add("-node", cmd.getOptionValue("d")); |
| |
| if (cmd.hasOption("D")) |
| r.add("-node", "file=" + cmd.getOptionValue("D")); |
| |
| if (cmd.hasOption("Z")) |
| r.add("-schema", "compaction=" + cmd.getOptionValue("Z")); |
| |
| if (cmd.hasOption("ns")) |
| r.add("-log", "no-summary"); |
| |
| if(cmd.hasOption(SSL_TRUSTSTORE)) |
| r.add("-transport", "truststore=" + cmd.getOptionValue(SSL_TRUSTSTORE)); |
| |
| if(cmd.hasOption(SSL_TRUSTSTORE_PW)) |
| r.add("-transport", "truststore-password=" + cmd.getOptionValue(SSL_TRUSTSTORE_PW)); |
| |
| if(cmd.hasOption(SSL_PROTOCOL)) |
| r.add("-transport", "ssl-protocol=" + cmd.getOptionValue(SSL_PROTOCOL)); |
| |
| if(cmd.hasOption(SSL_ALGORITHM)) |
| r.add("-transport", "ssl-alg=" + cmd.getOptionValue(SSL_ALGORITHM)); |
| |
| if(cmd.hasOption(SSL_STORE_TYPE)) |
| r.add("-transport", "store-type=" + cmd.getOptionValue(SSL_STORE_TYPE)); |
| |
| if(cmd.hasOption(SSL_CIPHER_SUITES)) |
| r.add("-transport", "ssl-ciphers=" + cmd.getOptionValue(SSL_CIPHER_SUITES)); |
| |
| } |
| catch (ParseException e) |
| { |
| printHelpMessage(); |
| System.exit(1); |
| } |
| |
| r.printNewCommand(); |
| return r.get(); |
| } |
| |
| private static final class Converter |
| { |
| private Map<String, List<String>> opts = new LinkedHashMap<>(); |
| List<String> command; |
| public void add(String option, String suboption) |
| { |
| if (option.equals("command")) |
| { |
| command.add(suboption); |
| return; |
| } |
| List<String> params = opts.get(option); |
| if (params == null) |
| opts.put(option, params = new ArrayList()); |
| params.add(suboption); |
| } |
| StressSettings get(){ |
| Map<String, String[]> clArgs = new HashMap<>(); |
| for (Map.Entry<String, List<String>> e : opts.entrySet()) |
| clArgs .put(e.getKey(), e.getValue().toArray(new String[0])); |
| return StressSettings.get(clArgs); |
| } |
| void setCommand(String command) |
| { |
| command = Command.get(command).toString().toLowerCase(); |
| opts.put(command, this.command = new ArrayList<>()); |
| } |
| void printNewCommand() |
| { |
| StringBuilder sb = new StringBuilder("stress"); |
| for (Map.Entry<String, List<String>> e : opts.entrySet()) |
| { |
| sb.append(" "); |
| sb.append(e.getKey()); |
| for (String opt : e.getValue()) |
| { |
| sb.append(" "); |
| sb.append(opt); |
| } |
| } |
| System.out.println("Running in legacy support mode. Translating command to: "); |
| System.out.println(sb.toString()); |
| } |
| } |
| |
| public static void printHelpMessage() |
| { |
| System.out.println("Usage: ./bin/cassandra-stress legacy [options]\n\nOptions:"); |
| System.out.println("THIS IS A LEGACY SUPPORT MODE"); |
| |
| for(Object o : availableOptions.getOptions()) |
| { |
| Option option = (Option) o; |
| String upperCaseName = option.getLongOpt().toUpperCase(); |
| System.out.println(String.format("-%s%s, --%s%s%n\t\t%s%n", option.getOpt(), (option.hasArg()) ? " "+upperCaseName : "", |
| option.getLongOpt(), (option.hasArg()) ? "="+upperCaseName : "", option.getDescription())); |
| } |
| } |
| |
| public static Runnable helpPrinter() |
| { |
| return new Runnable() |
| { |
| @Override |
| public void run() |
| { |
| printHelpMessage(); |
| } |
| }; |
| } |
| |
| } |