com.linkedin.databus.util.InteractiveSchemaGeneratorCli.java Source code

Java tutorial

Introduction

Here is the source code for com.linkedin.databus.util.InteractiveSchemaGeneratorCli.java

Source

package com.linkedin.databus.util;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* 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.
*
*/

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;

import com.linkedin.databus.core.BaseCli;

/**
 * Command-line interface for {@link InteractiveSchemaGenerator}
 * <preformat>
 * usage: java com.linkedin.databus.util.InteractiveSchemaGenerator [options]
 * -A,--automatic                   Answer all questions proved through cli automatically and interactive for the rest of the options.
 * -b,--database <db_name>          the name of database
 * -D,--dburl <url>                 DB URL to read view/table definitions
 * -f,--fields <fields>             comma-separated list of table/view fields to include in the schema
 * -h,--help                        Prints command-line options info
 * -k,--pk <keys>                   comma-separated list of primary keys of view/table
 * -l,--log_props <property_file>   Log4j properties to use
 * -p,--password <password>         DB password
 * -q,--quiet                       turn off logging
 * -S,--schema_reg_path <path>      path where to checkout the schema registry
 * -t,--table <table_name>          name of the table/view whose schema to generate
 * -u,--username <user>             DB username
 * -n, --namespace <namespace>      Namespace prefix
 * -v                               verbose
 * -vv                              more verbose
 * -vvv                             most verbose
 * </preformat>
 */
public class InteractiveSchemaGeneratorCli extends BaseCli {
    private static char AUTOMATIC_OPT_CHAR = 'A';
    private static char CHECKOUT_SCHEMA_REGISTRY_CHAR = 'C';
    private static char DBNAME_OPT_CHAR = 'b';
    private static char DBURL_OPT_CHAR = 'D';
    private static char FIELDS_OPT_CHAR = 'f';
    private static char PK_OPT_CHAR = 'k';
    private static char PASSWORD_OPT_CHAR = 'p';
    private static char TABLE_OPT_CHAR = 't';
    private static char USER_OPT_CHAR = 'u';
    private static char SCHEMA_REGISTRY_PATH_OPT_CHAR = 'S';
    private static char NUMBEROVERRIDE_OPT_CHAR = 'N';
    private static char NAMESPACE_OPT_CHAR = 'n';

    private static String AUTOMATIC_OPT_NAME = "automatic";
    private static String CHECKOUT_SCHEMA_REGISTRY_NAME = "checkout_schema_registy";
    private static String DBNAME_OPT_NAME = "database";
    private static String DBURL_OPT_NAME = "dburl";
    private static String FIELDS_OPT_NAME = "fields";
    private static String PASSWORD_OPT_NAME = "password";
    private static String PK_OPT_NAME = "pk";
    private static String TABLE_OPT_NAME = "table";
    private static String USER_OPT_NAME = "username";
    private static String SCHEMA_REGISTRY_PATH_OPT_NAME = "schema_reg_path";
    private static String NUMBEROVERRIDE_OPT_NAME = "number_override_map";
    private static String NAMESPACE_OPT_NAME = "namespace";

    private boolean _automatic = Boolean.FALSE;
    private boolean _checkoutSchemaRegistryLocation = Boolean.FALSE;
    private String _dbName;
    private String _dburl = InteractiveSchemaGenerator.DEFAULT_DATABASE;
    private List<String> _fields;
    private String _password;
    private List<String> _primaryKeys;
    private String _schemaRegPath = InteractiveSchemaGenerator.DEFAULT_SCHEMA_REGISTRY_LOCATION;
    private String _table;
    private String _user;
    private HashMap<String, String> _dbFieldToAvroDataType = null;
    private String _namespace = InteractiveSchemaGenerator.NAMESPACE_PREFIX;

    public InteractiveSchemaGeneratorCli() {
        super(createDefaultUsageString(InteractiveSchemaGenerator.class), null);
    }

    @SuppressWarnings("static-access")
    @Override
    protected void constructCommandLineOptions() {
        super.constructCommandLineOptions();

        Option automaticOption = OptionBuilder.withLongOpt(AUTOMATIC_OPT_NAME).withDescription(
                "Answer all questions proved through cli automatically and interactive for the rest of the options.")
                .create(AUTOMATIC_OPT_CHAR);
        Option checkoutSchemaRegistryOption = OptionBuilder.withLongOpt(CHECKOUT_SCHEMA_REGISTRY_NAME)
                .withDescription("Use Source Control tool to checkout schema.")
                .create(CHECKOUT_SCHEMA_REGISTRY_CHAR);
        Option dbnameOption = OptionBuilder.withLongOpt(DBNAME_OPT_NAME).hasArg().withArgName("db_name")
                .withDescription("The name of database").create(DBNAME_OPT_CHAR);
        Option dburlOption = OptionBuilder.withLongOpt(DBURL_OPT_NAME).hasArg().withArgName("url")
                .withDescription("DB URL to read view/table definitions").create(DBURL_OPT_CHAR);
        Option fieldsOption = OptionBuilder.withLongOpt(FIELDS_OPT_NAME).hasArg().withArgName("fields")
                .withDescription("Comma-separated list of table/view fields to include in the schema")
                .create(FIELDS_OPT_CHAR);
        Option passwordOption = OptionBuilder.withLongOpt(PASSWORD_OPT_NAME).hasArg().withArgName("password")
                .withDescription("DB password").create(PASSWORD_OPT_CHAR);
        Option pkOption = OptionBuilder.withLongOpt(PK_OPT_NAME).hasArg().withArgName("keys")
                .withDescription("Comma-separated list of primary keys of view/table").create(PK_OPT_CHAR);
        Option tableOption = OptionBuilder.withLongOpt(TABLE_OPT_NAME).hasArg().withArgName("table_name")
                .withDescription("The name of the table/view whose schema to generate ").create(TABLE_OPT_CHAR);
        Option userOption = OptionBuilder.withLongOpt(USER_OPT_NAME).hasArg().withArgName("user")
                .withDescription("DB username").create(USER_OPT_CHAR);
        Option schemaRegPathOption = OptionBuilder.withLongOpt(SCHEMA_REGISTRY_PATH_OPT_NAME).hasArg()
                .withArgName("path").withDescription("The path where to checkout the schema registry")
                .create(SCHEMA_REGISTRY_PATH_OPT_CHAR);

        Option numberOverrideOption = OptionBuilder.withLongOpt(NUMBEROVERRIDE_OPT_NAME).hasArg()
                .withArgName("path")
                .withDescription(
                        "Override number fields datatype with FLOAT, LONG, INTEGER, DOUBLE. Input as, DB_FIELD_NAME1=FLOAT,DB_FIELD_NAME2=DOUBLE")
                .create(NUMBEROVERRIDE_OPT_CHAR);

        Option namespaceOption = OptionBuilder.withLongOpt(NAMESPACE_OPT_NAME).hasArg().withArgName("namespace")
                .withDescription("The name of namespace prefix").create(NAMESPACE_OPT_CHAR);

        _cliOptions.addOption(automaticOption);
        _cliOptions.addOption(checkoutSchemaRegistryOption);
        _cliOptions.addOption(dbnameOption);
        _cliOptions.addOption(dburlOption);
        _cliOptions.addOption(fieldsOption);
        _cliOptions.addOption(passwordOption);
        _cliOptions.addOption(pkOption);
        _cliOptions.addOption(tableOption);
        _cliOptions.addOption(userOption);
        _cliOptions.addOption(schemaRegPathOption);
        _cliOptions.addOption(numberOverrideOption);
        _cliOptions.addOption(namespaceOption);
    }

    @Override
    public boolean processCommandLineArgs(String[] cliArgs) {
        boolean success = super.processCommandLineArgs(cliArgs);
        if (!success) {
            return false;
        }

        _automatic = _cmd.hasOption(AUTOMATIC_OPT_CHAR);
        _checkoutSchemaRegistryLocation = _cmd.hasOption(CHECKOUT_SCHEMA_REGISTRY_CHAR);

        if (_cmd.hasOption(DBNAME_OPT_CHAR)) {
            _dbName = _cmd.getOptionValue(DBNAME_OPT_CHAR).trim();
        }

        if (_cmd.hasOption(DBURL_OPT_CHAR)) {
            _dburl = _cmd.getOptionValue(DBURL_OPT_CHAR).trim();
        }

        if (_cmd.hasOption(FIELDS_OPT_CHAR)) {
            String fieldsStr = _cmd.getOptionValue(FIELDS_OPT_CHAR).trim();
            String[] fields = fieldsStr.split("[, ]+");
            _fields = Collections.unmodifiableList(Arrays.asList(fields));
        }

        if (_cmd.hasOption(PASSWORD_OPT_CHAR)) {
            _password = _cmd.getOptionValue(PASSWORD_OPT_CHAR);
        }

        if (_cmd.hasOption(PK_OPT_CHAR)) {
            String pkStr = _cmd.getOptionValue(PK_OPT_CHAR).trim();
            String[] pks = pkStr.split("[, ]+");
            _primaryKeys = Collections.unmodifiableList(Arrays.asList(pks));
        } else {
            _primaryKeys = Collections.unmodifiableList(Arrays.asList(new String[0]));
        }

        if (_cmd.hasOption(TABLE_OPT_CHAR)) {
            _table = _cmd.getOptionValue(TABLE_OPT_CHAR).trim();
        }

        if (_cmd.hasOption(USER_OPT_CHAR)) {
            _user = _cmd.getOptionValue(USER_OPT_CHAR).trim();
        }

        if (_cmd.hasOption(SCHEMA_REGISTRY_PATH_OPT_CHAR)) {
            _schemaRegPath = _cmd.getOptionValue(SCHEMA_REGISTRY_PATH_OPT_CHAR).trim();
        }

        if (_cmd.hasOption(NUMBEROVERRIDE_OPT_CHAR)) {
            _dbFieldToAvroDataType = new HashMap<String, String>();
            String mapList = _cmd.getOptionValue(NUMBEROVERRIDE_OPT_CHAR).trim();
            String[] mapElements = mapList.split(",");
            for (String mapElement : mapElements) {
                String[] dbFieldToDatatype = mapElement.split("=");
                _dbFieldToAvroDataType.put(dbFieldToDatatype[0].trim(), dbFieldToDatatype[1].trim());
            }
        }

        if (_cmd.hasOption(NAMESPACE_OPT_CHAR)) {
            _namespace = _cmd.getOptionValue(NAMESPACE_OPT_CHAR).trim();
        }

        return true;
    }

    /** For testing */
    public static void main(String[] args) {

        for (int i = 0; i < args.length; i++)
            System.out.println("Arg[" + i + "] = " + args[i]);

        String[] finalArgs;
        if (args.length > 1 && args[0].equals("-c")) //Python drive is going to pass all args in a "-c"
        {
            finalArgs = args[1].split("\\s");
        } else {
            finalArgs = args;
        }

        InteractiveSchemaGeneratorCli cli = new InteractiveSchemaGeneratorCli();
        if (!cli.processCommandLineArgs(finalArgs))
            return;
        try {
            System.out.println("Starting the schema generation with cli options: " + cli.toString());
            InteractiveSchemaGenerator automaticSchemaGeneration = new InteractiveSchemaGenerator(cli);
            automaticSchemaGeneration.runSchemaGenTool();
        } catch (Exception e) {
            System.out.println("Error running the schema generation tool");
            e.printStackTrace();
            System.exit(1);
        }
    }

    /** The path to the schema registry */
    public String getSchemaRegistryPath() {
        return _schemaRegPath;
    }

    /** Whether all questions should be answered automatically */
    public boolean isAutomatic() {
        return _automatic;
    }

    /** Whether Source Control System should be used to checkout schemas */
    public boolean isCheckoutSchemaRegistryLocation() {
        return _checkoutSchemaRegistryLocation;
    }

    /** The db url to read table/view definitions */
    public String getDburl() {
        return _dburl;
    }

    /** DB user name */
    public String getUser() {
        return _user;
    }

    /** DB password */
    public String getPassword() {
        return _password;
    }

    /** The database/Oracle schema name*/
    public String getDbName() {
        return _dbName;
    }

    /** Table/view name */
    public String getTableName() {
        return _table;
    }

    /** Primary key(s) of the table/view*/
    public List<String> getPrimaryKeys() {
        return _primaryKeys;
    }

    /** List of table/view fields to include in the generated schema */
    public List<String> getFields() {
        return _fields;
    }

    /** The namespace prefix name*/
    public String getNamespace() {
        return _namespace;
    }

    @Override
    public String toString() {
        return "InteractiveSchemaGeneratorCli{" + "_automatic=" + _automatic + ", _checkoutSchemaRegistryOption="
                + _checkoutSchemaRegistryLocation + ", _dbName='" + _dbName + '\'' + ", _dburl='" + _dburl + '\''
                + ", _fields=" + _fields + ", _password='" + _password + '\'' + ", _primaryKeys=" + _primaryKeys
                + ", _schemaRegPath='" + _schemaRegPath + '\'' + ", _table='" + _table + '\'' + ", _user='" + _user
                + '\'' + ", _dbFieldToAvroDataType=" + _dbFieldToAvroDataType + ", _namespace=" + _namespace + '}';
    }

    public HashMap<String, String> getDbFieldToAvroDataType() {
        return _dbFieldToAvroDataType;
    }

}