/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.dbcli; import java.io.File; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { private static final Logger log = LoggerFactory.getLogger(Main.class); private static DbCli dbCli = null; private static String ID_MARK = "-i"; private static String FILE_MARK = "-f"; private static final String LIST_ACTIVE = "-activeonly"; private static final String LIST_LIMIT = "-limit"; private static final String REGEX_NUMBERS = "\\d+"; private static final String SKIP_MIGRATION_CHECK = "-bypassMigrationCheck"; private static ClassPathXmlApplicationContext ctx = null; private enum Command { HELP { int validArgs(String[] args) { return 0; } }, SHOW_CF { int validArgs(String[] args) { return 0; } }, SHOW_SCHEMA { int validArgs(String[] args) { if (args.length < 2) { throw new IllegalArgumentException("Invalid command:need at least 2 arguments"); } return 0; } }, DUMP { int validArgs(String[] args) { if (args.length < 6) { throw new IllegalArgumentException("Invalid command:need at least 6 arguments"); } if (!args[1].equals(ID_MARK) || !args[3].equals(FILE_MARK)) { throw new IllegalArgumentException(String.format("Invalid parameter: %s", args[1])); } return 0; } }, LOAD { int validArgs(String[] args) { if (args.length < 3) { throw new IllegalArgumentException("Invalid command:need at least 3 arguments"); } if (!args[1].equals(FILE_MARK)) { throw new IllegalArgumentException(String.format("Invalid parameter: %s", args[1])); } return 0; } }, DELETE { int validArgs(String[] args) { if (args.length < 4) { throw new IllegalArgumentException("Invalid command:need at least 4 arguments"); } if (!args[1].equals(ID_MARK)) { throw new IllegalArgumentException(String.format("Invalid parameter: %s", args[1])); } return 0; } }, LIST { int validArgs(String[] args) { if (args.length < 2) { throw new IllegalArgumentException("Invalid command:need at least 2 arguments"); } // List all records. if (args[1].equalsIgnoreCase(LIST_ACTIVE) || args[1].equalsIgnoreCase(LIST_LIMIT) || !args[1].equalsIgnoreCase(ID_MARK)) { return 0; } // List records based on ids if (args.length < 4) { throw new IllegalArgumentException("Invalid command:need at least 4 arguments"); } if (!args[1].equals(ID_MARK)) { throw new IllegalArgumentException(String.format("Invalid parameter: %s", args[1])); } return 1; } }, CREATE { int validArgs(String[] args) { if (args.length < 3) { throw new IllegalArgumentException("Invalid command:need at least 3 arguments"); } if (!args[1].equals(FILE_MARK)) { throw new IllegalArgumentException(String.format("Invalid parameter: %s", args[1])); } return 0; } }; abstract int validArgs(String[] args); } private static void usage() { System.out.println("Usage: "); System.out.println(String.format("\t%s %s <File Name>", Command.CREATE.name().toLowerCase(), FILE_MARK)); System.out.println(String.format("\t%s %s \"id1,id2,...\" <Column Family Name>", Command.DELETE.name().toLowerCase(), ID_MARK)); System.out.println(String.format("\t%s %s \"id1,id2,...\" %s <File Name> <Column Family Name>", Command.DUMP.name().toLowerCase(), ID_MARK, FILE_MARK)); System.out.println(String.format("\t%s %s <File Name>", Command.LOAD.name().toLowerCase(), FILE_MARK)); System.out.println(String.format("\t%s %s \"id1,id2,...\" <Column Family Name>", Command.LIST.name().toLowerCase(), ID_MARK)); System.out.println(String.format("\t%s [%s <n>] [%s] <Column Family Name>", Command.LIST.name().toLowerCase(), LIST_LIMIT, LIST_ACTIVE)); System.out.println(String.format("\t\t%s <n>\t List paginated with a limit of <n>, " + "if <n> is missing, default is 100.", LIST_LIMIT)); System.out.println(String.format("\t\t%s\t List exclude inactive object ids.", LIST_ACTIVE)); System.out.println(String.format("\t%s", Command.HELP.name().toLowerCase())); System.out.println(String.format("\t%s", Command.SHOW_CF.name().toLowerCase())); System.out.println(String.format("\t%s <Column Family Name>", Command.SHOW_SCHEMA.name().toLowerCase())); System.out.printf("\t -bypassMigrationCheck%n"); System.out .printf("\t\tNote: it's used with other commands together only when migration fail, dbcli still work even migration fail if you pass this option\n"); } public static void main(String[] args) { if (args.length == 0) { usage(); return; } boolean skipMigrationCheck = skipMigrationCheck(args); // it's a hack of passed arg since we already hard-coded // parameter position in args array. if (skipMigrationCheck) { args = removeMigrationCheckArg(args); } Command cmd; try { cmd = Command.valueOf(args[0].trim().toUpperCase()); } catch (IllegalArgumentException e) { System.err.println("Invalid command " + args[0]); usage(); return; } try { // Suppress Sonar violation of Lazy initialization of static fields should be synchronized // This is a CLI application and main method will not be called by multiple threads ctx = new ClassPathXmlApplicationContext("/dbcli-conf.xml"); // NOSONAR ("squid:S2444") dbCli = (DbCli) ctx.getBean("dbcli"); // NOSONAR ("squid:S2444") dbCli.start(skipMigrationCheck); String cfName = null; String[] ids; String fileName; switch (cmd) { case HELP: usage(); break; case SHOW_CF: try { dbCli.printCfMaps(); } catch (Exception e) { System.out.println(String.format("Exception %s%n in printing column families' info.", e)); log.error("Exception in printing column families' info.", e); } break; case SHOW_SCHEMA: cmd.validArgs(args); cfName = args[1]; try { dbCli.printFieldsByCf(cfName); } catch (Exception e) { System.out.println(String.format("Exception %s%n in printing %s's fields info.", e, cfName)); log.error("Exception in priting {}'s fields info.", cfName, e); } break; case DUMP: cmd.validArgs(args); ids = args[2].split(","); fileName = args[4]; cfName = args[5]; dbCli.initDbClient(); try { dbCli.queryForDump(cfName, fileName, ids); } catch (Exception e) { System.out.println(String.format("Exception %s%n in dumping column family:%s into file:%s.", e, cfName, fileName)); log.error("Exception in dumping column family:{} into file.", cfName, e); } break; case LOAD: cmd.validArgs(args); fileName = args[2]; if (!new File(fileName).exists()) { throw new IllegalArgumentException(String.format("File: %s does not exist.", fileName)); } dbCli.initDbClient(); try { dbCli.loadFileAndPersist(fileName); } catch (Exception e) { System.out.println(String.format("Exception %s%n in load file:%s into database.", e, fileName)); log.error("Exception in loading file{} into database.", fileName, e); } break; case DELETE: cmd.validArgs(args); ids = args[2].split(","); cfName = args[3]; dbCli.initDbClient(); try { dbCli.deleteRecords(cfName, ids, true); } catch (Exception e) { System.out.println(String.format("Exception %s%n in deleting column family.", e)); log.error("Exception in deleting column familiy.", e); } break; case LIST: dbCli.initDbClient(); int result = cmd.validArgs(args); if (result == 0) { processListArgs(args, dbCli); cfName = args[args.length - 1]; try { dbCli.listRecords(cfName); } catch (Exception e) { System.out.println(String.format("Exception %s in listing records.", e)); log.error("Exception in listing records.", e); } break; } ids = args[2].split(","); cfName = args[3]; try { dbCli.queryForList(cfName, ids); } catch (Exception e) { System.out.println(String.format("Exception %s%n in listing column family.", e)); log.error("Exception in listing column family.", e); } break; case CREATE: cmd.validArgs(args); fileName = args[2]; if (!new File(fileName).exists()) { throw new IllegalArgumentException(String.format("File: %s does not exist.", fileName)); } dbCli.initDbClient(); try { dbCli.loadFileAndCreate(fileName); } catch (Exception e) { System.out.println(String.format("Exception %s%n in load file:%s into database.", e, fileName)); log.error("Exception in loading file{} into database.", fileName, e); } break; default: throw new IllegalArgumentException("Invalid command"); } } catch (Exception e) { System.err.println("Exception e=" + e); usage(); } finally { stop(); } } /** * Stop client and exit */ private static void stop() { if (dbCli != null) { dbCli.stop(); } System.exit(0); } private static void processListArgs(String[] args, DbCli dbCli) { if (args[args.length - 1].equalsIgnoreCase(LIST_LIMIT) || args[args.length - 1].equalsIgnoreCase(LIST_ACTIVE) || args[args.length - 1].matches(REGEX_NUMBERS)) { System.err.println("The Column Family Name is missing"); throw new IllegalArgumentException("The Column Family Name is missing"); } for (int i = 1; i < args.length - 1; i++) { if (args[i].equalsIgnoreCase(LIST_ACTIVE)) { dbCli.setActiveOnly(true); } if (args[i].equalsIgnoreCase(LIST_LIMIT)) { dbCli.setTurnOnLimit(true); if (args[i + 1].matches(REGEX_NUMBERS)) { dbCli.setListLimit(Integer.valueOf(args[i + 1])); i++; } } } } private static String[] removeMigrationCheckArg(String[] args) { List<String> tmpArgs = new ArrayList<String>(); for (String arg : args) { if (arg != null && arg.equals(SKIP_MIGRATION_CHECK)) { continue; } tmpArgs.add(arg); } return tmpArgs.toArray(new String[tmpArgs.size()]); } private static boolean skipMigrationCheck(String[] args) { for (String arg : args) { if (arg != null && arg.equals(SKIP_MIGRATION_CHECK)) { return true; } } return false; } }