com.orientechnologies.orient.stresstest.OStressTesterCommandLineParser Maven / Gradle / Ivy
The newest version!
/*
*
* * Copyright 2010-2016 OrientDB LTD (http://orientdb.com)
* *
* * Licensed 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.
* *
* * For more information: http://orientdb.com
*
*/
package com.orientechnologies.orient.stresstest;
import com.orientechnologies.orient.client.remote.OStorageRemote;
import com.orientechnologies.orient.stresstest.workload.OWorkload;
import java.io.Console;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* This is the parser of the command line arguments passed with the invocation of OStressTester. It
* contains a static method that - given the arguments - returns a OStressTester object.
*
* @author Andrea Iacono
*/
public class OStressTesterCommandLineParser {
public static final String TEMP_DATABASE_NAME = "stress-test-db-";
public static final String CONSOLE_REMOTE_PASSWORD_PROMPT =
"OrientDB Server (%s:%d) - Please insert the root password to create the test database: ";
public static final String OPTION_CONCURRENCY = "c";
public static final String OPTION_MODE = "m";
public static final String OPTION_WORKLOAD = "w";
public static final String OPTION_TRANSACTIONS = "tx";
public static final String OPTION_DELAY = "delay";
public static final String OPTION_KEEP_DATABASE_AFTER_TEST = "k";
public static final String OPTION_OUTPUT_FILE = "o";
public static final String OPTION_PLOCAL_PATH = "d";
public static final String OPTION_LOAD_BALANCING = "lb";
public static final String OPTION_DBNAME = "db";
public static final String OPTION_CHECK_DATABASE = "chk";
public static final String OPTION_ROOT_PASSWORD = "root-password";
public static final String ERROR_OPENING_CONSOLE =
"An error has occurred opening the console. Please supply the root password as the -"
+ OPTION_ROOT_PASSWORD
+ " parameter.";
public static final String OPTION_REMOTE_IP = "remote-ip";
public static final String OPTION_HA_METRICS = "ha-metrics";
public static final String COMMAND_LINE_PARSER_MISSING_REMOTE_IP =
"The mode is ["
+ OStressTester.OMode.REMOTE
+ "] but the param --"
+ OPTION_REMOTE_IP
+ " wasn't passed.";
public static final String OPTION_REMOTE_PORT = "remote-port";
public static final String MAIN_OPTIONS =
OPTION_MODE
+ OPTION_CONCURRENCY
+ OPTION_WORKLOAD
+ OPTION_TRANSACTIONS
+ OPTION_DELAY
+ OPTION_OUTPUT_FILE
+ OPTION_PLOCAL_PATH
+ OPTION_KEEP_DATABASE_AFTER_TEST
+ OPTION_CHECK_DATABASE
+ OPTION_LOAD_BALANCING
+ OPTION_DBNAME;
public static final String SYNTAX =
"StressTester "
+ "\n\t-m mode (can be any of these: [plocal|memory|remote|distributed] )"
+ "\n\t-w workloads"
+ "\n\t-c concurrency-level"
+ "\n\t-x operations-per-transaction"
+ "\n\t-o result-output-file"
+ "\n\t-d database-directory"
+ "\n\t-k true|false"
+ "\n\t-chk true|false"
+ "\n\t--root-password rootPassword"
+ "\n\t--remote-ip ipOrHostname"
+ "\n\t--remote-port portNumber"
+ "\n\t-lb load-balancing-strategy"
+ "\n\t-db db-name"
+ "\n";
static final String COMMAND_LINE_PARSER_INVALID_NUMBER = "Invalid %s number [%s].";
static final String COMMAND_LINE_PARSER_LESSER_THAN_ZERO_NUMBER =
"The %s value must be greater than 0.";
static final String COMMAND_LINE_PARSER_INVALID_MODE = "Invalid mode [%s].";
static final String COMMAND_LINE_PARSER_INVALID_OPTION = "Invalid option [%s]";
static final String COMMAND_LINE_PARSER_EXPECTED_VALUE = "Expected value after argument [%s]";
static final String COMMAND_LINE_PARSER_INVALID_REMOTE_PORT_NUMBER =
"Invalid remote port [%d]. The port number has to be lesser than 65536.";
static final String COMMAND_LINE_PARSER_MODE_PARAM_MANDATORY =
"The mode param [-m] is mandatory.";
static final String COMMAND_LINE_PARSER_NOT_EXISTING_OUTPUT_DIRECTORY =
"The directory where to write the resultOutputFile [%s] doesn't exist.";
static final String COMMAND_LINE_PARSER_NOT_EXISTING_PLOCAL_PATH =
"The plocal directory (param -d) doesn't exist [%s].";
static final String COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_OUTPUT_FILE =
"You don't have the permissions for writing on directory [%s] the resultOutputFile.";
static final String COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_PLOCAL_PATH =
"You don't have the permissions for writing on plocal directory [%s].";
static final String COMMAND_LINE_PARSER_PLOCAL_PATH_IS_NOT_DIRECTORY =
"The plocal path [%s] is not a directory.";
/**
* builds a StressTester object using the command line arguments
*
* @param args
* @return
* @throws Exception
*/
public static OStressTester getStressTester(String[] args) throws Exception {
final Map options = checkOptions(readOptions(args));
final OStressTesterSettings settings = new OStressTesterSettings();
settings.dbName =
TEMP_DATABASE_NAME + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
if (options.get(OPTION_DBNAME) != null) settings.dbName = options.get(OPTION_DBNAME);
settings.mode =
OStressTester.OMode.valueOf(options.get(OPTION_MODE).toUpperCase(Locale.ENGLISH));
settings.rootPassword = options.get(OPTION_ROOT_PASSWORD);
settings.resultOutputFile = options.get(OPTION_OUTPUT_FILE);
settings.plocalPath = options.get(OPTION_PLOCAL_PATH);
settings.operationsPerTransaction = getNumber(options.get(OPTION_TRANSACTIONS), "transactions");
settings.delay = getNumber(options.get(OPTION_DELAY), "delay");
settings.concurrencyLevel = getNumber(options.get(OPTION_CONCURRENCY), "concurrency");
settings.remoteIp = options.get(OPTION_REMOTE_IP);
settings.haMetrics =
options.get(OPTION_HA_METRICS) != null
? Boolean.parseBoolean(options.get(OPTION_HA_METRICS))
: false;
settings.workloadCfg = options.get(OPTION_WORKLOAD);
if (options.get(OPTION_KEEP_DATABASE_AFTER_TEST) != null) {
settings.keepDatabaseAfterTest =
Boolean.parseBoolean(options.get(OPTION_KEEP_DATABASE_AFTER_TEST));
} else {
settings.keepDatabaseAfterTest = false;
}
settings.remotePort = 2424;
settings.checkDatabase = Boolean.parseBoolean(options.get(OPTION_CHECK_DATABASE));
if (options.get(OPTION_LOAD_BALANCING) != null)
settings.loadBalancing =
OStorageRemote.CONNECTION_STRATEGY.valueOf(
options.get(OPTION_LOAD_BALANCING).toUpperCase(Locale.ENGLISH));
if (settings.plocalPath != null) {
if (settings.plocalPath.endsWith(File.separator)) {
settings.plocalPath =
settings.plocalPath.substring(
0, settings.plocalPath.length() - File.separator.length());
}
File plocalFile = new File(settings.plocalPath);
if (!plocalFile.exists()) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_NOT_EXISTING_PLOCAL_PATH, settings.plocalPath));
}
if (!plocalFile.canWrite()) {
throw new IllegalArgumentException(
String.format(
COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_PLOCAL_PATH, settings.plocalPath));
}
if (!plocalFile.isDirectory()) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_PLOCAL_PATH_IS_NOT_DIRECTORY, settings.plocalPath));
}
}
if (settings.resultOutputFile != null) {
File outputFile = new File(settings.resultOutputFile);
if (outputFile.exists()) {
outputFile.delete();
}
File parentFile = outputFile.getParentFile();
// if the filename does not contain a path (both relative and absolute)
if (parentFile == null) {
parentFile = new File(".");
}
if (!parentFile.exists()) {
throw new IllegalArgumentException(
String.format(
COMMAND_LINE_PARSER_NOT_EXISTING_OUTPUT_DIRECTORY, parentFile.getAbsoluteFile()));
}
if (!parentFile.canWrite()) {
throw new IllegalArgumentException(
String.format(
COMMAND_LINE_PARSER_NO_WRITE_PERMISSION_OUTPUT_FILE, parentFile.getAbsoluteFile()));
}
}
if (options.get(OPTION_REMOTE_PORT) != null) {
settings.remotePort = getNumber(options.get(OPTION_REMOTE_PORT), "remotePort");
if (settings.remotePort > 65535) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_INVALID_REMOTE_PORT_NUMBER, settings.remotePort));
}
}
if (settings.mode == OStressTester.OMode.DISTRIBUTED) {
throw new IllegalArgumentException(
String.format("OMode [%s] not yet supported.", settings.mode));
}
if (settings.mode == OStressTester.OMode.REMOTE && settings.remoteIp == null) {
throw new IllegalArgumentException(COMMAND_LINE_PARSER_MISSING_REMOTE_IP);
}
if (settings.rootPassword == null && settings.mode == OStressTester.OMode.REMOTE) {
Console console = System.console();
if (console != null) {
settings.rootPassword =
String.valueOf(
console.readPassword(
String.format(
CONSOLE_REMOTE_PASSWORD_PROMPT, settings.remoteIp, settings.remotePort)));
} else {
throw new Exception(ERROR_OPENING_CONSOLE);
}
}
final List workloads = parseWorkloads(settings.workloadCfg);
final ODatabaseIdentifier databaseIdentifier = new ODatabaseIdentifier(settings);
return new OStressTester(workloads, databaseIdentifier, settings);
}
private static List parseWorkloads(final String workloadConfig) {
if (workloadConfig == null || workloadConfig.isEmpty())
throw new IllegalArgumentException(
"Workload parameter is mandatory. Syntax: ");
final List result = new ArrayList();
final String[] parts = workloadConfig.split(",");
for (String part : parts) {
String workloadName;
String workloadParams;
final int pos = part.indexOf(":");
if (pos > -1) {
workloadName = part.substring(0, pos);
workloadParams = part.substring(pos + 1);
} else {
workloadName = part;
workloadParams = null;
}
final OWorkload workload = OStressTester.getWorkloadFactory().get(workloadName);
if (workload == null)
throw new IllegalArgumentException(
"Workload '"
+ workloadName
+ "' is not configured. Use one of the following: "
+ OStressTester.getWorkloadFactory().getRegistered());
workload.parseParameters(workloadParams);
result.add(workload);
}
return result;
}
private static int getNumber(final String value, final String option)
throws IllegalArgumentException {
if (value == null) return 0;
try {
int val = Integer.parseInt(value);
if (val < 0) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_LESSER_THAN_ZERO_NUMBER, option));
}
return val;
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_INVALID_NUMBER, option, value), ex);
}
}
private static Map checkOptions(Map options)
throws IllegalArgumentException {
if (options.get(OPTION_MODE) == null) {
throw new IllegalArgumentException(String.format(COMMAND_LINE_PARSER_MODE_PARAM_MANDATORY));
}
options = setDefaultIfNotPresent(options, OPTION_MODE, OStressTester.OMode.PLOCAL.name());
options = setDefaultIfNotPresent(options, OPTION_CONCURRENCY, "4");
options = setDefaultIfNotPresent(options, OPTION_TRANSACTIONS, "0");
options = setDefaultIfNotPresent(options, OPTION_WORKLOAD, "CRUD:C25000R25000U25000D25000");
try {
OStressTester.OMode.valueOf(options.get(OPTION_MODE).toUpperCase(Locale.ENGLISH));
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_INVALID_MODE, options.get(OPTION_MODE)), ex);
}
return options;
}
private static Map setDefaultIfNotPresent(
Map options, String option, String value) throws IllegalArgumentException {
if (!options.containsKey(option)) {
System.out.println(
String.format("WARNING: '%s' option not found. Defaulting to %s.", option, value));
options.put(option, value);
}
return options;
}
private static Map readOptions(final String[] args)
throws IllegalArgumentException {
final Map options = new HashMap();
// reads arguments from command line
for (int i = 0; i < args.length; i++) {
// an argument cannot be shorter than one char
if (args[i].length() < 2) {
throw new IllegalArgumentException(
String.format(COMMAND_LINE_PARSER_INVALID_OPTION, args[i]));
}
switch (args[i].charAt(0)) {
case '-':
if (args.length - 1 == i) {
throw new IllegalArgumentException(
(String.format(COMMAND_LINE_PARSER_EXPECTED_VALUE, args[i])));
}
String option = args[i].substring(1);
if (option.startsWith("-")) {
option = option.substring(1);
} else {
if (!MAIN_OPTIONS.contains(option)) {
throw new IllegalArgumentException(
(String.format(COMMAND_LINE_PARSER_INVALID_OPTION, args[i])));
}
}
options.put(option, args[i + 1]);
// jumps to the next switch
i++;
break;
}
}
return options;
}
}