jkosh44 commented on a change in pull request #1083: [WIP] POC for Command module with centralized Command Pattern logic URL: https://github.com/apache/fluo/pull/1083#discussion_r357823442
########## File path: modules/command/src/main/java/org/apache/fluo/command/FluoProgram.java ########## @@ -0,0 +1,125 @@ +/* + * 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.fluo.command; + +import java.util.Optional; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; + +import static org.apache.fluo.command.FluoCommandType.CONFIG; +import static org.apache.fluo.command.FluoCommandType.EXEC; +import static org.apache.fluo.command.FluoCommandType.GET_JARS; +import static org.apache.fluo.command.FluoCommandType.INIT; +import static org.apache.fluo.command.FluoCommandType.LIST; +import static org.apache.fluo.command.FluoCommandType.ORACLE; +import static org.apache.fluo.command.FluoCommandType.REMOVE; +import static org.apache.fluo.command.FluoCommandType.SCAN; +import static org.apache.fluo.command.FluoCommandType.STATUS; +import static org.apache.fluo.command.FluoCommandType.WAIT; +import static org.apache.fluo.command.FluoCommandType.WORKER; + +public class FluoProgram { + public static void main(String[] args) { + FluoConfig fluoConfig = new FluoConfig(); + FluoExec fluoExec = new FluoExec(); + FluoGetJars fluoGetJars = new FluoGetJars(); + FluoInit fluoInit = new FluoInit(); + FluoList fluoList = new FluoList(); + FluoOracle fluoOracle = new FluoOracle(); + FluoRemove fluoRemove = new FluoRemove(); + FluoScan fluoScan = new FluoScan(); + FluoStatus fluoStatus = new FluoStatus(); + FluoWait fluoWait = new FluoWait(); + FluoWorker fluoWorker = new FluoWorker(); + JCommander jcommand = JCommander.newBuilder().addCommand(CONFIG.getCommandName(), fluoConfig) + .addCommand(EXEC.getCommandName(), fluoExec) + .addCommand(GET_JARS.getCommandName(), fluoGetJars) + .addCommand(INIT.getCommandName(), fluoInit).addCommand(LIST.getCommandName(), fluoList) + .addCommand(ORACLE.getCommandName(), fluoOracle) + .addCommand(REMOVE.getCommandName(), fluoRemove).addCommand(SCAN.getCommandName(), fluoScan) + .addCommand(STATUS.getCommandName(), fluoStatus).addCommand(WAIT.getCommandName(), fluoWait) + .addCommand(WORKER.getCommandName(), fluoWorker).build(); + + try { + jcommand.parse(args); + } catch (ParameterException e) { + System.err.println(e.getMessage()); + String commandName = Optional.ofNullable(jcommand.getParsedCommand()).orElse(""); + JCommander parsedCommandOrProgram = + Optional.ofNullable(jcommand.findCommandByAlias(commandName)).orElse(jcommand); + parsedCommandOrProgram.setProgramName(String.format("fluo %s", commandName)); + parsedCommandOrProgram.usage(); Review comment: Yes. If I run the following program ``` FluoConfig fluoConfig = new FluoConfig(); FluoExec fluoExec = new FluoExec(); FluoGetJars fluoGetJars = new FluoGetJars(); FluoInit fluoInit = new FluoInit(); FluoList fluoList = new FluoList(); FluoOracle fluoOracle = new FluoOracle(); FluoRemove fluoRemove = new FluoRemove(); FluoScan fluoScan = new FluoScan(); FluoStatus fluoStatus = new FluoStatus(); FluoWait fluoWait = new FluoWait(); FluoWorker fluoWorker = new FluoWorker(); JCommander jcommand = JCommander.newBuilder().addCommand(CONFIG.getCommandName(), fluoConfig) .addCommand(EXEC.getCommandName(), fluoExec) .addCommand(GET_JARS.getCommandName(), fluoGetJars) .addCommand(INIT.getCommandName(), fluoInit).addCommand(LIST.getCommandName(), fluoList) .addCommand(ORACLE.getCommandName(), fluoOracle) .addCommand(REMOVE.getCommandName(), fluoRemove).addCommand(SCAN.getCommandName(), fluoScan) .addCommand(STATUS.getCommandName(), fluoStatus).addCommand(WAIT.getCommandName(), fluoWait) .addCommand(WORKER.getCommandName(), fluoWorker).build(); try{ jcommand.parse("asdf", "-3dd"); } catch (ParameterException e) { System.err.println(e.getMessage()); String commandName = Optional.ofNullable(jcommand.getParsedCommand()).orElse(""); JCommander parsedCommandOrProgram = Optional.ofNullable(jcommand.findCommandByAlias(commandName)).orElse(jcommand); parsedCommandOrProgram.setProgramName(String.format("fluo %s", commandName)); parsedCommandOrProgram.usage(); System.exit(1); return; } ``` Because it's unable to parse a command then I will see the following in my console ``` Expected a command, got asdf Usage: fluo [command] [command options] Commands: config Prints application configuration stored in Zookeeper for <app> Usage: config [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] exec Executes <class> with <args> using classpath for <app> Usage: exec <app> <class> args... get-jars Copies <app> jars from DFS to local <dir> Usage: get-jars [options] Options: -h, -help, --help Prints help * -a Fluo application name * -d Download directory path -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] init Initializes Fluo application for <app> using <appProps> Usage: init [options] Options: --clearTable Skips prompt and clears Accumulo table Default: false --clearZookeeper Skips prompt and clears Zookeeper Default: false -f, --force Skip all prompts and clears Zookeeper and Accumulo table. Equivalent to setting both --clearTable --clearZookeeper Default: false -h, -help, --help Prints help --retrieveProperty Gets specified property without initializing -u, --update Update Fluo configuration in Zookeeper Default: false * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] * -p Path to application properties file list Lists all Fluo applications in Fluo instance Usage: list [options] Options: -h, -help, --help Prints help -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] oracle Starts Fluo Oracle process for <app> Usage: oracle [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] remove Removes Fluo application for <app> Usage: remove [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] scan Prints snapshot of data in Fluo <app> Usage: scan [options] Options: -esc, --escape-non-ascii Hex encode non ascii bytes -h, -help, --help Prints help --json Export key/values stored in Accumulo as JSON file. --ntfy Scan active notifications --raw Show underlying key/values stored in Accumulo. Interprets the data using Fluo internal schema, making it easier to comprehend. * -a Fluo application name -c Columns of scan in comma separated format: <<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}> -e End row (inclusive) of scan -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] -p Row prefix to scan -r Exact row to scan -s Start row (inclusive) of scan status Prints status of Fluo application for <app> Usage: status [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] wait Waits until all notifications are processed for <app> Usage: wait [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] worker Starts Fluo Worker process for <app> Usage: worker [options] Options: -h, -help, --help Prints help * -a Fluo application name -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] ``` If I change `"asdf", "-3dd"` to `"list", "-3dd"` then because it can parse out a command the following is printed to my console ``` Was passed main parameter '-3dd' but no main parameter was defined in your arg class Usage: fluo list [options] Options: -h, -help, --help Prints help -o Override configuration set in properties file. Expected format: -o <key>=<value> Default: [] ``` The usage outputs are coming from the descriptions from the `@Parameter` and `@Paramters` annotations. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
