This is an automated email from the ASF dual-hosted git repository.
jkoshakow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/fluo.git
The following commit(s) were added to refs/heads/master by this push:
new f441623 Centralize command logic to be run from one class
f441623 is described below
commit f441623f03bda88cb9d514822d349b0abcd21d9d
Author: Joseph Koshakow <[email protected]>
AuthorDate: Mon Jan 13 22:21:22 2020 -0500
Centralize command logic to be run from one class
Using the Command Pattern as inspiration, all the logic for running a
command has been moved to the FluoProgram class. The purpose of this
was to prevent calling System.exit() from within the command classes.
This will allow the commands to be more easily reused outside of a CLI.
This also makes it easier to print standard error messages for expected
exceptions by throwing a FluoCommandException, and to print a stack
trace for all other exceptions.
Fixes #983
---
.../command/{CommonOpts.java => AppCommand.java} | 18 ++-
.../command/{BaseOpts.java => BaseCommand.java} | 29 +---
.../java/org/apache/fluo/command/CommandUtil.java | 13 +-
.../{ConfigOpts.java => ConfigCommand.java} | 30 ++--
.../command/{CommonOpts.java => FluoCommand.java} | 17 +--
.../{CommonOpts.java => FluoCommandException.java} | 26 ++--
.../java/org/apache/fluo/command/FluoConfig.java | 13 +-
.../java/org/apache/fluo/command/FluoExec.java | 46 ++++--
.../java/org/apache/fluo/command/FluoGetJars.java | 68 ++++-----
.../java/org/apache/fluo/command/FluoInit.java | 137 ++++++++---------
.../java/org/apache/fluo/command/FluoList.java | 63 +++++---
.../java/org/apache/fluo/command/FluoOracle.java | 26 ++--
.../java/org/apache/fluo/command/FluoProgram.java | 75 +++++++++
.../java/org/apache/fluo/command/FluoRemove.java | 21 +--
.../java/org/apache/fluo/command/FluoScan.java | 167 ++++++++++-----------
.../java/org/apache/fluo/command/FluoStatus.java | 13 +-
.../java/org/apache/fluo/command/FluoWait.java | 21 +--
.../java/org/apache/fluo/command/FluoWorker.java | 27 ++--
.../org/apache/fluo/command/AppCommandTest.java | 51 +++++++
.../org/apache/fluo/command/CommandUtilTest.java} | 29 ++--
.../org/apache/fluo/command/ConfigCommandTest.java | 104 +++++++++++++
.../org/apache/fluo/command/FluoProgramTest.java | 112 ++++++++++++++
.../java/org/apache/fluo/command/ScanTest.java | 6 +-
.../src/test/resources/test-fluo-conn.properties | 15 ++
modules/distribution/src/main/lib/fetch.sh | 2 +-
modules/distribution/src/main/scripts/fluo | 44 +++---
pom.xml | 2 +-
27 files changed, 760 insertions(+), 415 deletions(-)
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
b/modules/command/src/main/java/org/apache/fluo/command/AppCommand.java
similarity index 70%
copy from modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
copy to modules/command/src/main/java/org/apache/fluo/command/AppCommand.java
index 004c2ae..3409d51 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/AppCommand.java
@@ -16,19 +16,27 @@
package org.apache.fluo.command;
import com.beust.jcommander.Parameter;
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.fluo.api.config.FluoConfiguration;
-class CommonOpts extends ConfigOpts {
+abstract class AppCommand extends ConfigCommand {
@Parameter(names = "-a", required = true, description = "Fluo application
name")
private String applicationName;
+ @Override
+ FluoConfiguration getConfig() {
+ FluoConfiguration config = super.getConfig();
+ config.setApplicationName(applicationName);
+ return config;
+ }
+
String getApplicationName() {
return applicationName;
}
- public static CommonOpts parse(String programName, String[] args) {
- CommonOpts opts = new CommonOpts();
- parse(programName, opts, args);
- return opts;
+ @VisibleForTesting
+ void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/BaseOpts.java
b/modules/command/src/main/java/org/apache/fluo/command/BaseCommand.java
similarity index 63%
rename from modules/command/src/main/java/org/apache/fluo/command/BaseOpts.java
rename to modules/command/src/main/java/org/apache/fluo/command/BaseCommand.java
index c700afe..7e2c734 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/BaseOpts.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/BaseCommand.java
@@ -4,9 +4,9 @@
* 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
@@ -15,29 +15,14 @@
package org.apache.fluo.command;
-import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterException;
-
-public class BaseOpts {
+public abstract class BaseCommand implements FluoCommand {
@Parameter(names = {"-h", "-help", "--help"}, help = true, description =
"Prints help")
- boolean help;
-
- public static void parse(String programName, BaseOpts opts, String[] args) {
- JCommander jcommand = new JCommander(opts);
- jcommand.setProgramName(programName);
- try {
- jcommand.parse(args);
- } catch (ParameterException e) {
- System.err.println(e.getMessage());
- jcommand.usage();
- System.exit(-1);
- }
+ private boolean help;
- if (opts.help) {
- jcommand.usage();
- System.exit(1);
- }
+ @Override
+ public boolean isHelp() {
+ return help;
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/CommandUtil.java
b/modules/command/src/main/java/org/apache/fluo/command/CommandUtil.java
index ee839f4..762f17d 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/CommandUtil.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/CommandUtil.java
@@ -23,11 +23,13 @@ import org.apache.fluo.core.client.FluoAdminImpl;
public class CommandUtil {
+ public static final String FLUO_CONN_PROPS = "fluo.conn.props";
+
public static void verifyAppInitialized(FluoConfiguration config) {
if (!FluoAdminImpl.isInitialized(config)) {
- System.out.println("A Fluo '" + config.getApplicationName() + "'
application has not "
- + "been initialized yet in Zookeeper at " +
config.getAppZookeepers());
- System.exit(-1);
+ throw new FluoCommandException(
+ "A Fluo '" + config.getApplicationName() + "' application has not "
+ + "been initialized yet in Zookeeper at " +
config.getAppZookeepers());
}
}
@@ -35,15 +37,14 @@ public class CommandUtil {
verifyAppInitialized(config);
try (FluoAdminImpl admin = new FluoAdminImpl(config)) {
if (!admin.applicationRunning()) {
- System.out.println("A Fluo '" + config.getApplicationName()
+ throw new FluoCommandException("A Fluo '" + config.getApplicationName()
+ "' application is initialized but is not running!");
- System.exit(-1);
}
}
}
public static FluoConfiguration resolveFluoConfig() {
- String connPropsPath = System.getProperty("fluo.conn.props");
+ String connPropsPath = System.getProperty(FLUO_CONN_PROPS);
if (connPropsPath == null) {
return new FluoConfiguration();
} else {
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/ConfigOpts.java
b/modules/command/src/main/java/org/apache/fluo/command/ConfigCommand.java
similarity index 74%
rename from
modules/command/src/main/java/org/apache/fluo/command/ConfigOpts.java
rename to
modules/command/src/main/java/org/apache/fluo/command/ConfigCommand.java
index 09c9dea..35b5c36 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/ConfigOpts.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/ConfigCommand.java
@@ -21,9 +21,10 @@ import java.util.List;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.converters.IParameterSplitter;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.fluo.api.config.FluoConfiguration;
-public class ConfigOpts extends BaseOpts {
+public abstract class ConfigCommand extends BaseCommand {
public static class NullSplitter implements IParameterSplitter {
@Override
@@ -36,30 +37,35 @@ public class ConfigOpts extends BaseOpts {
description = "Override configuration set in properties file. Expected
format: -o <key>=<value>")
private List<String> properties = new ArrayList<>();
- List<String> getProperties() {
- return properties;
- }
-
- void overrideFluoConfig(FluoConfiguration config) {
+ private void overrideFluoConfig(FluoConfiguration config) {
for (String prop : getProperties()) {
String[] propArgs = prop.split("=", 2);
if (propArgs.length == 2) {
String key = propArgs[0].trim();
String value = propArgs[1].trim();
if (key.isEmpty() || value.isEmpty()) {
- throw new IllegalArgumentException("Invalid command line -o option:
" + prop);
+ throw new FluoCommandException("Invalid command line -o option: " +
prop);
} else {
config.setProperty(key, value);
}
} else {
- throw new IllegalArgumentException("Invalid command line -o option: "
+ prop);
+ throw new FluoCommandException("Invalid command line -o option: " +
prop);
}
}
}
- public static ConfigOpts parse(String programName, String[] args) {
- ConfigOpts opts = new ConfigOpts();
- parse(programName, opts, args);
- return opts;
+ FluoConfiguration getConfig() {
+ FluoConfiguration config = CommandUtil.resolveFluoConfig();
+ overrideFluoConfig(config);
+ return config;
+ }
+
+ public List<String> getProperties() {
+ return properties;
+ }
+
+ @VisibleForTesting
+ void setProperties(List<String> properties) {
+ this.properties = properties;
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoCommand.java
similarity index 66%
copy from modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
copy to modules/command/src/main/java/org/apache/fluo/command/FluoCommand.java
index 004c2ae..e2f6bb3 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoCommand.java
@@ -15,20 +15,9 @@
package org.apache.fluo.command;
-import com.beust.jcommander.Parameter;
+public interface FluoCommand {
-class CommonOpts extends ConfigOpts {
+ void execute() throws FluoCommandException;
- @Parameter(names = "-a", required = true, description = "Fluo application
name")
- private String applicationName;
-
- String getApplicationName() {
- return applicationName;
- }
-
- public static CommonOpts parse(String programName, String[] args) {
- CommonOpts opts = new CommonOpts();
- parse(programName, opts, args);
- return opts;
- }
+ boolean isHelp();
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoCommandException.java
similarity index 66%
copy from modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
copy to
modules/command/src/main/java/org/apache/fluo/command/FluoCommandException.java
index 004c2ae..60d25ed 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
+++
b/modules/command/src/main/java/org/apache/fluo/command/FluoCommandException.java
@@ -4,9 +4,9 @@
* 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
@@ -15,20 +15,22 @@
package org.apache.fluo.command;
-import com.beust.jcommander.Parameter;
+public class FluoCommandException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
-class CommonOpts extends ConfigOpts {
+ public FluoCommandException() {
+ super();
+ }
- @Parameter(names = "-a", required = true, description = "Fluo application
name")
- private String applicationName;
+ public FluoCommandException(String msg) {
+ super(msg);
+ }
- String getApplicationName() {
- return applicationName;
+ public FluoCommandException(String msg, Throwable cause) {
+ super(msg, cause);
}
- public static CommonOpts parse(String programName, String[] args) {
- CommonOpts opts = new CommonOpts();
- parse(programName, opts, args);
- return opts;
+ public FluoCommandException(Throwable cause) {
+ super(cause);
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoConfig.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoConfig.java
index 467b928..605ec74 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoConfig.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoConfig.java
@@ -17,17 +17,18 @@ package org.apache.fluo.command;
import java.util.Map;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.client.FluoAdmin;
import org.apache.fluo.api.client.FluoFactory;
import org.apache.fluo.api.config.FluoConfiguration;
-public class FluoConfig {
+@Parameters(commandNames = "config",
+ commandDescription = "Prints application configuration stored in Zookeeper
for <app>")
+public class FluoConfig extends AppCommand {
- public static void main(String[] args) {
- CommonOpts opts = CommonOpts.parse("fluo config", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
CommandUtil.verifyAppInitialized(config);
try (FluoAdmin admin = FluoFactory.newAdmin(config)) {
for (Map.Entry<String, String> entry :
admin.getApplicationConfig().toMap().entrySet()) {
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoExec.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoExec.java
index bffc448..1a993f5 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoExec.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoExec.java
@@ -15,17 +15,22 @@
package org.apache.fluo.command;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Arrays;
+import java.util.List;
import javax.inject.Provider;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
-public class FluoExec {
+@Parameters(commandNames = "exec",
+ commandDescription = "Executes <class> with <args> using classpath for
<app>")
+public class FluoExec extends BaseCommand implements FluoCommand {
private static class FluoConfigModule extends AbstractModule {
@@ -44,25 +49,40 @@ public class FluoExec {
}
}
- public static void main(String[] args) throws Exception {
- if (args.length < 2) {
- System.err.println("Usage: fluo exec <app> <class> args...");
- System.exit(-1);
+ @Parameter(description = "<app> <class> args...", variableArity = true)
+ private List<String> args;
+
+ @Override
+ public void execute() throws FluoCommandException {
+ if (args.size() < 2) {
+ throw new FluoCommandException("Usage: fluo exec <app> <class> args...");
}
- final String applicationName = args[0];
- final String className = args[1];
+ final String applicationName = args.get(0);
+ final String className = args.get(1);
FluoConfiguration fluoConfig = CommandUtil.resolveFluoConfig();
fluoConfig.setApplicationName(applicationName);
CommandUtil.verifyAppInitialized(fluoConfig);
fluoConfig = FluoAdminImpl.mergeZookeeperConfig(fluoConfig);
- Class<?> clazz = Class.forName(className);
+ try {
+ Class<?> clazz = Class.forName(className);
+
+ // inject fluo configuration
+ Guice.createInjector(new FluoConfigModule(clazz, fluoConfig));
- // inject fluo configuration
- Guice.createInjector(new FluoConfigModule(clazz, fluoConfig));
+ Method method = clazz.getMethod("main", String[].class);
+ List<String> execArgs = args.subList(2, args.size());
+ method.invoke(null, (Object) execArgs.toArray(new
String[execArgs.size()]));
+ } catch (NoSuchMethodException | IllegalAccessException |
InvocationTargetException e) {
+ throw new FluoCommandException(String.format("Class %s must have a main
method", className),
+ e);
+ } catch (ClassNotFoundException e) {
+ throw new FluoCommandException(String.format("Class %s not found",
className), e);
+ }
+ }
- Method method = clazz.getMethod("main", String[].class);
- method.invoke(null, (Object) Arrays.copyOfRange(args, 2, args.length));
+ public List<String> getArgs() {
+ return args;
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoGetJars.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoGetJars.java
index 2ac32fe..4f55bb2 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoGetJars.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoGetJars.java
@@ -4,9 +4,9 @@
* 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
@@ -16,9 +16,12 @@
package org.apache.fluo.command;
import java.io.File;
+import java.io.IOException;
import java.net.URI;
+import java.net.URISyntaxException;
import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
import org.apache.commons.io.FileUtils;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
@@ -28,57 +31,46 @@ import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FluoGetJars {
+@Parameters(commandNames = "get-jars",
+ commandDescription = "Copies <app> jars from DFS to local <dir>")
+public class FluoGetJars extends AppCommand {
private static final Logger log = LoggerFactory.getLogger(FluoGetJars.class);
- public static class GetJarsOpts extends CommonOpts {
+ @Parameter(names = "-d", required = true, description = "Download directory
path")
+ private String downloadPath;
- @Parameter(names = "-d", required = true, description = "Download
directory path")
- private String downloadPath;
-
- String getDownloadPath() {
- return downloadPath;
- }
-
- public static GetJarsOpts parse(String[] args) {
- GetJarsOpts opts = new GetJarsOpts();
- parse("fluo get-jars", opts, args);
- return opts;
- }
+ String getDownloadPath() {
+ return downloadPath;
}
- public static void main(String[] args) {
-
- GetJarsOpts opts = GetJarsOpts.parse(args);
-
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
CommandUtil.verifyAppInitialized(config);
config = FluoAdminImpl.mergeZookeeperConfig(config);
if (config.getObserverJarsUrl().isEmpty()) {
- log.info("No observer jars found for the '{}' Fluo application!",
opts.getApplicationName());
+ log.info("No observer jars found for the '{}' Fluo application!",
getApplicationName());
return;
}
- try {
- if (config.getObserverJarsUrl().startsWith("hdfs://")) {
- try (FileSystem fs = FileSystem.get(new URI(config.getDfsRoot()), new
Configuration())) {
- File downloadPathFile = new File(opts.getDownloadPath());
- if (downloadPathFile.exists()) {
- FileUtils.deleteDirectory(downloadPathFile);
- }
- fs.copyToLocalFile(new Path(config.getObserverJarsUrl()),
- new Path(opts.getDownloadPath()));
+ if (config.getObserverJarsUrl().startsWith("hdfs://")) {
+ try (FileSystem fs = FileSystem.get(new URI(config.getDfsRoot()), new
Configuration())) {
+ File downloadPathFile = new File(getDownloadPath());
+ if (downloadPathFile.exists()) {
+ FileUtils.deleteDirectory(downloadPathFile);
}
- } else {
- log.error("Unsupported url prefix for {}={}",
FluoConfiguration.OBSERVER_JARS_URL_PROP,
- config.getObserverJarsUrl());
+ fs.copyToLocalFile(new Path(config.getObserverJarsUrl()), new
Path(getDownloadPath()));
+ } catch (URISyntaxException e) {
+ throw new FluoCommandException(
+ String.format("Error parsing DFS ROOT URI: %s", e.getMessage()),
e);
+ } catch (IOException e) {
+ throw new FluoCommandException(e);
}
- } catch (Exception e) {
- log.error("", e);
+ } else {
+ throw new FluoCommandException(String.format("Unsupported url prefix for
%s=%s",
+ FluoConfiguration.OBSERVER_JARS_URL_PROP,
config.getObserverJarsUrl()));
}
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoInit.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoInit.java
index 9eeb5b9..e1c9bb2 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoInit.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoInit.java
@@ -4,9 +4,9 @@
* 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
@@ -22,65 +22,59 @@ import java.io.InputStreamReader;
import java.util.Optional;
import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
import com.google.common.base.Preconditions;
import org.apache.fluo.api.client.FluoAdmin;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
-public class FluoInit {
+@Parameters(commandNames = "init",
+ commandDescription = "Initializes Fluo application for <app> using
<appProps>")
+public class FluoInit extends AppCommand {
- public static class InitOptions extends CommonOpts {
+ @Parameter(names = "-p", required = true, description = "Path to application
properties file")
+ private String appPropsPath;
- @Parameter(names = "-p", required = true, description = "Path to
application properties file")
- private String appPropsPath;
+ @Parameter(names = {"-f", "--force"},
+ description = "Skip all prompts and clears Zookeeper and Accumulo table.
Equivalent to "
+ + "setting both --clearTable --clearZookeeper")
+ private boolean force;
- @Parameter(names = {"-f", "--force"},
- description = "Skip all prompts and clears Zookeeper and Accumulo
table. Equivalent to "
- + "setting both --clearTable --clearZookeeper")
- private boolean force;
+ @Parameter(names = {"--clearTable"}, description = "Skips prompt and clears
Accumulo table")
+ private boolean clearTable;
- @Parameter(names = {"--clearTable"}, description = "Skips prompt and
clears Accumulo table")
- private boolean clearTable;
+ @Parameter(names = {"--clearZookeeper"}, description = "Skips prompt and
clears Zookeeper")
+ private boolean clearZookeeper;
- @Parameter(names = {"--clearZookeeper"}, description = "Skips prompt and
clears Zookeeper")
- private boolean clearZookeeper;
+ @Parameter(names = {"-u", "--update"}, description = "Update Fluo
configuration in Zookeeper")
+ private boolean update;
- @Parameter(names = {"-u", "--update"}, description = "Update Fluo
configuration in Zookeeper")
- private boolean update;
+ @Parameter(names = "--retrieveProperty",
+ description = "Gets specified property without initializing")
+ private String retrieveProperty;
- @Parameter(names = "--retrieveProperty",
- description = "Gets specified property without initializing")
- private String retrieveProperty;
-
- String getAppPropsPath() {
- return appPropsPath;
- }
-
- boolean getForce() {
- return force;
- }
+ String getAppPropsPath() {
+ return appPropsPath;
+ }
- boolean getClearTable() {
- return clearTable;
- }
+ boolean getForce() {
+ return force;
+ }
- boolean getClearZookeeper() {
- return clearZookeeper;
- }
+ boolean getClearTable() {
+ return clearTable;
+ }
- boolean getUpdate() {
- return update;
- }
+ boolean getClearZookeeper() {
+ return clearZookeeper;
+ }
- String getRetrieveProperty() {
- return retrieveProperty;
- }
+ boolean getUpdate() {
+ return update;
+ }
- public static InitOptions parse(String[] args) {
- InitOptions opts = new InitOptions();
- parse("fluo init", opts, args);
- return opts;
- }
+ String getRetrieveProperty() {
+ return retrieveProperty;
}
private static boolean readYes() {
@@ -90,7 +84,7 @@ public class FluoInit {
try {
input =
Optional.ofNullable(bufferedReader.readLine()).orElse("").trim();
} catch (IOException e) {
- throw new IllegalStateException(e);
+ throw new FluoCommandException(e);
}
if (input.equalsIgnoreCase("y")) {
return true;
@@ -102,53 +96,49 @@ public class FluoInit {
}
}
- public static void main(String[] args) {
-
- InitOptions opts = InitOptions.parse(args);
- File applicationPropsFile = new File(opts.getAppPropsPath());
+ @Override
+ public void execute() throws FluoCommandException {
+ File applicationPropsFile = new File(getAppPropsPath());
Preconditions.checkArgument(applicationPropsFile.exists(),
- opts.getAppPropsPath() + " does not exist");
+ getAppPropsPath() + " does not exist");
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
+ FluoConfiguration config = getConfig();
config.load(applicationPropsFile);
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
- String propKey = opts.getRetrieveProperty();
+ String propKey = getRetrieveProperty();
if (propKey != null && !propKey.isEmpty()) {
if (config.containsKey(propKey)) {
System.out.println(config.getString(propKey));
}
- System.exit(0);
+ return;
}
if (!config.hasRequiredAdminProps()) {
- System.err.println("Error - Required properties are not set in " +
opts.getAppPropsPath());
- System.exit(-1);
+ throw new FluoCommandException(
+ "Error - Required properties are not set in " + getAppPropsPath());
}
try {
config.validate();
} catch (Exception e) {
- System.err.println("Error - Invalid configuration due to " +
e.getMessage());
- System.exit(-1);
+ throw new FluoCommandException("Error - Invalid configuration due to " +
e.getMessage(), e);
}
try (FluoAdminImpl admin = new FluoAdminImpl(config)) {
FluoAdmin.InitializationOptions initOpts = new
FluoAdmin.InitializationOptions();
- if (opts.getUpdate()) {
+ if (getUpdate()) {
System.out.println("Updating configuration for the Fluo '" +
config.getApplicationName()
- + "' application in Zookeeper using " + opts.getAppPropsPath());
+ + "' application in Zookeeper using " + getAppPropsPath());
admin.updateSharedConfig();
System.out.println("Update is complete.");
- System.exit(0);
+ return;
}
- if (opts.getForce()) {
+ if (getForce()) {
initOpts.setClearZookeeper(true).setClearTable(true);
} else {
- if (opts.getClearZookeeper()) {
+ if (getClearZookeeper()) {
initOpts.setClearZookeeper(true);
} else if (admin.zookeeperInitialized()) {
System.out.print("A Fluo '" + config.getApplicationName()
@@ -158,12 +148,11 @@ public class FluoInit {
if (readYes()) {
initOpts.setClearZookeeper(true);
} else {
- System.out.println("Aborted initialization.");
- System.exit(-1);
+ throw new FluoCommandException("Aborted initialization.");
}
}
- if (opts.getClearTable()) {
+ if (getClearTable()) {
initOpts.setClearTable(true);
} else if (admin.accumuloTableExists()) {
System.out.print("The Accumulo table '" + config.getAccumuloTable()
@@ -171,24 +160,18 @@ public class FluoInit {
if (readYes()) {
initOpts.setClearTable(true);
} else {
- System.out.println("Aborted initialization.");
- System.exit(-1);
+ throw new FluoCommandException("Aborted initialization.");
}
}
}
System.out.println("Initializing Fluo '" + config.getApplicationName()
- + "' application using " + opts.getAppPropsPath());
+ + "' application using " + getAppPropsPath());
admin.initialize(initOpts);
System.out.println("Initialization is complete.");
- } catch (FluoAdmin.AlreadyInitializedException e) {
- System.err.println(e.getMessage());
- System.exit(-1);
- } catch (Exception e) {
- System.out.println("Initialization failed due to the following
exception:");
- e.printStackTrace();
- System.exit(-1);
+ } catch (FluoAdmin.AlreadyInitializedException |
FluoAdmin.TableExistsException e) {
+ throw new FluoCommandException(e.getMessage(), e);
}
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoList.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoList.java
index 02f9768..a430d0c 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoList.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoList.java
@@ -18,29 +18,30 @@ package org.apache.fluo.command;
import java.util.Collections;
import java.util.List;
+import com.beust.jcommander.Parameters;
import org.apache.curator.framework.CuratorFramework;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
import org.apache.fluo.core.util.CuratorUtil;
-public class FluoList {
+@Parameters(commandNames = "list",
+ commandDescription = "Lists all Fluo applications in Fluo instance")
+public class FluoList extends ConfigCommand {
- public static void main(String[] args) throws Exception {
-
- ConfigOpts commandOpts = ConfigOpts.parse("fluo list", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- commandOpts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
try (CuratorFramework curator = CuratorUtil.newFluoCurator(config)) {
curator.start();
- if (curator.checkExists().forPath("/") == null) {
+ if (!checkCuratorExists(curator)) {
System.out.println("Fluo instance (" + config.getInstanceZookeepers()
+ ") has not been "
+ "created yet in Zookeeper. It will be created when the first
Fluo application is "
+ "initialized for this instance.");
return;
}
- List<String> children = curator.getChildren().forPath("/");
+ List<String> children = getCuratorChildren(curator);
if (children.isEmpty()) {
System.out.println("Fluo instance (" + config.getInstanceZookeepers()
+ ") does not "
+ "contain any Fluo applications.");
@@ -54,17 +55,43 @@ public class FluoList {
System.out.println("----------- ------ ---------");
for (String path : children) {
- FluoConfiguration appConfig = new FluoConfiguration(config);
- appConfig.setApplicationName(path);
- try (FluoAdminImpl admin = new FluoAdminImpl(appConfig)) {
- String state = "STOPPED";
- if (admin.applicationRunning()) {
- state = "RUNNING";
- }
- int numWorkers = admin.numWorkers();
- System.out.format("%-15s %-11s %4d\n", path, state, numWorkers);
- }
+ listApp(config, path);
+ }
+ }
+ }
+
+ private boolean checkCuratorExists(CuratorFramework curator) {
+ try {
+ return curator.checkExists().forPath("/") != null;
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ // throwing RuntimeException so stack trace is printed on command line
+ throw new RuntimeException("Error getting curator children", e);
+ }
+ }
+
+ private List<String> getCuratorChildren(CuratorFramework curator) {
+ try {
+ return curator.getChildren().forPath("/");
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ // throwing RuntimeException so stack trace is printed on command line
+ throw new RuntimeException("Error getting curator children", e);
+ }
+ }
+
+ private void listApp(FluoConfiguration config, String path) {
+ FluoConfiguration appConfig = new FluoConfiguration(config);
+ appConfig.setApplicationName(path);
+ try (FluoAdminImpl admin = new FluoAdminImpl(appConfig)) {
+ String state = "STOPPED";
+ if (admin.applicationRunning()) {
+ state = "RUNNING";
}
+ int numWorkers = admin.numWorkers();
+ System.out.format("%-15s %-11s %4d\n", path, state, numWorkers);
}
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoOracle.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoOracle.java
index 3cea36a..0f2f896 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoOracle.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoOracle.java
@@ -15,30 +15,24 @@
package org.apache.fluo.command;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.client.FluoFactory;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.util.UtilWaitThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FluoOracle {
+@Parameters(commandNames = "oracle", commandDescription = "Starts Fluo Oracle
process for <app>")
+public class FluoOracle extends AppCommand {
- private static final Logger log = LoggerFactory.getLogger(FluoOracle.class);
-
- public static void main(String[] args) {
- CommonOpts opts = CommonOpts.parse("fluo oracle", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
CommandUtil.verifyAppInitialized(config);
- try {
- org.apache.fluo.api.service.FluoOracle oracle =
FluoFactory.newOracle(config);
- oracle.start();
- while (true) {
- UtilWaitThread.sleep(10000);
- }
- } catch (Exception e) {
- log.error("Exception running FluoOracle: ", e);
+ org.apache.fluo.api.service.FluoOracle oracle =
FluoFactory.newOracle(config);
+ oracle.start();
+ while (true) {
+ UtilWaitThread.sleep(10000);
}
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoProgram.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoProgram.java
new file mode 100644
index 0000000..dfa9bed
--- /dev/null
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoProgram.java
@@ -0,0 +1,75 @@
+/*
+ * 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.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+import com.google.common.collect.Iterables;
+
+public class FluoProgram {
+
+ public static void main(String[] args) {
+ List<FluoCommand> fluoCommands = Arrays.asList(new FluoConfig(), new
FluoExec(),
+ new FluoGetJars(), new FluoInit(), new FluoList(), new FluoOracle(),
new FluoRemove(),
+ new FluoScan(), new FluoStatus(), new FluoWait(), new FluoWorker());
+ try {
+ runFluoCommand(fluoCommands, args);
+ } catch (FluoCommandException | ParameterException e) {
+ System.exit(1);
+ }
+ }
+
+ public static void runFluoCommand(List<FluoCommand> fluoCommands, String[]
args) {
+ JCommander.Builder jCommanderBuilder = JCommander.newBuilder();
+ fluoCommands.forEach(jCommanderBuilder::addCommand);
+ JCommander jcommand = jCommanderBuilder.build();
+
+ try {
+ jcommand.parse(args);
+ } catch (ParameterException e) {
+ System.err.println(e.getMessage());
+ String commandName =
Optional.ofNullable(jcommand.getParsedCommand()).orElse("");
+ JCommander parsedJCommandOrProgram =
+
Optional.ofNullable(jcommand.findCommandByAlias(commandName)).orElse(jcommand);
+ parsedJCommandOrProgram.setProgramName(String.format("fluo %s",
commandName));
+ parsedJCommandOrProgram.usage();
+ throw e;
+ }
+
+ String parsedCommandType = jcommand.getParsedCommand();
+ JCommander parsedJCommand = jcommand.findCommandByAlias(parsedCommandType);
+ String programName = String.format("fluo %s", parsedCommandType);
+ parsedJCommand.setProgramName(programName);
+ FluoCommand parsedFluoCommand =
+ (FluoCommand) Iterables.getOnlyElement(parsedJCommand.getObjects());
+
+ if (parsedFluoCommand.isHelp()) {
+ parsedJCommand.usage();
+ return;
+ }
+
+ try {
+ parsedFluoCommand.execute();
+ } catch (FluoCommandException e) {
+ System.err.println(String.format("%s failed - %s", programName,
e.getMessage()));
+ throw e;
+ }
+ }
+}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
index a1b37e2..a12fced 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoRemove.java
@@ -15,19 +15,17 @@
package org.apache.fluo.command;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.api.exceptions.FluoException;
import org.apache.fluo.core.client.FluoAdminImpl;
-public class FluoRemove {
+@Parameters(commandNames = "remove", commandDescription = "Removes Fluo
application for <app>")
+public class FluoRemove extends AppCommand {
- public static void main(String[] args) {
-
- CommonOpts opts = CommonOpts.parse("fluo remove", args);
-
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
config = FluoAdminImpl.mergeZookeeperConfig(config);
try (FluoAdminImpl admin = new FluoAdminImpl(config)) {
@@ -35,12 +33,7 @@ public class FluoRemove {
admin.remove();
System.out.println("Remove is complete.");
} catch (FluoException e) {
- System.err.println(e.getMessage());
- System.exit(-1);
- } catch (Exception e) {
- System.out.println("Remove failed due to the following exception:");
- e.printStackTrace();
- System.exit(-1);
+ throw new FluoCommandException(e);
}
}
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoScan.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoScan.java
index 3844e4d..25a2d87 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoScan.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoScan.java
@@ -21,6 +21,7 @@ import java.util.EnumSet;
import java.util.List;
import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
import org.apache.fluo.core.util.ScanUtil;
@@ -28,126 +29,110 @@ import org.apache.fluo.core.util.ScanUtil.ScanFlags;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
-public class FluoScan {
+@Parameters(commandNames = "scan", commandDescription = "Prints snapshot of
data in Fluo <app>")
+public class FluoScan extends AppCommand {
- public static class ScanOptions extends CommonOpts {
+ @Parameter(names = "-s", description = "Start row (inclusive) of scan")
+ private String startRow;
- @Parameter(names = "-s", description = "Start row (inclusive) of scan")
- private String startRow;
+ @Parameter(names = "-e", description = "End row (inclusive) of scan")
+ private String endRow;
- @Parameter(names = "-e", description = "End row (inclusive) of scan")
- private String endRow;
+ @Parameter(names = "-c", description = "Columns of scan in comma separated
format: "
+ +
"<<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}> ")
+ private List<String> columns;
- @Parameter(names = "-c", description = "Columns of scan in comma separated
format: "
- +
"<<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}> ")
- private List<String> columns;
+ @Parameter(names = "-r", description = "Exact row to scan")
+ private String exactRow;
- @Parameter(names = "-r", description = "Exact row to scan")
- private String exactRow;
+ @Parameter(names = "-p", description = "Row prefix to scan")
+ private String rowPrefix;
- @Parameter(names = "-p", description = "Row prefix to scan")
- private String rowPrefix;
+ @Parameter(names = {"-esc", "--escape-non-ascii"}, help = true,
+ description = "Hex encode non ascii bytes", arity = 1)
+ public boolean hexEncNonAscii = true;
- @Parameter(names = {"-esc", "--escape-non-ascii"}, help = true,
- description = "Hex encode non ascii bytes", arity = 1)
- public boolean hexEncNonAscii = true;
+ @Parameter(names = "--raw", help = true,
+ description = "Show underlying key/values stored in Accumulo. Interprets
the data using Fluo "
+ + "internal schema, making it easier to comprehend.")
+ public boolean scanAccumuloTable = false;
- @Parameter(names = "--raw", help = true,
- description = "Show underlying key/values stored in Accumulo.
Interprets the data using Fluo "
- + "internal schema, making it easier to comprehend.")
- public boolean scanAccumuloTable = false;
+ @Parameter(names = "--json", help = true,
+ description = "Export key/values stored in Accumulo as JSON file.")
+ public boolean exportAsJson = false;
- @Parameter(names = "--json", help = true,
- description = "Export key/values stored in Accumulo as JSON file.")
- public boolean exportAsJson = false;
+ @Parameter(names = "--ntfy", help = true, description = "Scan active
notifications")
+ public boolean scanNtfy = false;
- @Parameter(names = "--ntfy", help = true, description = "Scan active
notifications")
- public boolean scanNtfy = false;
-
- public String getStartRow() {
- return startRow;
- }
-
- public String getEndRow() {
- return endRow;
- }
-
- public String getExactRow() {
- return exactRow;
- }
-
- public String getRowPrefix() {
- return rowPrefix;
+ /**
+ * Check if the parameters informed can be used together.
+ */
+ private void checkScanOptions() {
+ if (this.scanAccumuloTable && this.exportAsJson) {
+ throw new FluoCommandException("Both \"--raw\" and \"--json\" can not be
set together.");
}
- public List<String> getColumns() {
- if (columns == null) {
- return Collections.emptyList();
- }
- return columns;
+ if (this.scanAccumuloTable && this.scanNtfy) {
+ throw new FluoCommandException("Both \"--raw\" and \"--ntfy\" can not be
set together.");
}
+ }
- /**
- * Check if the parameters informed can be used together.
- */
- private void checkScanOptions() {
- if (this.scanAccumuloTable && this.exportAsJson) {
- throw new IllegalArgumentException(
- "Both \"--raw\" and \"--json\" can not be set together.");
- }
-
- if (this.scanAccumuloTable && this.scanNtfy) {
- throw new IllegalArgumentException(
- "Both \"--raw\" and \"--ntfy\" can not be set together.");
- }
- }
-
- public ScanUtil.ScanOpts getScanOpts() {
- EnumSet<ScanFlags> flags = EnumSet.noneOf(ScanFlags.class);
-
- ScanUtil.setFlag(flags, help, ScanFlags.HELP);
- ScanUtil.setFlag(flags, hexEncNonAscii, ScanFlags.HEX);
- ScanUtil.setFlag(flags, scanAccumuloTable, ScanFlags.ACCUMULO);
- ScanUtil.setFlag(flags, exportAsJson, ScanFlags.JSON);
- ScanUtil.setFlag(flags, scanNtfy, ScanFlags.NTFY);
+ public ScanUtil.ScanOpts getScanOpts() {
+ EnumSet<ScanFlags> flags = EnumSet.noneOf(ScanFlags.class);
- return new ScanUtil.ScanOpts(startRow, endRow, columns, exactRow,
rowPrefix, flags);
- }
+ ScanUtil.setFlag(flags, isHelp(), ScanFlags.HELP);
+ ScanUtil.setFlag(flags, hexEncNonAscii, ScanFlags.HEX);
+ ScanUtil.setFlag(flags, scanAccumuloTable, ScanFlags.ACCUMULO);
+ ScanUtil.setFlag(flags, exportAsJson, ScanFlags.JSON);
+ ScanUtil.setFlag(flags, scanNtfy, ScanFlags.NTFY);
- public static ScanOptions parse(String[] args) {
- ScanOptions opts = new ScanOptions();
- parse("fluo scan", opts, args);
- return opts;
- }
+ return new ScanUtil.ScanOpts(startRow, endRow, columns, exactRow,
rowPrefix, flags);
}
- public static void main(String[] args) {
-
+ @Override
+ public void execute() throws FluoCommandException {
Logger.getRootLogger().setLevel(Level.ERROR);
Logger.getLogger("org.apache.fluo").setLevel(Level.ERROR);
- ScanOptions options = ScanOptions.parse(args);
- options.checkScanOptions();
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(options.getApplicationName());
- options.overrideFluoConfig(config);
+ checkScanOptions();
+ FluoConfiguration config = getConfig();
try {
- options.overrideFluoConfig(config);
- if (options.scanAccumuloTable) {
+ if (scanAccumuloTable) {
config = FluoAdminImpl.mergeZookeeperConfig(config);
- ScanUtil.scanAccumulo(options.getScanOpts(), config, System.out);
- } else if (options.scanNtfy) {
+ ScanUtil.scanAccumulo(getScanOpts(), config, System.out);
+ } else if (scanNtfy) {
config = FluoAdminImpl.mergeZookeeperConfig(config);
- ScanUtil.scanNotifications(options.getScanOpts(), config, System.out);
+ ScanUtil.scanNotifications(getScanOpts(), config, System.out);
} else {
CommandUtil.verifyAppRunning(config);
- ScanUtil.scanFluo(options.getScanOpts(), config, System.out);
+ ScanUtil.scanFluo(getScanOpts(), config, System.out);
}
- } catch (RuntimeException | IOException e) {
- System.err.println("Scan failed - " + e.getMessage());
- System.exit(-1);
+ } catch (IOException e) {
+ throw new FluoCommandException(e);
}
}
+ public String getStartRow() {
+ return startRow;
+ }
+
+ public String getEndRow() {
+ return endRow;
+ }
+
+ public String getExactRow() {
+ return exactRow;
+ }
+
+ public String getRowPrefix() {
+ return rowPrefix;
+ }
+
+ public List<String> getColumns() {
+ if (columns == null) {
+ return Collections.emptyList();
+ }
+ return columns;
+ }
}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoStatus.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoStatus.java
index 4cd227f..27ecd5d 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoStatus.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoStatus.java
@@ -15,16 +15,17 @@
package org.apache.fluo.command;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.client.FluoAdminImpl;
-public class FluoStatus {
+@Parameters(commandNames = "status",
+ commandDescription = "Prints status of Fluo application for <app>")
+public class FluoStatus extends AppCommand {
- public static void main(String[] args) throws Exception {
- CommonOpts opts = CommonOpts.parse("fluo status", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
try (FluoAdminImpl admin = new FluoAdminImpl(config)) {
if (!admin.zookeeperInitialized()) {
System.out.println("NOT_FOUND");
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoWait.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoWait.java
index 464a904..5b0fa55 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoWait.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoWait.java
@@ -18,6 +18,7 @@ package org.apache.fluo.command;
import java.util.Collections;
import java.util.List;
+import com.beust.jcommander.Parameters;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.Scanner;
@@ -33,7 +34,9 @@ import org.slf4j.LoggerFactory;
import static java.util.concurrent.TimeUnit.MINUTES;
-public class FluoWait {
+@Parameters(commandNames = "wait",
+ commandDescription = "Waits until all notifications are processed for
<app>")
+public class FluoWait extends AppCommand {
private static final Logger log = LoggerFactory.getLogger(FluoWait.class);
private static final long MIN_SLEEP_MS = 250;
@@ -109,17 +112,17 @@ public class FluoWait {
break;
}
}
- } catch (Exception e) {
- log.error("An exception was thrown -", e);
- System.exit(-1);
+ } catch (AccumuloSecurityException | AccumuloException e) {
+ throw new FluoCommandException(String.format("Error getting table
ranges: ", e.getMessage()),
+ e);
+ } catch (TableNotFoundException e) {
+ throw new FluoCommandException(String.format("Table %s not found",
e.getTableName()), e);
}
}
- public static void main(String[] args) throws Exception {
- CommonOpts opts = CommonOpts.parse("fluo wait", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
CommandUtil.verifyAppRunning(config);
config = FluoAdminImpl.mergeZookeeperConfig(config);
waitUntilFinished(config);
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/FluoWorker.java
b/modules/command/src/main/java/org/apache/fluo/command/FluoWorker.java
index 6a0f982..3fd02a7 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/FluoWorker.java
+++ b/modules/command/src/main/java/org/apache/fluo/command/FluoWorker.java
@@ -15,32 +15,25 @@
package org.apache.fluo.command;
+import com.beust.jcommander.Parameters;
import org.apache.fluo.api.client.FluoFactory;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.core.util.UtilWaitThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FluoWorker {
+@Parameters(commandNames = "worker", commandDescription = "Starts Fluo Worker
process for <app>")
+public class FluoWorker extends AppCommand {
- private static final Logger log = LoggerFactory.getLogger(FluoWorker.class);
-
- public static void main(String[] args) {
-
- CommonOpts opts = CommonOpts.parse("fluo worker", args);
- FluoConfiguration config = CommandUtil.resolveFluoConfig();
- config.setApplicationName(opts.getApplicationName());
- opts.overrideFluoConfig(config);
+ @Override
+ public void execute() throws FluoCommandException {
+ FluoConfiguration config = getConfig();
CommandUtil.verifyAppInitialized(config);
- try {
- org.apache.fluo.api.service.FluoWorker worker =
FluoFactory.newWorker(config);
- worker.start();
- while (true) {
- UtilWaitThread.sleep(10000);
- }
- } catch (Exception e) {
- log.error("Exception running FluoWorker: ", e);
+ org.apache.fluo.api.service.FluoWorker worker =
FluoFactory.newWorker(config);
+ worker.start();
+ while (true) {
+ UtilWaitThread.sleep(10000);
}
}
}
diff --git
a/modules/command/src/test/java/org/apache/fluo/command/AppCommandTest.java
b/modules/command/src/test/java/org/apache/fluo/command/AppCommandTest.java
new file mode 100644
index 0000000..c9e079b
--- /dev/null
+++ b/modules/command/src/test/java/org/apache/fluo/command/AppCommandTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.fluo.api.config.FluoConfiguration;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class AppCommandTest {
+
+ @Test
+ public void testGetConfig() {
+ AppCommand appCommand = new AppCommand() {
+ @Override
+ public void execute() throws FluoCommandException {}
+ };
+
+ URL testConfig =
getClass().getClassLoader().getResource("test-fluo-conn.properties");
+ System.setProperty(CommandUtil.FLUO_CONN_PROPS, testConfig.getPath());
+
+ String newAppName = "new-app-name";
+ int newZookeeperTimeout = 100;
+ List<String> overrideConfig = Collections.singletonList(
+ FluoConfiguration.CONNECTION_ZOOKEEPER_TIMEOUT_PROP + "=" +
newZookeeperTimeout);
+ appCommand.setApplicationName(newAppName);
+ appCommand.setProperties(overrideConfig);
+
+ FluoConfiguration fluoConfiguration = appCommand.getConfig();
+
+ assertEquals(newAppName, fluoConfiguration.getApplicationName());
+ assertEquals(newZookeeperTimeout, fluoConfiguration.getZookeeperTimeout());
+ }
+}
diff --git
a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
b/modules/command/src/test/java/org/apache/fluo/command/CommandUtilTest.java
similarity index 57%
rename from
modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
rename to
modules/command/src/test/java/org/apache/fluo/command/CommandUtilTest.java
index 004c2ae..802f71a 100644
--- a/modules/command/src/main/java/org/apache/fluo/command/CommonOpts.java
+++ b/modules/command/src/test/java/org/apache/fluo/command/CommandUtilTest.java
@@ -4,9 +4,9 @@
* 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
@@ -15,20 +15,23 @@
package org.apache.fluo.command;
-import com.beust.jcommander.Parameter;
+import java.net.URL;
-class CommonOpts extends ConfigOpts {
+import org.apache.fluo.api.config.FluoConfiguration;
+import org.junit.Test;
- @Parameter(names = "-a", required = true, description = "Fluo application
name")
- private String applicationName;
+import static org.junit.Assert.assertEquals;
- String getApplicationName() {
- return applicationName;
- }
+public class CommandUtilTest {
+
+ @Test
+ public void testResolveFluoConfig() {
+ URL testConfig =
getClass().getClassLoader().getResource("test-fluo-conn.properties");
+ System.setProperty(CommandUtil.FLUO_CONN_PROPS, testConfig.getPath());
+
+ FluoConfiguration fluoConfiguration = CommandUtil.resolveFluoConfig();
- public static CommonOpts parse(String programName, String[] args) {
- CommonOpts opts = new CommonOpts();
- parse(programName, opts, args);
- return opts;
+ assertEquals("app-name", fluoConfiguration.getApplicationName());
+ assertEquals(999, fluoConfiguration.getZookeeperTimeout());
}
}
diff --git
a/modules/command/src/test/java/org/apache/fluo/command/ConfigCommandTest.java
b/modules/command/src/test/java/org/apache/fluo/command/ConfigCommandTest.java
new file mode 100644
index 0000000..494362f
--- /dev/null
+++
b/modules/command/src/test/java/org/apache/fluo/command/ConfigCommandTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.fluo.api.config.FluoConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConfigCommandTest {
+
+ private ConfigCommand configCommand;
+
+ @Before
+ public void setUp() {
+ configCommand = new ConfigCommand() {
+ @Override
+ public void execute() throws FluoCommandException {}
+ };
+
+ URL testConfig =
getClass().getClassLoader().getResource("test-fluo-conn.properties");
+ System.setProperty(CommandUtil.FLUO_CONN_PROPS, testConfig.getPath());
+ }
+
+ @Test
+ public void testNullSplitter() {
+ String testStr = "asdf, safggr = adfjc :";
+ ConfigCommand.NullSplitter nullSplitter = new ConfigCommand.NullSplitter();
+
+ List<String> nullSplitList = nullSplitter.split(testStr);
+
+ assertEquals(1, nullSplitList.size());
+ assertEquals(testStr, nullSplitList.get(0));
+ }
+
+ @Test
+ public void testGetConfigWithOneOverriddenProp() {
+ int newZookeeperTimeout = 100;
+ List<String> overrideConfig = Collections.singletonList(
+ FluoConfiguration.CONNECTION_ZOOKEEPER_TIMEOUT_PROP + "=" +
newZookeeperTimeout);
+ configCommand.setProperties(overrideConfig);
+
+ FluoConfiguration fluoConfiguration = configCommand.getConfig();
+
+ assertEquals(newZookeeperTimeout, fluoConfiguration.getZookeeperTimeout());
+ assertEquals("app-name", fluoConfiguration.getApplicationName());
+ }
+
+ @Test
+ public void testGetConfigWithTwoOverriddenProp() {
+ int newZookeeperTimeout = 100;
+ int loaderQueueSize = 256;
+ List<String> overrideConfig = Arrays.asList(
+ FluoConfiguration.CONNECTION_ZOOKEEPER_TIMEOUT_PROP + "=" +
newZookeeperTimeout,
+ FluoConfiguration.LOADER_QUEUE_SIZE_PROP + "=" + "256");
+ configCommand.setProperties(overrideConfig);
+
+ FluoConfiguration fluoConfiguration = configCommand.getConfig();
+
+ assertEquals(newZookeeperTimeout, fluoConfiguration.getZookeeperTimeout());
+ assertEquals(loaderQueueSize, fluoConfiguration.getLoaderQueueSize());
+ assertEquals("app-name", fluoConfiguration.getApplicationName());
+ }
+
+ @Test(expected = FluoCommandException.class)
+ public void testGetConfigInvalidOption() {
+ configCommand.setProperties(Collections.singletonList("Invalid-Option"));
+
+ configCommand.getConfig();
+ }
+
+ @Test(expected = FluoCommandException.class)
+ public void testGetConfigMissingKey() {
+ configCommand.setProperties(Collections.singletonList(" =value"));
+
+ configCommand.getConfig();
+ }
+
+ @Test(expected = FluoCommandException.class)
+ public void testGetConfigMissingValue() {
+ configCommand.setProperties(Collections.singletonList("key= "));
+
+ configCommand.getConfig();
+ }
+}
diff --git
a/modules/command/src/test/java/org/apache/fluo/command/FluoProgramTest.java
b/modules/command/src/test/java/org/apache/fluo/command/FluoProgramTest.java
new file mode 100644
index 0000000..e3586a4
--- /dev/null
+++ b/modules/command/src/test/java/org/apache/fluo/command/FluoProgramTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.io.PrintStream;
+import java.util.Collections;
+
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.Parameters;
+import org.apache.commons.io.output.NullOutputStream;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class FluoProgramTest {
+ @Parameters(commandNames = "test")
+ class MockFluoCommand implements FluoCommand {
+
+ boolean help = false;
+ boolean throwException = false;
+ private boolean executed = false;
+
+ @Override
+ public void execute() throws FluoCommandException {
+ if (throwException) {
+ throw new FluoCommandException();
+ } else {
+ executed = true;
+ }
+ }
+
+ @Override
+ public boolean isHelp() {
+ return help;
+ }
+
+ public boolean isExecuted() {
+ return executed;
+ }
+ }
+
+ private MockFluoCommand mockFluoCommand;
+ private static PrintStream outPS;
+ private static PrintStream errPS;
+
+ @BeforeClass
+ public static void disablePrinting() {
+ outPS = System.out;
+ errPS = System.err;
+ // This will hide usage and error logs when running tests
+ try (PrintStream ps = new PrintStream(new NullOutputStream())) {
+ System.setOut(ps);
+ System.setErr(ps);
+ }
+ }
+
+ @AfterClass
+ public static void restorePrinting() {
+ System.setOut(outPS);
+ System.setErr(errPS);
+ }
+
+ @Before
+ public void setUp() {
+ mockFluoCommand = new MockFluoCommand();
+ }
+
+ @Test(expected = ParameterException.class)
+ public void testUnparsableCommand() {
+ FluoProgram.runFluoCommand(Collections.singletonList(new
MockFluoCommand()),
+ new String[] {"invalid", "command"});
+ }
+
+ @Test
+ public void testHelpCommand() {
+ mockFluoCommand.help = true;
+
+ FluoProgram.runFluoCommand(Collections.singletonList(mockFluoCommand), new
String[] {"test"});
+
+ assertFalse(mockFluoCommand.isExecuted());
+ }
+
+ @Test
+ public void testExecutedCommand() {
+ FluoProgram.runFluoCommand(Collections.singletonList(mockFluoCommand), new
String[] {"test"});
+
+ assertTrue(mockFluoCommand.isExecuted());
+ }
+
+ @Test(expected = FluoCommandException.class)
+ public void testExecutionError() {
+ mockFluoCommand.throwException = true;
+
+ FluoProgram.runFluoCommand(Collections.singletonList(mockFluoCommand), new
String[] {"test"});
+ }
+}
diff --git
a/modules/command/src/test/java/org/apache/fluo/command/ScanTest.java
b/modules/command/src/test/java/org/apache/fluo/command/ScanTest.java
index 20377a9..fabc3aa 100644
--- a/modules/command/src/test/java/org/apache/fluo/command/ScanTest.java
+++ b/modules/command/src/test/java/org/apache/fluo/command/ScanTest.java
@@ -30,10 +30,10 @@ import org.junit.Test;
public class ScanTest {
private SnapshotScanner.Opts parseArgs(String args) {
- FluoScan.ScanOptions options = new FluoScan.ScanOptions();
- JCommander jcommand = new JCommander(options);
+ FluoScan scan = new FluoScan();
+ JCommander jcommand = new JCommander(scan);
jcommand.parse(args.split(" "));
- ScanUtil.ScanOpts opts = options.getScanOpts();
+ ScanUtil.ScanOpts opts = scan.getScanOpts();
return new SnapshotScanner.Opts(ScanUtil.getSpan(opts),
ScanUtil.getColumns(opts), false);
}
diff --git a/modules/command/src/test/resources/test-fluo-conn.properties
b/modules/command/src/test/resources/test-fluo-conn.properties
new file mode 100644
index 0000000..113f9f3
--- /dev/null
+++ b/modules/command/src/test/resources/test-fluo-conn.properties
@@ -0,0 +1,15 @@
+# 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.
+
+fluo.connection.application.name=app-name
+fluo.connection.zookeeper.timeout=999
diff --git a/modules/distribution/src/main/lib/fetch.sh
b/modules/distribution/src/main/lib/fetch.sh
index 5f9c854..4cedc82 100755
--- a/modules/distribution/src/main/lib/fetch.sh
+++ b/modules/distribution/src/main/lib/fetch.sh
@@ -55,7 +55,7 @@ ahz)
extra)
echo "Fetching extra Fluo dependencies"
download aopalliance:aopalliance:jar:1.0
- download com.beust:jcommander:jar:1.72
+ download com.beust:jcommander:jar:1.78
download com.google.code.gson:gson:jar:2.8.5
download com.google.guava:guava:jar:27.0-jre
download com.google.inject:guice:jar:4.2.2
diff --git a/modules/distribution/src/main/scripts/fluo
b/modules/distribution/src/main/scripts/fluo
index 9a9426b..7372ddc 100755
--- a/modules/distribution/src/main/scripts/fluo
+++ b/modules/distribution/src/main/scripts/fluo
@@ -94,9 +94,6 @@ function verify_app {
echo -e "The application name (set by <app>) cannot be an empty string!\n"
print_usage
fi
- if [[ $1 = *"-h"* ]]; then
- print_usage
- fi
}
function check_hadoop {
@@ -113,13 +110,14 @@ function check_hadoop {
function setup_service {
if [[ "$@" =~ ^.*-a\ *([^\ ]*).*$ ]]; then
app=${BASH_REMATCH[1]}
+
verify_app "$app"
check_conn_props
# create a temp dir to fetch application jars to
app_lib=$(mktemp -d "$FLUO_TMP"/fluo-"$app"-XXXXXXXXX) || die "fatal:
unable to allocate a temporary directory"
# schedule removal of app_lib tmp dir when this script exits
trap "rm -rf '""$app_lib""'" EXIT HUP INT QUIT TERM
- $JAVA org.apache.fluo.command.FluoGetJars -d "$app_lib" "$@"
+ $JAVA org.apache.fluo.command.FluoProgram get-jars -d "$app_lib" "$@"
export CLASSPATH="$conf:$app_lib/*:$CLASSPATH"
else
echo "Application name must be set!"
@@ -131,50 +129,50 @@ function setup_service {
case "$1" in
config)
check_conn_props
- $JAVA org.apache.fluo.command.FluoConfig "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
get-jars)
check_conn_props
- $JAVA org.apache.fluo.command.FluoGetJars "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
init)
if [[ $2 = *"-h"* ]]; then
- $JAVA org.apache.fluo.command.FluoInit -h
+ $JAVA org.apache.fluo.command.FluoProgram $1 -h
exit 0
fi
- init_dir=$($JAVA org.apache.fluo.command.FluoInit "${@:2}"
--retrieveProperty fluo.observer.init.dir)
+ init_dir=$($JAVA org.apache.fluo.command.FluoProgram "$@" --retrieveProperty
fluo.observer.init.dir)
if [ -d "$init_dir" ]; then
echo "Adding $init_dir/* to CLASSPATH"
export CLASSPATH="$init_dir/*:$CLASSPATH"
fi
- $JAVA org.apache.fluo.command.FluoInit "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
remove)
if [[ $2 = *"-h"* ]]; then
- $JAVA org.apache.fluo.command.FluoRemove -h
+ $JAVA org.apache.fluo.command.FluoProgram $1 -h
exit 0
fi
- $JAVA org.apache.fluo.command.FluoRemove "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
oracle)
if [[ $2 = *"-h"* ]]; then
- $JAVA org.apache.fluo.command.FluoOracle -h
+ $JAVA org.apache.fluo.command.FluoProgram $1 -h
exit 0
fi
setup_service "${@:2}"
- $JAVA org.apache.fluo.command.FluoOracle "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
worker)
if [[ $2 = *"-h"* ]]; then
- $JAVA org.apache.fluo.command.FluoWorker -h
+ $JAVA org.apache.fluo.command.FluoProgram $1 -h
exit 0
fi
setup_service "${@:2}"
- $JAVA org.apache.fluo.command.FluoWorker "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
scan)
if [ -f "$FLUO_CONN_PROPS" ]; then
- $JAVA org.apache.fluo.command.FluoScan "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
else
check_hadoop
java org.apache.fluo.cluster.command.FluoCommand "$basedir"
"$HADOOP_PREFIX" "$@"
@@ -185,7 +183,7 @@ ps)
;;
list)
if [ -f "$FLUO_CONN_PROPS" ]; then
- $JAVA org.apache.fluo.command.FluoList "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
else
check_hadoop
java org.apache.fluo.cluster.command.FluoCommand "$basedir"
"$HADOOP_PREFIX" list app "${@:2}"
@@ -195,6 +193,10 @@ classpath)
echo "$CLASSPATH"
;;
exec)
+ if [[ $2 = *"-h"* ]]; then
+ $JAVA org.apache.fluo.command.FluoProgram $1 -h
+ exit 0
+ fi
app=$2
verify_app "$app"
check_conn_props
@@ -202,18 +204,18 @@ exec)
app_lib=$(mktemp -d "$FLUO_TMP"/fluo-"$app"-XXXXXXXXX) || die "fatal: unable
to allocate a temporary directory"
# schedule removal of app_lib tmp dir when this script exits
trap "rm -rf '""$app_lib""'" EXIT HUP INT QUIT TERM
- $JAVA org.apache.fluo.command.FluoGetJars -d "$app_lib" -a "$app"
+ $JAVA org.apache.fluo.command.FluoProgram get-jars -d "$app_lib" -a "$app"
export CLASSPATH="$conf:$app_lib/*:$CLASSPATH"
- $JAVA org.apache.fluo.command.FluoExec "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
status)
- $JAVA org.apache.fluo.command.FluoStatus "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
version)
echo "$FLUO_VERSION"
;;
wait)
- $JAVA org.apache.fluo.command.FluoWait "${@:2}"
+ $JAVA org.apache.fluo.command.FluoProgram "$@"
;;
*)
print_usage
diff --git a/pom.xml b/pom.xml
index eebd34c..8715a45 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,7 +71,7 @@
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
- <version>1.72</version>
+ <version>1.78</version>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>