You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@batchee.apache.org by rm...@apache.org on 2015/11/30 11:26:18 UTC
incubator-batchee git commit: BATCHEE-75 allow custom user commands
to be used in the cli + upgrade airline
Repository: incubator-batchee
Updated Branches:
refs/heads/master 77a0a69f3 -> 0ab8285da
BATCHEE-75 allow custom user commands to be used in the cli + upgrade airline
Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/0ab8285d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/0ab8285d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/0ab8285d
Branch: refs/heads/master
Commit: 0ab8285da00facb41808e91e0632b37f3052b0dc
Parents: 77a0a69
Author: Romain Manni-Bucau <rm...@gmail.com>
Authored: Mon Nov 30 11:26:43 2015 +0100
Committer: Romain Manni-Bucau <rm...@gmail.com>
Committed: Mon Nov 30 11:26:43 2015 +0100
----------------------------------------------------------------------
tools/cli/pom.xml | 2 +-
.../java/org/apache/batchee/cli/BatchEECLI.java | 48 ++++++++++++++--
.../org/apache/batchee/cli/command/Abandon.java | 4 +-
.../apache/batchee/cli/command/Executions.java | 4 +-
.../apache/batchee/cli/command/Instances.java | 4 +-
.../batchee/cli/command/JobOperatorCommand.java | 2 +-
.../org/apache/batchee/cli/command/Names.java | 2 +-
.../org/apache/batchee/cli/command/Restart.java | 4 +-
.../org/apache/batchee/cli/command/Running.java | 2 +-
.../batchee/cli/command/SocketCommand.java | 2 +-
.../cli/command/SocketConfigurableCommand.java | 2 +-
.../org/apache/batchee/cli/command/Start.java | 4 +-
.../batchee/cli/command/StartableCommand.java | 60 +++++++++++++++++---
.../org/apache/batchee/cli/command/Status.java | 2 +-
.../org/apache/batchee/cli/command/Stop.java | 4 +-
.../apache/batchee/cli/command/UserCommand.java | 22 +++++++
.../java/org/apache/batchee/cli/MainTest.java | 10 +++-
.../org/apache/batchee/cli/command/User1.java | 27 +++++++++
.../org/apache/batchee/cli/command/User2.java | 27 +++++++++
.../org.apache.batchee.cli.command.UserCommand | 2 +
20 files changed, 200 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/pom.xml
----------------------------------------------------------------------
diff --git a/tools/cli/pom.xml b/tools/cli/pom.xml
index 369595f..7cd6b4d 100644
--- a/tools/cli/pom.xml
+++ b/tools/cli/pom.xml
@@ -51,7 +51,7 @@
<dependency>
<groupId>io.airlift</groupId>
<artifactId>airline</artifactId>
- <version>0.6</version>
+ <version>0.7</version>
<exclusions>
<exclusion>
<groupId>javax.inject</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/BatchEECLI.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/BatchEECLI.java b/tools/cli/src/main/java/org/apache/batchee/cli/BatchEECLI.java
index bf44e07..ef737b4 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/BatchEECLI.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/BatchEECLI.java
@@ -16,9 +16,9 @@
*/
package org.apache.batchee.cli;
-import io.airlift.command.Cli;
-import io.airlift.command.Help;
-import io.airlift.command.ParseException;
+import io.airlift.airline.Cli;
+import io.airlift.airline.Help;
+import io.airlift.airline.ParseException;
import org.apache.batchee.cli.command.Abandon;
import org.apache.batchee.cli.command.Executions;
import org.apache.batchee.cli.command.Instances;
@@ -29,6 +29,14 @@ import org.apache.batchee.cli.command.Start;
import org.apache.batchee.cli.command.Status;
import org.apache.batchee.cli.command.Stop;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+
+import static java.lang.ClassLoader.getSystemClassLoader;
+
public class BatchEECLI {
public static void main(final String[] args) {
final Cli.CliBuilder<Runnable> builder = Cli.<Runnable>builder("batchee")
@@ -41,11 +49,41 @@ public class BatchEECLI {
Stop.class, Abandon.class,
Instances.class, Executions.class);
+ // user extension point
+ try { // read manually cause we dont want to instantiate them there, so no ServiceLoader
+ final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ final ClassLoader loader = tccl != null ? tccl : getSystemClassLoader();
+ final Enumeration<URL> uc = loader.getResources("META-INF/services/org.apache.batchee.cli.command.UserCommand");
+ while (uc.hasMoreElements()) {
+ final URL url = uc.nextElement();
+ BufferedReader r = null;
+ try {
+ r = new BufferedReader(new InputStreamReader(url.openStream()));
+ String line;
+ while ((line = r.readLine()) != null) {
+ if (line.startsWith("#") || line.trim().isEmpty()) {
+ continue;
+ }
+ builder.withCommand(Class.class.cast(loader.loadClass(line.trim())));
+ }
+ } catch (final IOException ioe) {
+ throw new IllegalStateException(ioe);
+ } catch (final ClassNotFoundException cnfe) {
+ throw new IllegalArgumentException(cnfe);
+ } finally {
+ if (r != null) {
+ r.close();
+ }
+ }
+ }
+ } catch (final IOException e) {
+ throw new IllegalStateException(e);
+ }
+
final Cli<Runnable> parser = builder.build();
try {
- final Runnable cmd = parser.parse(args);
- cmd.run();
+ parser.parse(args).run();
} catch (final ParseException e) {
parser.parse("help").run();
}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Abandon.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Abandon.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Abandon.java
index 4f4259a..eed60af 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Abandon.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Abandon.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
@Command(name = "abandon", description = "abandon a batch from its id")
public class Abandon extends SocketCommand {
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Executions.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Executions.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Executions.java
index 321a49e..40d4253 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Executions.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Executions.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
import org.apache.batchee.container.impl.JobInstanceImpl;
import org.apache.commons.lang3.StringUtils;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Instances.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Instances.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Instances.java
index 10fce0e..10a4350 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Instances.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Instances.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.JobInstance;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
index bb2b505..c8c3c23 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/JobOperatorCommand.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Option;
+import io.airlift.airline.Option;
import org.apache.batchee.cli.classloader.ChildFirstURLClassLoader;
import org.apache.batchee.cli.lifecycle.Lifecycle;
import org.apache.batchee.cli.zip.Zips;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Names.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Names.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Names.java
index 46100ee..6ef2282 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Names.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Names.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
+import io.airlift.airline.Command;
import java.io.File;
import java.io.FilenameFilter;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Restart.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Restart.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Restart.java
index d991b06..be345b6 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Restart.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Restart.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
import javax.batch.operations.JobOperator;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Running.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Running.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Running.java
index 2a6211c..7e0ff0a 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Running.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Running.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
+import io.airlift.airline.Command;
import javax.batch.operations.JobOperator;
import javax.batch.operations.NoSuchJobException;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketCommand.java
index efc2070..3785d14 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketCommand.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketCommand.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Option;
+import io.airlift.airline.Option;
import org.apache.batchee.container.exception.BatchContainerRuntimeException;
import org.apache.commons.io.IOUtils;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketConfigurableCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketConfigurableCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketConfigurableCommand.java
index d1b2aeb..8241745 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketConfigurableCommand.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/SocketConfigurableCommand.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Option;
+import io.airlift.airline.Option;
public abstract class SocketConfigurableCommand extends JobOperatorCommand {
@Option(name = "-wait", description = "should wait the end of the batch", arity = 1)
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Start.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Start.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Start.java
index 84416cb..4b310c6 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Start.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Start.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
import javax.batch.operations.JobOperator;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/StartableCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/StartableCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/StartableCommand.java
index d5f332c..6e16962 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/StartableCommand.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/StartableCommand.java
@@ -16,7 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Arguments;
+import io.airlift.airline.Arguments;
+import io.airlift.airline.Option;
import org.apache.batchee.util.Batches;
import org.apache.commons.io.IOUtils;
@@ -39,6 +40,13 @@ public abstract class StartableCommand extends SocketConfigurableCommand {
@Arguments(description = "properties to pass to the batch")
protected List<String> properties;
+ // some unix systems dont support negative systems.
+ @Option(name = "-error-exit-code", description = "exit code if any error occurs, should be > 0 or ignored")
+ protected int errorExitCode = -1;
+
+ @Option(name = "-failure-exit-code", description = "exit code if the batch result is not completed, should be > 0 and wait should be true or ignored")
+ protected int failureExitCode = -1;
+
@Override
public void doRun() {
final JobOperator operator = operator();
@@ -60,23 +68,52 @@ public abstract class StartableCommand extends SocketConfigurableCommand {
if (adminThread != null && adminThread.getServerSocket() != null) {
IOUtils.closeQuietly(adminThread.getServerSocket());
}
- e.printStackTrace();
- //X TODO how about a system return code? otherwise shell scripts cannot see if we did fine or not...
+ if (errorExitCode >= 0) {
+ System.exit(errorExitCode);
+ }
+ e.printStackTrace(); // ensure it is traced
return;
}
- if (wait) {
- Batches.waitForEnd(operator, id);
- report(operator, id);
+ try {
+ if (wait) {
+ finishBatch(operator, id);
+ }
+ } finally {
+ stopAdminThread(adminThread, id);
}
+ }
+
+ private void finishBatch(final JobOperator operator, final long id) {
+ Batches.waitForEnd(operator, id);
+ if (report(operator, id).getBatchStatus() == BatchStatus.FAILED) {
+ if (failureExitCode >= 0) {
+ System.exit(failureExitCode);
+ }
+ }
+ }
+
+ private void stopAdminThread(final AdminThread adminThread, final long id) {
if (adminThread != null) {
adminThread.setId(id);
+ if (wait) {
+ try {
+ try {
+ adminThread.serverSocket.close();
+ } catch (final IOException e) {
+ // no-op
+ }
+ adminThread.join();
+ } catch (final InterruptedException e) {
+ Thread.interrupted();
+ }
+ } // else let it live
}
}
protected abstract long doStart(JobOperator operator);
- private void report(final JobOperator operator, final long id) {
+ private JobExecution report(final JobOperator operator, final long id) {
final JobExecution execution = operator.getJobExecution(id);
info("");
@@ -102,6 +139,7 @@ public abstract class StartableCommand extends SocketConfigurableCommand {
}
info(LINE);
+ return execution;
}
private static String statusToString(final BatchStatus status) {
@@ -172,9 +210,13 @@ public abstract class StartableCommand extends SocketConfigurableCommand {
}
}
} catch (final IOException e) {
- e.printStackTrace();
+ if (!serverSocket.isClosed()) {
+ e.printStackTrace();
+ }
} finally {
- IOUtils.closeQuietly(serverSocket);
+ if (!serverSocket.isClosed()) {
+ IOUtils.closeQuietly(serverSocket);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Status.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Status.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Status.java
index 109cc73..b5eb0a6 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Status.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Status.java
@@ -16,7 +16,7 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
+import io.airlift.airline.Command;
import org.apache.commons.lang3.StringUtils;
import javax.batch.operations.JobOperator;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/Stop.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/Stop.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/Stop.java
index 6ccc89b..d183027 100644
--- a/tools/cli/src/main/java/org/apache/batchee/cli/command/Stop.java
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/Stop.java
@@ -16,8 +16,8 @@
*/
package org.apache.batchee.cli.command;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
@Command(name = "stop", description = "stop a batch from its id")
public class Stop extends SocketCommand {
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/main/java/org/apache/batchee/cli/command/UserCommand.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/main/java/org/apache/batchee/cli/command/UserCommand.java b/tools/cli/src/main/java/org/apache/batchee/cli/command/UserCommand.java
new file mode 100644
index 0000000..3309e76
--- /dev/null
+++ b/tools/cli/src/main/java/org/apache/batchee/cli/command/UserCommand.java
@@ -0,0 +1,22 @@
+/*
+ * 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.batchee.cli.command;
+
+// use io.airlift.airline.Command and more generally io.airlift.airline.*
+// and register your command using META-INF/services/org.apache.batchee.cli.command.UserCommand mecanism
+public interface UserCommand extends Runnable {
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/test/java/org/apache/batchee/cli/MainTest.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/test/java/org/apache/batchee/cli/MainTest.java b/tools/cli/src/test/java/org/apache/batchee/cli/MainTest.java
index b16f5ce..2774fcc 100644
--- a/tools/cli/src/test/java/org/apache/batchee/cli/MainTest.java
+++ b/tools/cli/src/test/java/org/apache/batchee/cli/MainTest.java
@@ -106,7 +106,7 @@ public class MainTest {
do {
idx = out.indexOf(str);
} while (idx < 0);
- final int end = out.indexOf(System.getProperty("line.separator"));
+ final int end = out.lastIndexOf(System.getProperty("line.separator"));
final long id = Long.parseLong(out.substring(idx + str.length(), end));
main(new String[]{"stop", "-id", Long.toString(id), "-socket", "1236"});
@@ -183,6 +183,14 @@ public class MainTest {
assertEquals("start stop", MyLifecycle.result);
}
+ @Test
+ public void user() {
+ for (int i = 1; i < 3; i++) {
+ main(new String[]{"user" + i});
+ assertThat(stdout.getLog(), containsString("User " + i + " called"));
+ }
+ }
+
public static class MyLifecycle implements Lifecycle<String> {
private static String result;
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/test/java/org/apache/batchee/cli/command/User1.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/test/java/org/apache/batchee/cli/command/User1.java b/tools/cli/src/test/java/org/apache/batchee/cli/command/User1.java
new file mode 100644
index 0000000..1688693
--- /dev/null
+++ b/tools/cli/src/test/java/org/apache/batchee/cli/command/User1.java
@@ -0,0 +1,27 @@
+/*
+ * 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.batchee.cli.command;
+
+import io.airlift.airline.Command;
+
+@Command(name = "user1")
+public class User1 implements UserCommand {
+ @Override
+ public void run() {
+ System.out.println("User 1 called");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/test/java/org/apache/batchee/cli/command/User2.java
----------------------------------------------------------------------
diff --git a/tools/cli/src/test/java/org/apache/batchee/cli/command/User2.java b/tools/cli/src/test/java/org/apache/batchee/cli/command/User2.java
new file mode 100644
index 0000000..773c2ae
--- /dev/null
+++ b/tools/cli/src/test/java/org/apache/batchee/cli/command/User2.java
@@ -0,0 +1,27 @@
+/*
+ * 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.batchee.cli.command;
+
+import io.airlift.airline.Command;
+
+@Command(name = "user2")
+public class User2 implements UserCommand {
+ @Override
+ public void run() {
+ System.out.println("User 2 called");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/0ab8285d/tools/cli/src/test/resources/META-INF/services/org.apache.batchee.cli.command.UserCommand
----------------------------------------------------------------------
diff --git a/tools/cli/src/test/resources/META-INF/services/org.apache.batchee.cli.command.UserCommand b/tools/cli/src/test/resources/META-INF/services/org.apache.batchee.cli.command.UserCommand
new file mode 100644
index 0000000..bd05bf5
--- /dev/null
+++ b/tools/cli/src/test/resources/META-INF/services/org.apache.batchee.cli.command.UserCommand
@@ -0,0 +1,2 @@
+org.apache.batchee.cli.command.User1
+org.apache.batchee.cli.command.User2