You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by dl...@apache.org on 2013/05/23 02:08:38 UTC
svn commit: r1485516 - in /accumulo/trunk:
core/src/main/java/org/apache/accumulo/core/util/shell/
core/src/main/java/org/apache/accumulo/core/util/shell/commands/
examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/
examples/simple...
Author: dlmarion
Date: Thu May 23 00:08:38 2013
New Revision: 1485516
URL: http://svn.apache.org/r1485516
Log:
ACCUMULO-1399: Added support for shell extensions and scripts
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/
accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
accumulo/trunk/examples/simple/src/main/resources/
accumulo/trunk/examples/simple/src/main/resources/META-INF/
accumulo/trunk/examples/simple/src/main/resources/META-INF/services/
accumulo/trunk/examples/simple/src/main/resources/META-INF/services/org.apache.accumulo.core.util.shell.ShellExtension
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
Modified: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java?rev=1485516&r1=1485515&r2=1485516&view=diff
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java (original)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java Thu May 23 00:08:38 2013
@@ -92,6 +92,7 @@ import org.apache.accumulo.core.util.she
import org.apache.accumulo.core.util.shell.commands.ExecfileCommand;
import org.apache.accumulo.core.util.shell.commands.ExitCommand;
import org.apache.accumulo.core.util.shell.commands.ExportTableCommand;
+import org.apache.accumulo.core.util.shell.commands.ExtensionCommand;
import org.apache.accumulo.core.util.shell.commands.FateCommand;
import org.apache.accumulo.core.util.shell.commands.FlushCommand;
import org.apache.accumulo.core.util.shell.commands.FormatterCommand;
@@ -125,6 +126,7 @@ import org.apache.accumulo.core.util.she
import org.apache.accumulo.core.util.shell.commands.RenameTableCommand;
import org.apache.accumulo.core.util.shell.commands.RevokeCommand;
import org.apache.accumulo.core.util.shell.commands.ScanCommand;
+import org.apache.accumulo.core.util.shell.commands.ScriptCommand;
import org.apache.accumulo.core.util.shell.commands.SetAuthsCommand;
import org.apache.accumulo.core.util.shell.commands.SetGroupsCommand;
import org.apache.accumulo.core.util.shell.commands.SetIterCommand;
@@ -338,7 +340,7 @@ public class Shell extends ShellOptions
new InterpreterCommand(), new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new ScanCommand()};
Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(), new ListScansCommand(), new ListCompactionsCommand(), new TraceCommand(),
new PingCommand()};
- Command[] execCommands = {new ExecfileCommand(), new HistoryCommand()};
+ Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new ExtensionCommand(), new ScriptCommand()};
Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new QuitCommand()};
Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new InfoCommand(), new QuestionCommand()};
Command[] iteratorCommands = {new DeleteIterCommand(), new DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new SetScanIterCommand(),
@@ -1062,4 +1064,9 @@ public class Shell extends ShellOptions
public boolean hasExited() {
return exit;
}
+
+ public boolean isTabCompletion() {
+ return tabCompletion;
+ }
+
}
Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java (added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/ShellExtension.java Thu May 23 00:08:38 2013
@@ -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.accumulo.core.util.shell;
+
+import org.apache.accumulo.core.util.shell.Shell.Command;
+
+public abstract class ShellExtension {
+
+ public abstract String getExtensionName();
+
+ public abstract Command[] getCommands();
+
+}
Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java (added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java Thu May 23 00:08:38 2013
@@ -0,0 +1,102 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.util.HashSet;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellExtension;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class ExtensionCommand extends Command {
+
+ protected Option enable, disable, list;
+
+ private static ServiceLoader<ShellExtension> extensions = null;
+
+ private Set<String> loadedHeaders = new HashSet<String>();
+ private Set<String> loadedCommands = new HashSet<String>();
+ private Set<String> loadedExtensions = new TreeSet<String>();
+
+ public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+ if (cl.hasOption(enable.getOpt())) {
+ extensions = ServiceLoader.load(ShellExtension.class);
+ for (ShellExtension se : extensions) {
+
+ loadedExtensions.add(se.getExtensionName());
+ String header = "-- " + se.getExtensionName() + " Extension Commands ---------";
+ loadedHeaders.add(header);
+ shellState.commandGrouping.put(header, se.getCommands());
+
+ for (Command cmd : se.getCommands()) {
+ String name = se.getExtensionName() + "::" + cmd.getName();
+ loadedCommands.add(name);
+ shellState.commandFactory.put(name, cmd);
+ }
+ }
+ } else if (cl.hasOption(disable.getOpt())) {
+ //Remove the headers
+ for (String header : loadedHeaders) {
+ shellState.commandGrouping.remove(header);
+ }
+ //remove the commands
+ for (String name : loadedCommands) {
+ shellState.commandFactory.remove(name);
+ }
+ //Reset state
+ loadedExtensions.clear();
+ extensions.reload();
+ } else if (cl.hasOption(list.getOpt())) {
+ shellState.printLines(loadedExtensions.iterator(), true);
+ } else {
+ printHelp(shellState);
+ }
+ return 0;
+ }
+
+ public String description() {
+ return "Enable, disable, or list shell extensions";
+ }
+
+ public int numArgs() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return "extensions";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+ enable = new Option("e", "enable", false, "enable shell extensions");
+ disable = new Option("d", "disable", false, "disable shell extensions");
+ list = new Option("l", "list", false, "list shell extensions");
+ o.addOption(enable);
+ o.addOption(disable);
+ o.addOption(list);
+ return o;
+ }
+
+}
Added: accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java (added)
+++ accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScriptCommand.java Thu May 23 00:08:38 2013
@@ -0,0 +1,290 @@
+/*
+ * 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.accumulo.core.util.shell.commands;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class ScriptCommand extends Command {
+
+ // Command to allow user to run scripts, see JSR-223
+ // http://www.oracle.com/technetwork/articles/javase/scripting-140262.html
+
+ protected Option list, engine, script, file, args, out, function, object;
+ private static final String DEFAULT_ENGINE = "rhino";
+
+ public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+
+ boolean invoke = false;
+ ScriptEngineManager mgr = new ScriptEngineManager();
+
+ if (cl.hasOption(list.getOpt())) {
+ listJSREngineInfo(mgr, shellState);
+ } else if (cl.hasOption(file.getOpt()) || cl.hasOption(script.getOpt())) {
+ String engineName = DEFAULT_ENGINE;
+ if (cl.hasOption(engine.getOpt())) {
+ engineName = cl.getOptionValue(engine.getOpt());
+ }
+ ScriptEngine engine = mgr.getEngineByName(engineName);
+ if (null == engine) {
+ shellState.printException(new Exception(engineName + " not found"));
+ return 1;
+ }
+
+ if (cl.hasOption(object.getOpt()) || cl.hasOption(function.getOpt())) {
+ if (!(engine instanceof Invocable)) {
+ shellState.printException(new Exception(engineName + " does not support invoking functions or methods"));
+ return 1;
+ }
+ invoke = true;
+ }
+
+ ScriptContext ctx = new SimpleScriptContext();
+
+ // Put the following objects into the context so that they
+ // are available to the scripts
+ // TODO: What else should go in here?
+ Bindings b = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+ b.put("connection", shellState.getConnector());
+
+ List<Object> argValues = new ArrayList<Object>();
+ if (cl.hasOption(args.getOpt())) {
+ String[] argList = cl.getOptionValue(args.getOpt()).split(",");
+ for (String arg : argList) {
+ String[] parts = arg.split("=");
+ if (parts.length == 0) {
+ continue;
+ } else if (parts.length == 1) {
+ b.put(parts[0], null);
+ argValues.add(null);
+ } else if (parts.length == 2) {
+ b.put(parts[0], parts[1]);
+ argValues.add(parts[1]);
+ }
+ }
+ }
+ ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ Object[] argArray = argValues.toArray(new Object[argValues.size()]);
+
+ Writer writer = null;
+ if (cl.hasOption(out.getOpt())) {
+ File f = new File(cl.getOptionValue(out.getOpt()));
+ writer = new FileWriter(f);
+ ctx.setWriter(writer);
+ }
+
+ if (cl.hasOption(file.getOpt())) {
+ File f = new File(cl.getOptionValue(file.getOpt()));
+ if (!f.exists()) {
+ if (null != writer) {
+ writer.close();
+ }
+ shellState.printException(new Exception(f.getAbsolutePath() + " not found"));
+ return 1;
+ }
+ Reader reader = new FileReader(f);
+ try {
+ engine.eval(reader, ctx);
+ if (invoke) {
+ this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+ }
+ } catch (ScriptException ex) {
+ shellState.printException(ex);
+ return 1;
+ } finally {
+ reader.close();
+ if (null != writer) {
+ writer.close();
+ }
+ }
+ } else if (cl.hasOption(script.getOpt())) {
+ String inlineScript = cl.getOptionValue(script.getOpt());
+ try {
+ if (engine instanceof Compilable) {
+ Compilable compiledEng = (Compilable) engine;
+ CompiledScript script = compiledEng.compile(inlineScript);
+ script.eval(ctx);
+ if (invoke) {
+ this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+ }
+ } else {
+ engine.eval(inlineScript, ctx);
+ if (invoke) {
+ this.invokeFunctionOrMethod(shellState, engine, cl, argArray);
+ }
+ }
+ } catch (ScriptException ex) {
+ shellState.printException(ex);
+ return 1;
+ } finally {
+ if (null != writer) {
+ writer.close();
+ }
+ }
+ }
+ if (null != writer) {
+ writer.close();
+ }
+
+ } else {
+ printHelp(shellState);
+ }
+ return 0;
+ }
+
+ public String description() {
+ return "execute JSR-223 scripts";
+ }
+
+ public int numArgs() {
+ return 0;
+ }
+
+ @Override
+ public String getName() {
+ return "script";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ engine = new Option("e", "engine", false, "engine name, defaults to JDK default (Rhino)");
+ engine.setArgName("engineName");
+ engine.setArgs(1);
+ engine.setRequired(false);
+ o.addOption(engine);
+
+ OptionGroup inputGroup = new OptionGroup();
+ list = new Option("l", "list", false, "list available script engines");
+ inputGroup.addOption(list);
+
+ script = new Option("s", "script", true, "use inline script");
+ script.setArgName("script text");
+ script.setArgs(1);
+ script.setRequired(false);
+ inputGroup.addOption(script);
+
+ file = new Option("f", "file", true, "use script file");
+ file.setArgName("fileName");
+ file.setArgs(1);
+ file.setRequired(false);
+
+ inputGroup.addOption(file);
+ inputGroup.setRequired(true);
+ o.addOptionGroup(inputGroup);
+
+ OptionGroup invokeGroup = new OptionGroup();
+ object = new Option("obj", "object", true, "name of object");
+ object.setArgs(1);
+ object.setArgName("objectName:methodName");
+ object.setRequired(false);
+ invokeGroup.addOption(object);
+
+ function = new Option("fx", "function", true, "invoke a script function");
+ function.setArgName("functionName");
+ function.setArgs(1);
+ function.setRequired(false);
+ invokeGroup.addOption(function);
+ invokeGroup.setRequired(false);
+ o.addOptionGroup(invokeGroup);
+
+ args = new Option("a", "args", true, "comma separated list of key=value arguments");
+ args.setArgName("property1=value1,propert2=value2,...");
+ args.setArgs(Option.UNLIMITED_VALUES);
+ args.setRequired(false);
+ o.addOption(args);
+
+ out = new Option("o", "output", true, "output file");
+ out.setArgName("fileName");
+ out.setArgs(1);
+ out.setRequired(false);
+ o.addOption(out);
+
+ return o;
+ }
+
+ private void listJSREngineInfo(ScriptEngineManager mgr, Shell shellState) throws IOException {
+ List<ScriptEngineFactory> factories = mgr.getEngineFactories();
+ Set<String> lines = new TreeSet<String>();
+ for (ScriptEngineFactory factory : factories) {
+ lines.add("ScriptEngineFactory Info");
+ String engName = factory.getEngineName();
+ String engVersion = factory.getEngineVersion();
+ String langName = factory.getLanguageName();
+ String langVersion = factory.getLanguageVersion();
+ lines.add("\tScript Engine: " + engName + " (" + engVersion + ")");
+ List<String> engNames = factory.getNames();
+ for (String name : engNames) {
+ lines.add("\tEngine Alias: " + name);
+ }
+ lines.add("\tLanguage: " + langName + " (" + langVersion + ")");
+ }
+ shellState.printLines(lines.iterator(), true);
+
+ }
+
+ private void invokeFunctionOrMethod(Shell shellState, ScriptEngine engine, CommandLine cl, Object[] args) {
+ try {
+ Invocable inv = (Invocable) engine;
+ if (cl.hasOption(function.getOpt())) {
+ inv.invokeFunction(cl.getOptionValue(function.getOpt()), args);
+ } else if (cl.hasOption(object.getOpt())) {
+ String objectMethod = cl.getOptionValue(object.getOpt());
+ String[] parts = objectMethod.split(":");
+ if (!(parts.length == 2)) {
+ shellState.printException(new Exception("Object and Method must be supplied"));
+ return;
+ }
+ String objectName = parts[0];
+ String methodName = parts[1];
+ Object obj = engine.get(objectName);
+ inv.invokeMethod(obj, methodName, args);
+
+ }
+ } catch (Exception e) {
+ shellState.printException(e);
+ }
+ }
+
+}
Added: accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java (added)
+++ accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/DebugCommand.java Thu May 23 00:08:38 2013
@@ -0,0 +1,43 @@
+/*
+ * 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.accumulo.examples.simple.shell;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class DebugCommand extends Command {
+
+ public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+ Set<String> lines = new TreeSet<String>();
+ lines.add("This is a test");
+ shellState.printLines(lines.iterator(), true);
+ return 0;
+ }
+
+ public String description() {
+ return "prints a message to test extension feature";
+ }
+
+ public int numArgs() {
+ return 0;
+ }
+
+}
Added: accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java
URL: http://svn.apache.org/viewvc/accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java (added)
+++ accumulo/trunk/examples/simple/src/main/java/org/apache/accumulo/examples/simple/shell/MyAppShellExtension.java Thu May 23 00:08:38 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.accumulo.examples.simple.shell;
+
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellExtension;
+
+public class MyAppShellExtension extends ShellExtension {
+
+ public String getExtensionName() {
+ return "MyApp";
+ }
+
+ @Override
+ public Command[] getCommands() {
+ return new Command[] { new DebugCommand() };
+ }
+
+}
Added: accumulo/trunk/examples/simple/src/main/resources/META-INF/services/org.apache.accumulo.core.util.shell.ShellExtension
URL: http://svn.apache.org/viewvc/accumulo/trunk/examples/simple/src/main/resources/META-INF/services/org.apache.accumulo.core.util.shell.ShellExtension?rev=1485516&view=auto
==============================================================================
--- accumulo/trunk/examples/simple/src/main/resources/META-INF/services/org.apache.accumulo.core.util.shell.ShellExtension (added)
+++ accumulo/trunk/examples/simple/src/main/resources/META-INF/services/org.apache.accumulo.core.util.shell.ShellExtension Thu May 23 00:08:38 2013
@@ -0,0 +1 @@
+org.apache.accumulo.examples.simple.shell.MyAppShellExtension
\ No newline at end of file