package com.zendesk.maxwell.bootstrap;
import joptsimple.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
import java.util.Map;
import java.io.IOException;
import com.zendesk.maxwell.util.AbstractConfig;
public class MaxwellBootstrapUtilityConfig extends AbstractConfig {
static final Logger LOGGER = LoggerFactory.getLogger(MaxwellBootstrapUtilityConfig.class);
public String mysqlHost;
public Integer mysqlPort;
public String mysqlUser;
public String mysqlPassword;
public String databaseName;
public String schemaDatabaseName;
public String tableName;
public String whereClause;
public String log_level;
public Long abortBootstrapID;
public Long monitorBootstrapID;
public MaxwellBootstrapUtilityConfig(String argv[]) {
this.parse(argv);
this.setDefaults();
}
public String getConnectionURI( ) {
return "jdbc:mysql://" + mysqlHost + ":" + mysqlPort + "/" + schemaDatabaseName;
}
protected OptionParser buildOptionParser() {
OptionParser parser = new OptionParser();
parser.accepts( "config", "location of config file" ).withRequiredArg();
parser.accepts( "__separator_1", "" );
parser.accepts( "database", "database that contains the table to bootstrap").withRequiredArg();
parser.accepts( "table", "table to bootstrap").withRequiredArg();
parser.accepts( "where", "where clause to restrict the rows bootstrapped from the specified table. e.g. my_date >= '2017-01-01 11:07:13'").withOptionalArg();
parser.accepts( "__separator_2", "" );
parser.accepts( "abort", "bootstrap_id to abort" ).withRequiredArg();
parser.accepts( "monitor", "bootstrap_id to monitor" ).withRequiredArg();
parser.accepts( "__separator_3", "" );
parser.accepts( "log_level", "log level, one of DEBUG|INFO|WARN|ERROR. default: WARN" ).withRequiredArg();
parser.accepts( "host", "mysql host. default: localhost").withRequiredArg();
parser.accepts( "user", "mysql username. default: maxwell" ).withRequiredArg();
parser.accepts( "password", "mysql password" ).withRequiredArg();
parser.accepts( "port", "mysql port. default: 3306" ).withRequiredArg();
parser.accepts( "schema_database", "database that contains maxwell schema and state").withRequiredArg();
parser.accepts( "help", "display help").forHelp();
BuiltinHelpFormatter helpFormatter = new BuiltinHelpFormatter(200, 4) {
@Override
public String format(Map<String, ? extends OptionDescriptor> options) {
this.addRows(options.values());
String output = this.formattedHelpOutput();
return output.replaceAll("--__separator_.*", "");
}
};
parser.formatHelpWith(helpFormatter);
return parser;
}
private String parseLogLevel(String level) {
level = level.toLowerCase();
if ( !( level.equals("debug") || level.equals("info") || level.equals("warn") || level.equals("error")))
usage("unknown log level: " + level);
return level;
}
private void parse(String [] argv) {
OptionSet options = buildOptionParser().parse(argv);
if ( options.has("config") ) {
parseFile((String) options.valueOf("config"), true);
} else {
parseFile(DEFAULT_CONFIG_FILE, false);
}
if ( options.has("help") )
usage("Help for Maxwell Bootstrap Utility:\n\nPlease provide one of:\n--database AND --table, --abort ID, or --monitor ID");
if ( options.has("log_level"))
this.log_level = parseLogLevel((String) options.valueOf("log_level"));
if ( options.has("host"))
this.mysqlHost = (String) options.valueOf("host");
if ( options.has("user"))
this.mysqlUser = (String) options.valueOf("user");
if ( options.has("password"))
this.mysqlPassword = (String) options.valueOf("password");
if ( options.has("port"))
this.mysqlPort = Integer.valueOf((String) options.valueOf("port"));
if ( options.has("schema_database"))
this.schemaDatabaseName = (String) options.valueOf("schema_database");
if ( options.has("database") )
this.databaseName = (String) options.valueOf("database");
else if ( !options.has("abort") && !options.has("monitor") )
usage("please specify a database");
if ( options.has("abort") ) {
this.abortBootstrapID = Long.valueOf((String) options.valueOf("abort"));
}
if ( options.has("monitor") )
this.monitorBootstrapID = Long.valueOf((String) options.valueOf("monitor"));
if ( this.abortBootstrapID != null ) {
if ( this.monitorBootstrapID != null )
usage("--abort is incompatible with --monitor");
if ( this.databaseName != null )
usage("--abort is incompatible with --database and --table");
}
if ( this.monitorBootstrapID != null ) {
if ( this.databaseName != null )
usage("--monitor is incompatible with --database and --table");
}
if ( options.has("table") )
this.tableName = (String) options.valueOf("table");
else if ( !options.has("abort") && !options.has("monitor") )
usage("please specify a table");
if ( options.has("where") && !StringUtils.isEmpty(((String) options.valueOf("where"))) )
this.whereClause = (String) options.valueOf("where");
}
private void parseFile(String filename, boolean abortOnMissing) {
Properties p = this.readPropertiesFile(filename, abortOnMissing);
if ( p == null )
return;
this.mysqlHost = p.getProperty("host");
this.mysqlUser = p.getProperty("user", "maxwell");
this.mysqlPort = Integer.valueOf(p.getProperty("port", "3306"));
this.mysqlPassword = p.getProperty("password");
this.schemaDatabaseName = p.getProperty("schema_database", "maxwell");
}
private void setDefaults() {
if ( this.log_level == null ) {
this.log_level = "WARN";
}
if ( this.mysqlHost == null ) {
LOGGER.warn("mysql host not specified, defaulting to localhost");
this.mysqlHost = "localhost";
}
}
}