accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ctubb...@apache.org
Subject [02/61] [abbrv] [partial] accumulo git commit: ACCUMULO-722 put trunk in my sandbox
Date Thu, 03 Mar 2016 21:59:27 GMT
http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
new file mode 100644
index 0000000..d70629f
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
@@ -0,0 +1,116 @@
+/*
+ * 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.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+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 RevokeCommand extends TableOperation {
+  {
+    disableUnflaggedTableOptions();
+  }
+  
+  private Option systemOpt, userOpt;
+  private String user;
+  private String[] permission;
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    user = cl.hasOption(userOpt.getOpt()) ? cl.getOptionValue(userOpt.getOpt()) : shellState.getConnector().whoami();
+    
+    permission = cl.getArgs()[0].split("\\.", 2);
+    if (cl.hasOption(systemOpt.getOpt()) && permission[0].equalsIgnoreCase("System")) {
+      try {
+        shellState.getConnector().securityOperations().revokeSystemPermission(user, SystemPermission.valueOf(permission[1]));
+        Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission");
+      } catch (IllegalArgumentException e) {
+        throw new BadArgumentException("No such system permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+      }
+    } else if (permission[0].equalsIgnoreCase("Table")) {
+      super.execute(fullCommand, cl, shellState);
+    } else {
+      throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    }
+    return 0;
+  }
+  
+  @Override
+  protected void doTableOp(Shell shellState, String tableName) throws Exception {
+    try {
+      shellState.getConnector().securityOperations().revokeTablePermission(user, tableName, TablePermission.valueOf(permission[1]));
+      Shell.log.debug("Revoked from " + user + " the " + permission[1] + " permission on table " + tableName);
+    } catch (IllegalArgumentException e) {
+      throw new IllegalArgumentException("No such table permission", e);
+    }
+  }
+  
+  @Override
+  public String description() {
+    return "revokes system or table permissions from a user";
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <permission>";
+  }
+  
+  @Override
+  public void registerCompletion(Token root, Map<Command.CompletionSet,Set<String>> completionSet) {
+    Token cmd = new Token(getName());
+    cmd.addSubcommand(new Token(TablePermission.printableValues()));
+    cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+    root.addSubcommand(cmd);
+  }
+  
+  @Override
+  public Options getOptions() {
+    super.getOptions();
+    Options o = new Options();
+    
+    OptionGroup group = new OptionGroup();
+    
+    systemOpt = new Option("s", "system", false, "revoke a system permission");
+    
+    group.addOption(systemOpt);
+    group.addOption(optTableName);
+    group.addOption(optTablePattern);
+    
+    o.addOptionGroup(group);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("username");
+    userOpt.setRequired(true);
+    o.addOption(userOpt);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
new file mode 100644
index 0000000..9ecfde8
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
@@ -0,0 +1,229 @@
+/*
+ * 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.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.ScannerBase;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.BinaryFormatter;
+import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.AccumuloClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class ScanCommand extends Command {
+  
+  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt, formatterOpt;
+  protected Option timestampOpt;
+  private Option optStartRowExclusive;
+  private Option optEndRowExclusive;
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    Class<? extends Formatter> formatter = null;
+    
+    // Use the configured formatter unless one was provided
+    if (!cl.hasOption(formatterOpt.getOpt())) {
+      formatter = FormatterCommand.getCurrentFormatter(tableName, shellState);
+    }
+    
+    // handle first argument, if present, the authorizations list to
+    // scan with
+    Authorizations auths = getAuths(cl, shellState);
+    Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    
+    // handle session-specific scan iterators
+    addScanIterators(shellState, scanner, tableName);
+    
+    // handle remaining optional arguments
+    scanner.setRange(getRange(cl));
+    
+    // handle columns
+    fetchColumns(cl, scanner);
+    
+    // output the records
+    if (cl.hasOption(showFewOpt.getOpt())) {
+      String showLength = cl.getOptionValue(showFewOpt.getOpt());
+      try {
+        int length = Integer.parseInt(showLength);
+        if (length < 1) {
+          throw new IllegalArgumentException();
+        }
+        BinaryFormatter.getlength(length);
+        printBinaryRecords(cl, shellState, scanner);
+      } catch (NumberFormatException nfe) {
+        shellState.getReader().printString("Arg must be an integer. \n");
+      } catch (IllegalArgumentException iae) {
+        shellState.getReader().printString("Arg must be greater than one. \n");
+      }
+      
+    } else {
+      if (null == formatter) {
+        printRecords(cl, shellState, scanner);
+      } else {
+        printRecords(cl, shellState, scanner, formatter);
+      }
+    }
+    
+    return 0;
+  }
+  
+  protected void addScanIterators(Shell shellState, Scanner scanner, String tableName) {
+    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(shellState.getTableName());
+    if (tableScanIterators == null) {
+      Shell.log.debug("Found no scan iterators to set");
+      return;
+    }
+    Shell.log.debug("Found " + tableScanIterators.size() + " scan iterators to set");
+    
+    for (IteratorSetting setting : tableScanIterators) {
+      Shell.log.debug("Setting scan iterator " + setting.getName() + " at priority " + setting.getPriority() + " using class name "
+          + setting.getIteratorClass());
+      for (Entry<String,String> option : setting.getOptions().entrySet()) {
+        Shell.log.debug("Setting option for " + setting.getName() + ": " + option.getKey() + "=" + option.getValue());
+      }
+      scanner.addScanIterator(setting);
+    }
+  }
+  
+  protected void printRecords(CommandLine cl, Shell shellState, Iterable<Entry<Key,Value>> scanner) throws IOException {
+    if (cl.hasOption(formatterOpt.getOpt())) {
+      try {
+        String className = cl.getOptionValue(formatterOpt.getOpt());
+        Class<? extends Formatter> formatterClass = AccumuloClassLoader.loadClass(className, Formatter.class);
+        
+        printRecords(cl, shellState, scanner, formatterClass);
+      } catch (ClassNotFoundException e) {
+        shellState.getReader().printString("Formatter class could not be loaded.\n" + e.getMessage() + "\n");
+      }
+    } else {
+      shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
+    }
+  }
+  
+  protected void printRecords(CommandLine cl, Shell shellState, Iterable<Entry<Key,Value>> scanner, Class<? extends Formatter> formatter) throws IOException {
+    shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()), formatter);
+  }
+  
+  protected void printBinaryRecords(CommandLine cl, Shell shellState, Iterable<Entry<Key,Value>> scanner) throws IOException {
+    shellState.printBinaryRecords(scanner, cl.hasOption(timestampOpt.getOpt()), !cl.hasOption(disablePaginationOpt.getOpt()));
+  }
+  
+  protected void fetchColumns(CommandLine cl, ScannerBase scanner) throws UnsupportedEncodingException {
+    if (cl.hasOption(scanOptColumns.getOpt())) {
+      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
+        String sa[] = a.split(":", 2);
+        if (sa.length == 1)
+          scanner.fetchColumnFamily(new Text(a.getBytes(Shell.CHARSET)));
+        else
+          scanner.fetchColumn(new Text(sa[0].getBytes(Shell.CHARSET)), new Text(sa[1].getBytes(Shell.CHARSET)));
+      }
+    }
+  }
+  
+  protected Range getRange(CommandLine cl) throws UnsupportedEncodingException {
+    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
+      // did not see a way to make commons cli do this check... it has mutually exclusive options but does not support the or
+      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
+          + ") are mutally exclusive ");
+    }
+    
+    if (cl.hasOption(scanOptRow.getOpt())) {
+      return new Range(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET)));
+    } else {
+      Text startRow = OptUtil.getStartRow(cl);
+      Text endRow = OptUtil.getEndRow(cl);
+      boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
+      boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
+      return new Range(startRow, startInclusive, endRow, endInclusive);
+    }
+  }
+  
+  protected Authorizations getAuths(CommandLine cl, Shell shellState) throws AccumuloSecurityException, AccumuloException {
+    String user = shellState.getConnector().whoami();
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    if (cl.hasOption(scanOptAuths.getOpt())) {
+      auths = CreateUserCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
+    }
+    return auths;
+  }
+  
+  @Override
+  public String description() {
+    return "scans the table, and displays the resulting records";
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations (all user auths are used if this argument is not specified)");
+    optStartRowExclusive = new Option("be", "begin-exclusive", false, "make start row exclusive (by default it's inclusive)");
+    optStartRowExclusive.setArgName("begin-exclusive");
+    optEndRowExclusive = new Option("ee", "end-exclusive", false, "make end row exclusive (by default it's inclusive)");
+    optEndRowExclusive.setArgName("end-exclusive");
+    scanOptRow = new Option("r", "row", true, "row to scan");
+    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
+    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
+    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
+    showFewOpt = new Option("f", "show few", true, "show only a specified number of characters");
+    formatterOpt = new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
+    
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    scanOptRow.setArgName("row");
+    scanOptColumns.setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
+    showFewOpt.setRequired(false);
+    showFewOpt.setArgName("int");
+    formatterOpt.setArgName("className");
+    
+    o.addOption(scanOptAuths);
+    o.addOption(scanOptRow);
+    o.addOption(OptUtil.startRowOpt());
+    o.addOption(OptUtil.endRowOpt());
+    o.addOption(optStartRowExclusive);
+    o.addOption(optEndRowExclusive);
+    o.addOption(scanOptColumns);
+    o.addOption(timestampOpt);
+    o.addOption(disablePaginationOpt);
+    o.addOption(OptUtil.tableOpt("table to be scanned"));
+    o.addOption(showFewOpt);
+    o.addOption(formatterOpt);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
new file mode 100644
index 0000000..e3d0878
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetAuthsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+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 SetAuthsCommand extends Command {
+  private Option userOpt;
+  private Option scanOptAuths;
+  private Option clearOptAuths;
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException {
+    String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    String scanOpts = cl.hasOption(clearOptAuths.getOpt()) ? null : cl.getOptionValue(scanOptAuths.getOpt());
+    shellState.getConnector().securityOperations().changeUserAuthorizations(user, CreateUserCommand.parseAuthorizations(scanOpts));
+    Shell.log.debug("Changed record-level authorizations for user " + user);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sets the maximum scan authorizations for a user";
+  }
+  
+  @Override
+  public void registerCompletion(Token root, Map<Command.CompletionSet,Set<String>> completionSet) {
+    registerCompletionForUsers(root, completionSet);
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    OptionGroup setOrClear = new OptionGroup();
+    scanOptAuths = new Option("s", "scan-authorizations", true, "scan authorizations to set");
+    scanOptAuths.setArgName("comma-separated-authorizations");
+    setOrClear.addOption(scanOptAuths);
+    clearOptAuths = new Option("c", "clear-authorizations", false, "clear the scan authorizations");
+    setOrClear.addOption(clearOptAuths);
+    setOrClear.setRequired(true);
+    o.addOptionGroup(setOrClear);
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
new file mode 100644
index 0000000..a70dd2c
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetGroupsCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+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.Options;
+import org.apache.hadoop.io.Text;
+
+public class SetGroupsCommand extends Command {
+  @Override
+  public String description() {
+    return "sets the locality groups for a given table (for binary or commas, use Java API)";
+  }
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    HashMap<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
+    
+    for (String arg : cl.getArgs()) {
+      String sa[] = arg.split("=", 2);
+      if (sa.length < 2)
+        throw new IllegalArgumentException("Missing '='");
+      String group = sa[0];
+      HashSet<Text> colFams = new HashSet<Text>();
+      
+      for (String family : sa[1].split(",")) {
+        colFams.add(new Text(family.getBytes(Shell.CHARSET)));
+      }
+      
+      groups.put(group, colFams);
+    }
+    
+    shellState.getConnector().tableOperations().setLocalityGroups(tableName, groups);
+    
+    return 0;
+  }
+  
+  @Override
+  public int numArgs() {
+    return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}}";
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options opts = new Options();
+    opts.addOption(OptUtil.tableOpt("table to fetch locality groups for"));
+    return opts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
new file mode 100644
index 0000000..0b054b6
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetIterCommand.java
@@ -0,0 +1,254 @@
+/*
+ * 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.IOException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import jline.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.AggregatingIterator;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.OptionDescriber;
+import org.apache.accumulo.core.iterators.OptionDescriber.IteratorOptions;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.iterators.aggregation.Aggregator;
+import org.apache.accumulo.core.iterators.user.AgeOffFilter;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.accumulo.core.iterators.user.ReqVisFilter;
+import org.apache.accumulo.core.iterators.user.VersioningIterator;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+import org.apache.accumulo.start.classloader.AccumuloClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+@SuppressWarnings("deprecation")
+public class SetIterCommand extends Command {
+  
+  private Option mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt, priorityOpt;
+  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, classnameTypeOpt;
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      IOException, ShellCommandException {
+    String tableName = OptUtil.getTableOpt(cl, shellState);
+    
+    int priority = Integer.parseInt(cl.getOptionValue(priorityOpt.getOpt()));
+    
+    Map<String,String> options = new HashMap<String,String>();
+    String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
+    if (cl.hasOption(aggTypeOpt.getOpt())) {
+      Shell.log.warn("aggregators are deprecated");
+      classname = AggregatingIterator.class.getName();
+    } else if (cl.hasOption(regexTypeOpt.getOpt()))
+      classname = RegExFilter.class.getName();
+    else if (cl.hasOption(ageoffTypeOpt.getOpt()))
+      classname = AgeOffFilter.class.getName();
+    else if (cl.hasOption(versionTypeOpt.getOpt()))
+      classname = VersioningIterator.class.getName();
+    else if (cl.hasOption(reqvisTypeOpt.getOpt()))
+      classname = ReqVisFilter.class.getName();
+    
+    if (!shellState.getConnector().instanceOperations().testClassLoad(classname, SortedKeyValueIterator.class.getName()))
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    
+    String name = cl.getOptionValue(nameOpt.getOpt(), setUpOptions(shellState.getReader(), classname, options));
+    
+    String aggregatorClass = options.get("aggregatorClass");
+    if (aggregatorClass != null && !shellState.getConnector().instanceOperations().testClassLoad(aggregatorClass, Aggregator.class.getName()))
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + aggregatorClass + " as type "
+          + Aggregator.class.getName());
+    
+    setTableProperties(cl, shellState, tableName, priority, options, classname, name);
+    
+    return 0;
+  }
+  
+  protected void setTableProperties(CommandLine cl, Shell shellState, String tableName, int priority, Map<String,String> options, String classname, String name)
+      throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // remove empty values
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); i.hasNext();) {
+      Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty())
+        i.remove();
+    }
+    EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+    if (cl.hasOption(mincScopeOpt.getOpt()))
+      scopes.add(IteratorScope.minc);
+    if (cl.hasOption(majcScopeOpt.getOpt()))
+      scopes.add(IteratorScope.majc);
+    if (cl.hasOption(scanScopeOpt.getOpt()))
+      scopes.add(IteratorScope.scan);
+    if (scopes.isEmpty())
+      throw new IllegalArgumentException("You must select at least one scope to configure");
+    
+    IteratorSetting setting = new IteratorSetting(priority, name, classname, options);
+    shellState.getConnector().tableOperations().attachIterator(tableName, setting, scopes);
+  }
+  
+  private static String setUpOptions(ConsoleReader reader, String className, Map<String,String> options) throws IOException, ShellCommandException {
+    String input;
+    OptionDescriber skvi;
+    Class<? extends OptionDescriber> clazz;
+    try {
+      clazz = AccumuloClassLoader.loadClass(className, OptionDescriber.class);
+      skvi = clazz.newInstance();
+    } catch (ClassNotFoundException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (InstantiationException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (IllegalAccessException e) {
+      throw new IllegalArgumentException(e.getMessage());
+    } catch (ClassCastException e) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Unable to load " + className + " as type " + OptionDescriber.class.getName()
+          + "; configure with 'config' instead");
+    }
+    
+    IteratorOptions itopts = skvi.describeOptions();
+    if (itopts.getName() == null)
+      throw new IllegalArgumentException(className + " described its default distinguishing name as null");
+    
+    String shortClassName = className;
+    if (className.contains("."))
+      shortClassName = className.substring(className.lastIndexOf('.') + 1);
+    
+    Map<String,String> localOptions = new HashMap<String,String>();
+    do {
+      // clean up the overall options that caused things to fail
+      for (String key : localOptions.keySet())
+        options.remove(key);
+      localOptions.clear();
+      
+      reader.printString(itopts.getDescription());
+      reader.printNewline();
+      
+      String prompt;
+      if (itopts.getNamedOptions() != null) {
+        for (Entry<String,String> e : itopts.getNamedOptions().entrySet()) {
+          prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " parameter " + e.getKey() + ", " + e.getValue() + ": ";
+          reader.flushConsole();
+          input = reader.readLine(prompt);
+          if (input == null) {
+            reader.printNewline();
+            throw new IOException("Input stream closed");
+          } else {
+            input = new String(input);
+          }
+          // Places all Parameters and Values into the LocalOptions, even if the value is "".
+          // This allows us to check for "" values when setting the iterators and allows us to remove
+          // the parameter and value from the table property.
+          localOptions.put(e.getKey(), input);
+        }
+      }
+      
+      if (itopts.getUnnamedOptionDescriptions() != null) {
+        for (String desc : itopts.getUnnamedOptionDescriptions()) {
+          reader.printString(Shell.repeat("-", 10) + "> entering options: " + desc + "\n");
+          input = "start";
+          while (true) {
+            prompt = Shell.repeat("-", 10) + "> set " + shortClassName + " option (<name> <value>, hit enter to skip): ";
+            
+            reader.flushConsole();
+            input = reader.readLine(prompt);
+            if (input == null) {
+              reader.printNewline();
+              throw new IOException("Input stream closed");
+            } else {
+              input = new String(input);
+            }
+            
+            if (input.length() == 0)
+              break;
+            
+            String[] sa = input.split(" ", 2);
+            localOptions.put(sa[0], sa[1]);
+          }
+        }
+      }
+      
+      options.putAll(localOptions);
+      if (!skvi.validateOptions(options))
+        reader.printString("invalid options for " + clazz.getName() + "\n");
+      
+    } while (!skvi.validateOptions(options));
+    return itopts.getName();
+  }
+  
+  @Override
+  public String description() {
+    return "sets a table-specific iterator";
+  }
+  
+  public Options getOptions() {
+    Options o = new Options();
+    
+    priorityOpt = new Option("p", "priority", true, "the order in which the iterator is applied");
+    priorityOpt.setArgName("pri");
+    priorityOpt.setRequired(true);
+    
+    nameOpt = new Option("n", "name", true, "iterator to set");
+    nameOpt.setArgName("itername");
+    
+    mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "applied at minor compaction");
+    majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "applied at major compaction");
+    scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "applied at scan time");
+    
+    OptionGroup typeGroup = new OptionGroup();
+    classnameTypeOpt = new Option("class", "class-name", true, "a java class that implements SortedKeyValueIterator");
+    classnameTypeOpt.setArgName("name");
+    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
+    regexTypeOpt = new Option("regex", "regular-expression", false, "a regex matching iterator");
+    versionTypeOpt = new Option("vers", "version", false, "a versioning iterator");
+    reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an iterator that omits entries with empty visibilities");
+    ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off iterator");
+    
+    typeGroup.addOption(classnameTypeOpt);
+    typeGroup.addOption(aggTypeOpt);
+    typeGroup.addOption(regexTypeOpt);
+    typeGroup.addOption(versionTypeOpt);
+    typeGroup.addOption(reqvisTypeOpt);
+    typeGroup.addOption(ageoffTypeOpt);
+    typeGroup.setRequired(true);
+    
+    o.addOption(OptUtil.tableOpt("table to configure iterators on"));
+    o.addOption(priorityOpt);
+    o.addOption(nameOpt);
+    o.addOption(mincScopeOpt);
+    o.addOption(majcScopeOpt);
+    o.addOption(scanScopeOpt);
+    o.addOptionGroup(typeGroup);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
new file mode 100644
index 0000000..4159e8b
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SetScanIterCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.ShellCommandException;
+import org.apache.accumulo.core.util.shell.ShellCommandException.ErrorCode;
+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 SetScanIterCommand extends SetIterCommand {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+      IOException, ShellCommandException {
+    return super.execute(fullCommand, cl, shellState);
+  }
+  
+  @Override
+  protected void setTableProperties(CommandLine cl, Shell shellState, String tableName, int priority, Map<String,String> options, String classname, String name)
+      throws AccumuloException, AccumuloSecurityException, ShellCommandException, TableNotFoundException {
+    // instead of setting table properties, just put the options in a list to use at scan time
+    if (!shellState.getConnector().instanceOperations().testClassLoad(classname, SortedKeyValueIterator.class.getName()))
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, "Servers are unable to load " + classname + " as type "
+          + SortedKeyValueIterator.class.getName());
+    List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<IteratorSetting>();
+      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
+    }
+    IteratorSetting setting = new IteratorSetting(priority, name, classname);
+    setting.addOptions(options);
+    
+    // initialize a scanner to ensure the new setting does not conflict with existing settings
+    String user = shellState.getConnector().whoami();
+    Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+    for (IteratorSetting s : tableScanIterators) {
+      scanner.addScanIterator(s);
+    }
+    scanner.addScanIterator(setting);
+    
+    // if no exception has been thrown, it's safe to add it to the list
+    tableScanIterators.add(setting);
+    Shell.log.debug("Scan iterators :" + shellState.scanIteratorOptions.get(tableName));
+  }
+  
+  @Override
+  public String description() {
+    return "sets a table-specific scan iterator for this shell session";
+  }
+  
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    HashSet<OptionGroup> groups = new HashSet<OptionGroup>();
+    Options parentOptions = super.getOptions();
+    Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && !IteratorScope.minc.name().equals(o.getOpt()) && !IteratorScope.scan.name().equals(o.getOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    return modifiedOptions;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
new file mode 100644
index 0000000..77568a5
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SleepCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+
+public class SleepCommand extends Command {
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    double secs = Double.parseDouble(cl.getArgs()[0]);
+    Thread.sleep((long) (secs * 1000));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "sleeps for the given number of seconds";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <seconds>";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
new file mode 100644
index 0000000..f4b9f2a
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/SystemPermissionsCommand.java
@@ -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.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.SystemPermission;
+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 SystemPermissionsCommand extends Command {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws IOException {
+    for (String p : SystemPermission.printableValues())
+      shellState.getReader().printString(p + "\n");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid system permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
new file mode 100644
index 0000000..7fd6ad8
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class TableCommand extends Command {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+    String tableName = cl.getArgs()[0];
+    if (!shellState.getConnector().tableOperations().exists(tableName))
+      throw new TableNotFoundException(null, tableName, null);
+    
+    shellState.setTableName(tableName);
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified table";
+  }
+  
+  @Override
+  public void registerCompletion(Token root, Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForTables(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <tableName>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
new file mode 100644
index 0000000..9f55849
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TableOperation.java
@@ -0,0 +1,137 @@
+/**
+ * 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.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+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 abstract class TableOperation extends Command {
+  
+  protected Option optTablePattern, optTableName;
+  private boolean force = true;
+  private boolean useCommandLine = true;
+  
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws Exception {
+    // populate the tableSet set with the tables you want to operate on
+    SortedSet<String> tableSet = new TreeSet<String>();
+    if (cl.hasOption(optTablePattern.getOpt())) {
+      for (String table : shellState.getConnector().tableOperations().list())
+        if (table.matches(cl.getOptionValue(optTablePattern.getOpt())))
+          tableSet.add(table);
+    } else if (cl.hasOption(optTableName.getOpt())) {
+      tableSet.add(cl.getOptionValue(optTableName.getOpt()));
+    } else if (useCommandLine && cl.getArgs().length > 0) {
+      for (String tableName : cl.getArgs())
+        tableSet.add(tableName);
+    } else {
+      shellState.checkTableState();
+      tableSet.add(shellState.getTableName());
+    }
+    
+    if (tableSet.isEmpty())
+      Shell.log.warn("No tables found that match your criteria");
+    
+    boolean more = true;
+    // flush the tables
+    for (String tableName : tableSet) {
+      if (!more)
+        break;
+      if (!shellState.getConnector().tableOperations().exists(tableName))
+        throw new TableNotFoundException(null, tableName, null);
+      boolean operate = true;
+      if (!force) {
+        shellState.getReader().flushConsole();
+        String line = shellState.getReader().readLine(getName() + " { " + tableName + " } (yes|no)? ");
+        more = line != null;
+        operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+      }
+      if (operate)
+        doTableOp(shellState, tableName);
+    }
+    
+    return 0;
+  }
+  
+  protected abstract void doTableOp(Shell shellState, String tableName) throws Exception;
+  
+  @Override
+  public String description() {
+    return "makes a best effort to flush tables from memory to disk";
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    
+    optTablePattern = new Option("p", "pattern", true, "regex pattern of table names to operate on");
+    optTablePattern.setArgName("pattern");
+    
+    optTableName = new Option(Shell.tableOption, "table", true, "name of a table to operate on");
+    optTableName.setArgName("tableName");
+    
+    OptionGroup opg = new OptionGroup();
+    
+    opg.addOption(optTablePattern);
+    opg.addOption(optTableName);
+    
+    o.addOptionGroup(opg);
+    
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    if (useCommandLine)
+      return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+    else
+      return 0;
+  }
+  
+  protected void force() {
+    force = true;
+  }
+  
+  protected void noForce() {
+    force = false;
+  }
+  
+  protected void disableUnflaggedTableOptions() {
+    useCommandLine = false;
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " [<table>{ <table>}]";
+  }
+  
+  @Override
+  public void registerCompletion(Token root, Map<Command.CompletionSet,Set<String>> special) {
+    if (useCommandLine)
+      registerCompletionForTables(root, special);
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
new file mode 100644
index 0000000..d702f76
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablePermissionsCommand.java
@@ -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.core.util.shell.commands;
+
+import java.io.IOException;
+
+import org.apache.accumulo.core.security.TablePermission;
+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 TablePermissionsCommand extends Command {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws IOException {
+    for (String p : TablePermission.printableValues())
+      shellState.getReader().printString(p + "\n");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of valid table permissions";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
new file mode 100644
index 0000000..4c6413a
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TablesCommand.java
@@ -0,0 +1,63 @@
+/*
+ * 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.IOException;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+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.Options;
+
+public class TablesCommand extends Command {
+  private Option tableIdOption;
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    if (cl.hasOption(tableIdOption.getOpt())) {
+      Map<String,String> tableIds = shellState.getConnector().tableOperations().tableIdMap();
+      for (String tableName : shellState.getConnector().tableOperations().list())
+        shellState.getReader().printString(String.format("%-15s => %10s\n", tableName, tableIds.get(tableName)));
+    } else {
+      for (String table : shellState.getConnector().tableOperations().list())
+        shellState.getReader().printString(table + "\n");
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of all existing tables";
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    tableIdOption = new Option("l", "list-ids", false, "display internal table ids along with the table name");
+    o.addOption(tableIdOption);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
new file mode 100644
index 0000000..359897c
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/TraceCommand.java
@@ -0,0 +1,93 @@
+/*
+ * 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.IOException;
+import java.util.Map;
+
+import org.apache.accumulo.cloudtrace.instrument.Trace;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Range;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.trace.TraceDump;
+import org.apache.accumulo.core.trace.TraceDump.Printer;
+import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.UtilWaitThread;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.hadoop.io.Text;
+
+public class TraceCommand extends DebugCommand {
+  
+  public int execute(String fullCommand, CommandLine cl, final Shell shellState) throws IOException {
+    if (cl.getArgs().length == 1) {
+      if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+        Trace.on("shell:" + shellState.getCredentials().user);
+      } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+        if (Trace.isTracing()) {
+          long trace = Trace.currentTrace().traceId();
+          Trace.off();
+          for (int i = 0; i < 10; i++) {
+            try {
+              Map<String,String> properties = shellState.getConnector().instanceOperations().getSystemConfiguration();
+              String table = properties.get(Property.TRACE_TABLE.getKey());
+              String user = shellState.getConnector().whoami();
+              Authorizations auths = shellState.getConnector().securityOperations().getUserAuthorizations(user);
+              Scanner scanner = shellState.getConnector().createScanner(table, auths);
+              scanner.setRange(new Range(new Text(Long.toHexString(trace))));
+              final StringBuffer sb = new StringBuffer();
+              if (TraceDump.printTrace(scanner, new Printer() {
+                @Override
+                public void print(String line) {
+                  try {
+                    sb.append(line + "\n");
+                  } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                  }
+                }
+              }) > 0) {
+                shellState.getReader().printString(sb.toString());
+                break;
+              }
+            } catch (Exception ex) {
+              shellState.printException(ex);
+            }
+            shellState.getReader().printString("Waiting for trace information\n");
+            shellState.getReader().flushConsole();
+            UtilWaitThread.sleep(500);
+          }
+        } else {
+          shellState.getReader().printString("Not tracing\n");
+        }
+      } else
+        throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+    } else if (cl.getArgs().length == 0) {
+      shellState.getReader().printString(Trace.isTracing() ? "on\n" : "off\n");
+    } else {
+      shellState.printException(new IllegalArgumentException("Expected 0 or 1 argument. There were " + cl.getArgs().length + "."));
+      printHelp(shellState);
+      return 1;
+    }
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "turns trace logging on or off";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
new file mode 100644
index 0000000..9070c08
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserCommand.java
@@ -0,0 +1,70 @@
+/*
+ * 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.IOException;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.thrift.AuthInfo;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.Token;
+import org.apache.commons.cli.CommandLine;
+
+public class UserCommand extends Command {
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    // save old credentials and connection in case of failure
+    String user = cl.getArgs()[0];
+    byte[] pass;
+    
+    // We can't let the wrapping try around the execute method deal
+    // with the exceptions because we have to do something if one
+    // of these methods fails
+    String p = shellState.readMaskedLine("Enter password for user " + user + ": ", '*');
+    if (p == null) {
+      shellState.getReader().printNewline();
+      return 0;
+    } // user canceled
+    pass = p.getBytes();
+    shellState.updateUser(new AuthInfo(user, ByteBuffer.wrap(pass), shellState.getConnector().getInstance().getInstanceID()));
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "switches to the specified user";
+  }
+  
+  @Override
+  public void registerCompletion(Token root, Map<Command.CompletionSet,Set<String>> special) {
+    registerCompletionForUsers(root, special);
+  }
+  
+  @Override
+  public String usage() {
+    return getName() + " <username>";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 1;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
new file mode 100644
index 0000000..3042445
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
@@ -0,0 +1,86 @@
+/*
+ * 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.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TablePermission;
+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.Options;
+
+public class UserPermissionsCommand extends Command {
+  private Option userOpt;
+  private static int runOnce = 0;
+  
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    String user = cl.getOptionValue(userOpt.getOpt(), shellState.getConnector().whoami());
+    
+    String delim = "";
+    shellState.getReader().printString("System permissions: ");
+    for (SystemPermission p : SystemPermission.values()) {
+      if (shellState.getConnector().securityOperations().hasSystemPermission(user, p) & p != null) {
+        shellState.getReader().printString(delim + "System." + p.name());
+        delim = ", ";
+      }
+    }
+    shellState.getReader().printNewline();
+    
+    for (String t : shellState.getConnector().tableOperations().list()) {
+      delim = "";
+      for (TablePermission p : TablePermission.values()) {
+        if (shellState.getConnector().securityOperations().hasTablePermission(user, t, p) && p != null) {
+          if (runOnce == 0) {
+            shellState.getReader().printString("\nTable permissions (" + t + "): ");
+            runOnce++;
+          }
+          shellState.getReader().printString(delim + "Table." + p.name());
+          delim = ", ";
+        }
+        
+      }
+      runOnce = 0;
+    }
+    shellState.getReader().printNewline();
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a user's system and table permissions";
+  }
+  
+  @Override
+  public Options getOptions() {
+    Options o = new Options();
+    userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
+    userOpt.setArgName("user");
+    o.addOption(userOpt);
+    return o;
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
new file mode 100644
index 0000000..6975185
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UsersCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.IOException;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+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 UsersCommand extends Command {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws AccumuloException, AccumuloSecurityException, IOException {
+    for (String user : shellState.getConnector().securityOperations().listUsers())
+      shellState.getReader().printString(user + "\n");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "displays a list of existing users";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
new file mode 100644
index 0000000..ceb778b
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/util/shell/commands/WhoAmICommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.IOException;
+
+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 WhoAmICommand extends Command {
+  @Override
+  public int execute(String fullCommand, CommandLine cl, Shell shellState) throws IOException {
+    shellState.getReader().printString(shellState.getConnector().whoami() + "\n");
+    return 0;
+  }
+  
+  @Override
+  public String description() {
+    return "reports the current user name";
+  }
+  
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/java/org/apache/accumulo/core/zookeeper/ZooUtil.java
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/java/org/apache/accumulo/core/zookeeper/ZooUtil.java b/1.5/core/src/main/java/org/apache/accumulo/core/zookeeper/ZooUtil.java
new file mode 100644
index 0000000..037f214
--- /dev/null
+++ b/1.5/core/src/main/java/org/apache/accumulo/core/zookeeper/ZooUtil.java
@@ -0,0 +1,30 @@
+/*
+ * 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.zookeeper;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.Instance;
+
+public class ZooUtil extends org.apache.accumulo.fate.zookeeper.ZooUtil {
+  public static String getRoot(Instance instance) {
+    return getRoot(instance.getInstanceID());
+  }
+  
+  public static String getRoot(String instanceId) {
+    return Constants.ZROOT + "/" + instanceId;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/resources/org/apache/accumulo/core/conf/config.html
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/resources/org/apache/accumulo/core/conf/config.html b/1.5/core/src/main/resources/org/apache/accumulo/core/conf/config.html
new file mode 100644
index 0000000..21d7438
--- /dev/null
+++ b/1.5/core/src/main/resources/org/apache/accumulo/core/conf/config.html
@@ -0,0 +1,89 @@
+<!--
+  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.
+-->
+<html>
+ <head>
+  <title>Accumulo Configuration</title>
+  <link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+ </head>
+ <body>
+  <h1>Apache Accumulo Configuration Management</h1>
+  <p>All accumulo properties have a default value in the source code.  Properties can also be set
+  in accumulo-site.xml and in zookeeper on per-table or system-wide basis.  If properties are set in more than one location,
+  accumulo will choose the property with the highest precedence.  This order of precedence is described
+  below (from highest to lowest):</p>
+  <table>
+   <tr><th>Location</th><th>Description</th></tr>
+   <tr class='highlight'><td><b>Zookeeper<br/>table properties</td>
+       <td>Table properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  While table properties take precedent over system properties, both will override properties set in accumulo-site.xml<br/><br/>
+           Table properties consist of all properties with the table.* prefix.  Table properties are configured on a per-table basis using the following shell commmand:
+		    <pre>config -t TABLE -s PROPERTY=VALUE</pre></td>
+   </tr>
+   <tr><td><b>Zookeeper<br/>system properties</td>
+	    <td>System properties are applied to the entire cluster when set in zookeeper using the accumulo API or shell.  System properties consist of all properties with a 'yes' in the 'Zookeeper Mutable' column in the table below.  They are set with the following shell command:
+		    <pre>config -s PROPERTY=VALUE</pre>
+			If a table.* property is set using this method, the value will apply to all tables except those configured on per-table basis (which have higher precedence).<br/><br/>
+			While most system properties take effect immediately, some require a restart of the process which is indicated in 'Zookeeper Mutable'.</td>
+   </tr>
+   <tr class='highlight'><td><b>accumulo-site.xml</td>
+       <td>Accumulo processes (master, tserver, etc) read their local accumulo-site.xml on start up.  Therefore, changes made to accumulo-site.xml must rsynced across the cluster and processes must be restarted to apply changes.<br/><br/>
+           Certain properties (indicated by a 'no' in 'Zookeeper Mutable') cannot be set in zookeeper and only set in this file.  The accumulo-site.xml also allows you to configure tablet servers with different settings.</td>
+   </tr>
+   <tr><td><b>Default</td>
+   	   <td>All properties have a default value in the source code.  This value has the lowest precedence and is overriden if set in accumulo-site.xml or zookeeper.<br/><br/>While the default value is usually optimal, there are cases where a change can increase query and ingest performance.</td>
+   </tr>
+  </table>
+  
+  <p>The 'config' command in the shell allows you to view the current system configuration.  You can also use the '-t' option to view a table's configuration as below:
+  
+  <pre>
+    $ ./bin/accumulo shell -u root
+    Enter current password for 'root'@'ac14': ******
+
+    Shell - Apache Accumulo Interactive Shell
+    - 
+    - version: 1.5.0-SNAPSHOT
+    - instance name: ac14
+    - instance id: 4f48fa03-f692-43ce-ae03-94c9ea8b7181
+    - 
+    - type 'help' for a list of available commands
+    - 
+    root@ac13> config -t foo
+    ---------+---------------------------------------------+------------------------------------------------------
+    SCOPE    | NAME                                        | VALUE
+    ---------+---------------------------------------------+------------------------------------------------------
+    default  | table.balancer ............................ | org.apache.accumulo.server.master.balancer.DefaultLoadBalancer
+    default  | table.bloom.enabled ....................... | false
+    default  | table.bloom.error.rate .................... | 0.5%
+    default  | table.bloom.hash.type ..................... | murmur
+    default  | table.bloom.key.functor ................... | org.apache.accumulo.core.file.keyfunctor.RowFunctor
+    default  | table.bloom.load.threshold ................ | 1
+    default  | table.bloom.size .......................... | 1048576
+    default  | table.cache.block.enable .................. | false
+    default  | table.cache.index.enable .................. | false
+    default  | table.compaction.major.everything.at ...... | 19700101000000GMT
+    default  | table.compaction.major.everything.idle .... | 1h
+    default  | table.compaction.major.ratio .............. | 1.3
+    site     |    @override .............................. | 1.4
+    system   |    @override .............................. | 1.5
+    table    |    @override .............................. | 1.6
+    default  | table.compaction.minor.idle ............... | 5m
+    default  | table.compaction.minor.logs.threshold ..... | 3
+    default  | table.failures.ignore ..................... | false
+  </pre>
+  
+  <h1>Configuration Properties</h1>
+  

http://git-wip-us.apache.org/repos/asf/accumulo/blob/7bdbfccb/1.5/core/src/main/thrift/client.thrift
----------------------------------------------------------------------
diff --git a/1.5/core/src/main/thrift/client.thrift b/1.5/core/src/main/thrift/client.thrift
new file mode 100644
index 0000000..70ddac2
--- /dev/null
+++ b/1.5/core/src/main/thrift/client.thrift
@@ -0,0 +1,96 @@
+/*
+* 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.
+*/
+namespace java org.apache.accumulo.core.client.impl.thrift
+
+include "security.thrift"
+include "cloudtrace.thrift"
+
+enum TableOperation {
+    CREATE,
+    DELETE,
+    RENAME,
+    SET_PROPERTY,
+    REMOVE_PROPERTY,
+    OFFLINE,
+    ONLINE,
+    FLUSH,
+    PERMISSION,
+    CLONE,
+    MERGE,
+    DELETE_RANGE,
+    BULK_IMPORT,
+    COMPACT
+    IMPORT
+    EXPORT
+}
+
+enum TableOperationExceptionType {
+    EXISTS,
+    NOTFOUND,
+    OFFLINE,
+    BULK_BAD_INPUT_DIRECTORY,
+    BULK_BAD_ERROR_DIRECTORY,
+    BAD_RANGE,
+    OTHER
+}
+
+enum ConfigurationType {
+    CURRENT,
+    SITE,
+    DEFAULT
+}
+
+exception ThriftTableOperationException {
+    1:string tableId,
+    2:string tableName,
+    3:TableOperation op,
+    4:TableOperationExceptionType type,
+    5:string description
+}
+
+service ClientService {
+
+    // system management methods
+    string getRootTabletLocation()
+    string getInstanceId()
+    string getZooKeepers()
+    
+    list<string> bulkImportFiles(1:cloudtrace.TInfo tinfo, 2:security.AuthInfo credentials, 3:i64 tid, 4:string tableId, 5:list<string> files, 6:string errorDir, 7:bool setTime) throws (1:security.ThriftSecurityException sec, 2:ThriftTableOperationException tope);
+    // ensures that nobody is working on the transaction id above
+    bool isActive(1:cloudtrace.TInfo tinfo, 2:i64 tid),
+
+    void ping(1:security.AuthInfo credentials) throws (1:security.ThriftSecurityException sec)
+
+    // user management methods
+    bool authenticateUser(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:binary password) throws (1:security.ThriftSecurityException sec)
+    set<string> listUsers(2:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials) throws (1:security.ThriftSecurityException sec)
+    void createUser(5:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:binary password, 4:list<binary> authorizations) throws (1:security.ThriftSecurityException sec)
+    void dropUser(3:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user) throws (1:security.ThriftSecurityException sec)
+    void changePassword(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:binary password) throws (1:security.ThriftSecurityException sec)
+    void changeAuthorizations(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:list<binary> authorizations) throws (1:security.ThriftSecurityException sec)
+    list<binary> getUserAuthorizations(3:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user) throws (1:security.ThriftSecurityException sec)
+    bool hasSystemPermission(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:byte sysPerm) throws (1:security.ThriftSecurityException sec)
+    bool hasTablePermission(5:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:string tableName, 4:byte tblPerm) throws (1:security.ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+    void grantSystemPermission(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:byte permission) throws (1:security.ThriftSecurityException sec)
+    void revokeSystemPermission(4:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:byte permission) throws (1:security.ThriftSecurityException sec)
+    void grantTablePermission(5:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:string tableName, 4:byte permission) throws (1:security.ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+    void revokeTablePermission(5:cloudtrace.TInfo tinfo, 1:security.AuthInfo credentials, 2:string user, 3:string tableName, 4:byte permission) throws (1:security.ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+    
+    map<string, string> getConfiguration(1:ConfigurationType type);
+    map<string, string> getTableConfiguration(2:string tableName) throws (1:ThriftTableOperationException tope);
+    bool checkClass(1:cloudtrace.TInfo tinfo, 2:string className, 3:string interfaceMatch);
+}


Mime
View raw message