You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by md...@apache.org on 2014/04/08 02:37:15 UTC
[12/27] Revert "ACCUMULO-1897 Move shell into new package and module"
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
new file mode 100644
index 0000000..bc5f1d1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
@@ -0,0 +1,203 @@
+/*
+ * 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 java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.TimeType;
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.iterators.IteratorUtil;
+import org.apache.accumulo.core.security.VisibilityConstraint;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.util.shell.ShellUtil;
+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;
+import org.apache.hadoop.io.Text;
+
+public class CreateTableCommand extends Command {
+ private Option createTableOptCopySplits;
+ private Option createTableOptCopyConfig;
+ private Option createTableOptSplit;
+ private Option createTableOptTimeLogical;
+ private Option createTableOptTimeMillis;
+ private Option createTableNoDefaultIters;
+ private Option createTableOptEVC;
+ private Option base64Opt;
+ private Option createTableOptFormatter;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+ TableExistsException, TableNotFoundException, IOException, ClassNotFoundException {
+
+ final String testTableName = cl.getArgs()[0];
+
+ if (!testTableName.matches(Tables.VALID_NAME_REGEX)) {
+ shellState.getReader().println("Only letters, numbers and underscores are allowed for use in table names.");
+ throw new IllegalArgumentException();
+ }
+
+ final String tableName = cl.getArgs()[0];
+ if (shellState.getConnector().tableOperations().exists(tableName)) {
+ throw new TableExistsException(null, tableName, null);
+ }
+ final SortedSet<Text> partitions = new TreeSet<Text>();
+ final boolean decode = cl.hasOption(base64Opt.getOpt());
+
+ if (cl.hasOption(createTableOptSplit.getOpt())) {
+ partitions.addAll(ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode));
+ } else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
+ final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
+ if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+ throw new TableNotFoundException(null, oldTable, null);
+ }
+ partitions.addAll(shellState.getConnector().tableOperations().listSplits(oldTable));
+ }
+
+ if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+ final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
+ if (!shellState.getConnector().tableOperations().exists(oldTable)) {
+ throw new TableNotFoundException(null, oldTable, null);
+ }
+ }
+
+ TimeType timeType = TimeType.MILLIS;
+ if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
+ timeType = TimeType.LOGICAL;
+ }
+
+ // create table
+ shellState.getConnector().tableOperations().create(tableName, true, timeType);
+ if (partitions.size() > 0) {
+ shellState.getConnector().tableOperations().addSplits(tableName, partitions);
+ }
+
+ shellState.setTableName(tableName); // switch shell to new table context
+
+ if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
+ for (String key : IteratorUtil.generateInitialTableProperties(true).keySet()) {
+ shellState.getConnector().tableOperations().removeProperty(tableName, key);
+ }
+ }
+
+ // Copy options if flag was set
+ if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
+ if (shellState.getConnector().tableOperations().exists(tableName)) {
+ final Iterable<Entry<String,String>> configuration = shellState.getConnector().tableOperations()
+ .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
+ for (Entry<String,String> entry : configuration) {
+ if (Property.isValidTablePropertyKey(entry.getKey())) {
+ shellState.getConnector().tableOperations().setProperty(tableName, entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+
+ if (cl.hasOption(createTableOptEVC.getOpt())) {
+ try {
+ shellState.getConnector().tableOperations().addConstraint(tableName, VisibilityConstraint.class.getName());
+ } catch (AccumuloException e) {
+ Shell.log.warn(e.getMessage() + " while setting visibility constraint, but table was created");
+ }
+ }
+
+ // Load custom formatter if set
+ if (cl.hasOption(createTableOptFormatter.getOpt())) {
+ final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
+
+ shellState.getConnector().tableOperations().setProperty(tableName, Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "creates a new table, with optional aggregators and optionally pre-split";
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <tableName>";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ createTableOptCopyConfig = new Option("cc", "copy-config", true, "table to copy configuration from");
+ createTableOptCopySplits = new Option("cs", "copy-splits", true, "table to copy current splits from");
+ createTableOptSplit = new Option("sf", "splits-file", true, "file with a newline-separated list of rows to split the table with");
+ createTableOptTimeLogical = new Option("tl", "time-logical", false, "use logical time");
+ createTableOptTimeMillis = new Option("tm", "time-millis", false, "use time in milliseconds");
+ createTableNoDefaultIters = new Option("ndi", "no-default-iterators", false, "prevent creation of the normal default iterator set");
+ createTableOptEVC = new Option("evc", "enable-visibility-constraint", false,
+ "prevent users from writing data they cannot read. When enabling this, consider disabling bulk import and alter table.");
+ createTableOptFormatter = new Option("f", "formatter", true, "default formatter to set");
+
+ createTableOptCopyConfig.setArgName("table");
+ createTableOptCopySplits.setArgName("table");
+ createTableOptSplit.setArgName("filename");
+ createTableOptFormatter.setArgName("className");
+
+ // Splits and CopySplits are put in an optionsgroup to make them
+ // mutually exclusive
+ final OptionGroup splitOrCopySplit = new OptionGroup();
+ splitOrCopySplit.addOption(createTableOptSplit);
+ splitOrCopySplit.addOption(createTableOptCopySplits);
+
+ final OptionGroup timeGroup = new OptionGroup();
+ timeGroup.addOption(createTableOptTimeLogical);
+ timeGroup.addOption(createTableOptTimeMillis);
+
+ base64Opt = new Option("b64", "base64encoded", false, "decode encoded split points");
+ o.addOption(base64Opt);
+
+ o.addOptionGroup(splitOrCopySplit);
+ o.addOptionGroup(timeGroup);
+ o.addOption(createTableOptSplit);
+ o.addOption(createTableOptCopyConfig);
+ o.addOption(createTableNoDefaultIters);
+ o.addOption(createTableOptEVC);
+ o.addOption(createTableOptFormatter);
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+
+ @Override
+ public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+ registerCompletionForNamespaces(root, special);
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
new file mode 100644
index 0000000..aa3d7b9
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateUserCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+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;
+
+public class CreateUserCommand extends Command {
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, TableNotFoundException,
+ AccumuloSecurityException, TableExistsException, IOException {
+ final String user = cl.getArgs()[0];
+
+ final String password = shellState.readMaskedLine("Enter new password for '" + user + "': ", '*');
+ if (password == null) {
+ shellState.getReader().println();
+ return 0;
+ } // user canceled
+ String passwordConfirm = shellState.readMaskedLine("Please confirm new password for '" + user + "': ", '*');
+ if (passwordConfirm == null) {
+ shellState.getReader().println();
+ return 0;
+ } // user canceled
+
+ if (!password.equals(passwordConfirm)) {
+ throw new IllegalArgumentException("Passwords do not match");
+ }
+ shellState.getConnector().securityOperations().createLocalUser(user, new PasswordToken(password));
+ Shell.log.debug("Created user " + user);
+ return 0;
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <username>";
+ }
+
+ @Override
+ public String description() {
+ return "creates a new user";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
new file mode 100644
index 0000000..660ec6c
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DUCommand.java
@@ -0,0 +1,124 @@
+/*
+ * 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.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.admin.DiskUsage;
+import org.apache.accumulo.core.client.impl.Namespaces;
+import org.apache.accumulo.core.util.NumUtil;
+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 DUCommand extends Command {
+
+ private Option optTablePattern, optHumanReadble, optNamespace;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException, TableNotFoundException,
+ NamespaceNotFoundException {
+
+ final SortedSet<String> tables = new TreeSet<String>(Arrays.asList(cl.getArgs()));
+
+ if (cl.hasOption(Shell.tableOption)) {
+ String tableName = cl.getOptionValue(Shell.tableOption);
+ if (!shellState.getConnector().tableOperations().exists(tableName)) {
+ throw new TableNotFoundException(tableName, tableName, "specified table that doesn't exist");
+ }
+ tables.add(tableName);
+ }
+
+ if (cl.hasOption(optNamespace.getOpt())) {
+ Instance instance = shellState.getInstance();
+ String namespaceId = Namespaces.getNamespaceId(instance, cl.getOptionValue(optNamespace.getOpt()));
+ tables.addAll(Namespaces.getTableNames(instance, namespaceId));
+ }
+
+ boolean prettyPrint = cl.hasOption(optHumanReadble.getOpt()) ? true : false;
+
+ // Add any patterns
+ if (cl.hasOption(optTablePattern.getOpt())) {
+ for (String table : shellState.getConnector().tableOperations().list()) {
+ if (table.matches(cl.getOptionValue(optTablePattern.getOpt()))) {
+ tables.add(table);
+ }
+ }
+ }
+
+ // If we didn't get any tables, and we have a table selected, add the current table
+ if (tables.isEmpty() && !shellState.getTableName().isEmpty()) {
+ tables.add(shellState.getTableName());
+ }
+
+ try {
+ String valueFormat = prettyPrint ? "%9s" : "%,24d";
+ for (DiskUsage usage : shellState.getConnector().tableOperations().getDiskUsage(tables)) {
+ Object value = prettyPrint ? NumUtil.bigNumberForSize(usage.getUsage()) : usage.getUsage();
+ shellState.getReader().println(String.format(valueFormat + " %s", value, usage.getTables()));
+ }
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "prints how much space, in bytes, is used by files referenced by a table. When multiple tables are specified it prints how much space, in bytes, is used by files shared between tables, if any.";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ optTablePattern = new Option("p", "pattern", true, "regex pattern of table names");
+ optTablePattern.setArgName("pattern");
+
+ optHumanReadble = new Option("h", "human-readable", false, "format large sizes to human readable units");
+ optHumanReadble.setArgName("human readable output");
+
+ optNamespace = new Option(Shell.namespaceOption, "namespace", true, "name of a namespace");
+ optNamespace.setArgName("namespace");
+
+ o.addOption(OptUtil.tableOpt("table to examine"));
+
+ o.addOption(optTablePattern);
+ o.addOption(optHumanReadble);
+ o.addOption(optNamespace);
+
+ return o;
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <table>{ <table>}";
+ }
+
+ @Override
+ public int numArgs() {
+ return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
new file mode 100644
index 0000000..206b5901
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DebugCommand.java
@@ -0,0 +1,71 @@
+/*
+ * 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.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+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;
+
+public class DebugCommand extends Command {
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws IOException {
+ if (cl.getArgs().length == 1) {
+ if (cl.getArgs()[0].equalsIgnoreCase("on")) {
+ Shell.setDebugging(true);
+ } else if (cl.getArgs()[0].equalsIgnoreCase("off")) {
+ Shell.setDebugging(false);
+ } else {
+ throw new BadArgumentException("Argument must be 'on' or 'off'", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+ }
+ } else if (cl.getArgs().length == 0) {
+ shellState.getReader().println(Shell.isDebuggingEnabled() ? "on" : "off");
+ } 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 debug logging on or off";
+ }
+
+ @Override
+ public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+ final Token debug_command = new Token(getName());
+ debug_command.addSubcommand(Arrays.asList(new String[] {"on", "off"}));
+ root.addSubcommand(debug_command);
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " [ on | off ]";
+ }
+
+ @Override
+ public int numArgs() {
+ return Shell.NO_FIXED_ARG_LENGTH_CHECK;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
new file mode 100644
index 0000000..b409ccc
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteCommand.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.shell.commands;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.security.ColumnVisibility;
+import org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
+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;
+import org.apache.hadoop.io.Text;
+
+public class DeleteCommand extends Command {
+ private Option deleteOptAuths, timestampOpt;
+ private Option timeoutOption;
+
+ protected long getTimeout(final CommandLine cl) {
+ if (cl.hasOption(timeoutOption.getLongOpt())) {
+ return AccumuloConfiguration.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
+ }
+
+ return Long.MAX_VALUE;
+ }
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException,
+ TableNotFoundException, IOException, ConstraintViolationException {
+ shellState.checkTableState();
+
+ final Mutation m = new Mutation(new Text(cl.getArgs()[0].getBytes(Shell.CHARSET)));
+ final Text colf = new Text(cl.getArgs()[1].getBytes(Shell.CHARSET));
+ final Text colq = new Text(cl.getArgs()[2].getBytes(Shell.CHARSET));
+
+ if (cl.hasOption(deleteOptAuths.getOpt())) {
+ final ColumnVisibility le = new ColumnVisibility(cl.getOptionValue(deleteOptAuths.getOpt()));
+ if (cl.hasOption(timestampOpt.getOpt())) {
+ m.putDelete(colf, colq, le, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+ } else {
+ m.putDelete(colf, colq, le);
+ }
+ } else if (cl.hasOption(timestampOpt.getOpt())) {
+ m.putDelete(colf, colq, Long.parseLong(cl.getOptionValue(timestampOpt.getOpt())));
+ } else {
+ m.putDelete(colf, colq);
+ }
+ final BatchWriter bw = shellState.getConnector().createBatchWriter(shellState.getTableName(),
+ new BatchWriterConfig().setMaxMemory(Math.max(m.estimatedMemoryUsed(), 1024)).setMaxWriteThreads(1).setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+ bw.addMutation(m);
+ bw.close();
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a record from a table";
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <row> <colfamily> <colqualifier>";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ deleteOptAuths = new Option("l", "visibility-label", true, "formatted visibility");
+ deleteOptAuths.setArgName("expression");
+ o.addOption(deleteOptAuths);
+
+ timestampOpt = new Option("ts", "timestamp", true, "timestamp to use for deletion");
+ timestampOpt.setArgName("timestamp");
+ o.addOption(timestampOpt);
+
+ timeoutOption = new Option(null, "timeout", true,
+ "time before insert should fail if no data is written. If no unit is given assumes seconds. Units d,h,m,s,and ms are supported. e.g. 30s or 100ms");
+ timeoutOption.setArgName("timeout");
+ o.addOption(timeoutOption);
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 3;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
new file mode 100644
index 0000000..c100325
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteIterCommand.java
@@ -0,0 +1,114 @@
+/*
+ * 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.EnumSet;
+
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+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 DeleteIterCommand extends Command {
+ private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, nameOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+ boolean tables = cl.hasOption(OptUtil.tableOpt().getOpt()) || !shellState.getTableName().isEmpty();
+ boolean namespaces = cl.hasOption(OptUtil.namespaceOpt().getOpt());
+
+ final String name = cl.getOptionValue(nameOpt.getOpt());
+
+ if (namespaces) {
+ if (!shellState.getConnector().namespaceOperations().listIterators(OptUtil.getNamespaceOpt(cl, shellState)).containsKey(name)) {
+ Shell.log.warn("no iterators found that match your criteria");
+ return 0;
+ }
+ } else if (tables) {
+ if (!shellState.getConnector().tableOperations().listIterators(OptUtil.getTableOpt(cl, shellState)).containsKey(name)) {
+ Shell.log.warn("no iterators found that match your criteria");
+ return 0;
+ }
+ } else {
+ throw new IllegalArgumentException("No table or namespace specified");
+ }
+
+ final EnumSet<IteratorScope> scopes = EnumSet.noneOf(IteratorScope.class);
+ if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(mincScopeOpt.getOpt())) {
+ scopes.add(IteratorScope.minc);
+ }
+ if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(majcScopeOpt.getOpt())) {
+ scopes.add(IteratorScope.majc);
+ }
+ if (cl.hasOption(allScopeOpt.getOpt()) || cl.hasOption(scanScopeOpt.getOpt())) {
+ scopes.add(IteratorScope.scan);
+ }
+ if (scopes.isEmpty()) {
+ throw new IllegalArgumentException("You must select at least one scope to configure");
+ }
+
+ if (namespaces) {
+ shellState.getConnector().namespaceOperations().removeIterator(OptUtil.getNamespaceOpt(cl, shellState), name, scopes);
+ } else if (tables) {
+ shellState.getConnector().tableOperations().removeIterator(OptUtil.getTableOpt(cl, shellState), name, scopes);
+ } else {
+ throw new IllegalArgumentException("No table or namespace specified");
+ }
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a table-specific or namespace-specific iterator";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ nameOpt = new Option("n", "name", true, "iterator to delete");
+ nameOpt.setArgName("itername");
+ nameOpt.setRequired(true);
+
+ allScopeOpt = new Option("all", "all-scopes", false, "remove from all scopes");
+ mincScopeOpt = new Option(IteratorScope.minc.name(), "minor-compaction", false, "remove from minor compaction scope");
+ majcScopeOpt = new Option(IteratorScope.majc.name(), "major-compaction", false, "remove from major compaction scope");
+ scanScopeOpt = new Option(IteratorScope.scan.name(), "scan-time", false, "remove from scan scope");
+
+ OptionGroup grp = new OptionGroup();
+ grp.addOption(OptUtil.tableOpt("table to delete the iterator from"));
+ grp.addOption(OptUtil.namespaceOpt("namespace to delete the iterator from"));
+ o.addOptionGroup(grp);
+ o.addOption(nameOpt);
+
+ o.addOption(allScopeOpt);
+ o.addOption(mincScopeOpt);
+ o.addOption(majcScopeOpt);
+ o.addOption(scanScopeOpt);
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
new file mode 100644
index 0000000..7518bf9
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
@@ -0,0 +1,82 @@
+/*
+ * 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.concurrent.TimeUnit;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.BatchWriterConfig;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.iterators.SortedKeyIterator;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.DeleterFormatter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteManyCommand extends ScanCommand {
+ private Option forceOpt;
+
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+ final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
+ // handle first argument, if present, the authorizations list to
+ // scan with
+ final Authorizations auths = getAuths(cl, shellState);
+ final Scanner scanner = shellState.getConnector().createScanner(tableName, auths);
+
+ scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE", SortedKeyIterator.class));
+
+ // handle session-specific scan iterators
+ addScanIterators(shellState, cl, scanner, tableName);
+
+ // handle remaining optional arguments
+ scanner.setRange(getRange(cl, interpeter));
+
+ scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);
+
+ // handle columns
+ fetchColumns(cl, scanner, interpeter);
+
+ // output / delete the records
+ final BatchWriter writer = shellState.getConnector()
+ .createBatchWriter(tableName, new BatchWriterConfig().setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS));
+ shellState.printLines(new DeleterFormatter(writer, scanner, cl.hasOption(timestampOpt.getOpt()), shellState, cl.hasOption(forceOpt.getOpt())), false);
+
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "scans a table and deletes the resulting records";
+ }
+
+ @Override
+ public Options getOptions() {
+ forceOpt = new Option("f", "force", false, "force deletion without prompting");
+ final Options opts = super.getOptions();
+ opts.addOption(forceOpt);
+ opts.addOption(OptUtil.tableOpt("table to delete entries from"));
+ return opts;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
new file mode 100644
index 0000000..01d7fc0
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteNamespaceCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.accumulo.core.client.NamespaceNotFoundException;
+import org.apache.accumulo.core.client.impl.Namespaces;
+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.Options;
+
+public class DeleteNamespaceCommand extends Command {
+ private Option forceOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ boolean force = false;
+ boolean operate = true;
+ if (cl.hasOption(forceOpt.getOpt())) {
+ force = true;
+ }
+ String namespace = cl.getArgs()[0];
+
+ if (!force) {
+ shellState.getReader().flush();
+ String line = shellState.getReader().readLine(getName() + " { " + namespace + " } (yes|no)? ");
+ operate = line != null && (line.equalsIgnoreCase("y") || line.equalsIgnoreCase("yes"));
+ }
+ if (operate) {
+ doTableOp(shellState, namespace, force);
+ }
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a namespace";
+ }
+
+ protected void doTableOp(final Shell shellState, final String namespace, boolean force) throws Exception {
+ boolean resetContext = false;
+ String currentTable = shellState.getTableName();
+ if (!Namespaces.getNameToIdMap(shellState.getInstance()).containsKey(namespace)) {
+ throw new NamespaceNotFoundException(null, namespace, null);
+ }
+
+ String namespaceId = Namespaces.getNamespaceId(shellState.getInstance(), namespace);
+ List<String> tables = Namespaces.getTableNames(shellState.getInstance(), namespaceId);
+ resetContext = tables.contains(currentTable);
+
+ if (force)
+ for (String table : shellState.getConnector().tableOperations().list())
+ if (table.startsWith(namespace + "."))
+ shellState.getConnector().tableOperations().delete(table);
+
+ shellState.getConnector().namespaceOperations().delete(namespace);
+ if (resetContext) {
+ shellState.setTableName("");
+ }
+ }
+
+ @Override
+ public Options getOptions() {
+ forceOpt = new Option("f", "force", false, "force deletion without prompting");
+ final Options opts = super.getOptions();
+
+ opts.addOption(forceOpt);
+ return opts;
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+
+ @Override
+ public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> special) {
+ registerCompletionForNamespaces(root, special);
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
new file mode 100644
index 0000000..1414b4d
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteRowsCommand.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class DeleteRowsCommand extends Command {
+ private Option forceOpt;
+ private Option startRowOptExclusive;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ final String tableName = OptUtil.getTableOpt(cl, shellState);
+ final Text startRow = OptUtil.getStartRow(cl);
+ final Text endRow = OptUtil.getEndRow(cl);
+ if (!cl.hasOption(forceOpt.getOpt()) && (startRow == null || endRow == null)) {
+ shellState.getReader().println("Not deleting unbounded range. Specify both ends, or use --force");
+ return 1;
+ }
+ shellState.getConnector().tableOperations().deleteRows(tableName, startRow, endRow);
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a range of rows in a table. Note that rows matching the start row ARE NOT deleted, but rows matching the end row ARE deleted.";
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+ forceOpt = new Option("f", "force", false, "delete data even if start or end are not specified");
+ startRowOptExclusive = new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (exclusive)");
+ startRowOptExclusive.setArgName("begin-row");
+ o.addOption(startRowOptExclusive);
+ o.addOption(OptUtil.endRowOpt());
+ o.addOption(OptUtil.tableOpt("table to delete a row range from"));
+ o.addOption(forceOpt);
+ return o;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
new file mode 100644
index 0000000..9b8699b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteScanIterCommand.java
@@ -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.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+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 DeleteScanIterCommand extends Command {
+ private Option nameOpt, allOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+ if (cl.hasOption(allOpt.getOpt())) {
+ final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.remove(tableName);
+ if (tableScanIterators == null) {
+ Shell.log.info("No scan iterators set on table " + tableName);
+ } else {
+ Shell.log.info("Removed the following scan iterators from table " + tableName + ":" + tableScanIterators);
+ }
+ } else if (cl.hasOption(nameOpt.getOpt())) {
+ final String name = cl.getOptionValue(nameOpt.getOpt());
+ final List<IteratorSetting> tableScanIterators = shellState.scanIteratorOptions.get(tableName);
+ if (tableScanIterators != null) {
+ boolean found = false;
+ for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); iter.hasNext();) {
+ if (iter.next().getName().equals(name)) {
+ iter.remove();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ Shell.log.info("No iterator named " + name + " found for table " + tableName);
+ } else {
+ Shell.log.info("Removed scan iterator " + name + " from table " + tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " left)");
+ if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
+ shellState.scanIteratorOptions.remove(tableName);
+ }
+ }
+ } else {
+ Shell.log.info("No iterator named " + name + " found for table " + tableName);
+ }
+ }
+
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a table-specific scan iterator so it is no longer used during this shell session";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ OptionGroup nameGroup = new OptionGroup();
+
+ nameOpt = new Option("n", "name", true, "iterator to delete");
+ nameOpt.setArgName("itername");
+
+ allOpt = new Option("a", "all", false, "delete all scan iterators");
+ allOpt.setArgName("all");
+
+ nameGroup.addOption(nameOpt);
+ nameGroup.addOption(allOpt);
+ nameGroup.setRequired(true);
+ o.addOptionGroup(nameGroup);
+ o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
new file mode 100644
index 0000000..89060c1
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteShellIterCommand.java
@@ -0,0 +1,100 @@
+/*
+ * 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.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+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 DeleteShellIterCommand extends Command {
+ private Option nameOpt, allOpt, profileOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+
+ String profile = cl.getOptionValue(profileOpt.getOpt());
+ if (shellState.iteratorProfiles.containsKey(profile)) {
+ if (cl.hasOption(allOpt.getOpt())) {
+ shellState.iteratorProfiles.remove(profile);
+ Shell.log.info("Removed profile " + profile);
+ } else {
+ List<IteratorSetting> iterSettings = shellState.iteratorProfiles.get(profile);
+ String name = cl.getOptionValue(nameOpt.getOpt());
+ boolean found = false;
+ for (Iterator<IteratorSetting> iter = iterSettings.iterator(); iter.hasNext();) {
+ if (iter.next().getName().equals(name)) {
+ iter.remove();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ Shell.log.info("No iterator named " + name + " found");
+ } else {
+ Shell.log.info("Removed iterator " + name + " from profile " + profile + " (" + iterSettings.size() + " left)");
+ }
+ }
+
+ } else {
+ Shell.log.info("No profile named " + profile);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes iterators profiles configured in this shell session";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ OptionGroup nameGroup = new OptionGroup();
+
+ nameOpt = new Option("n", "name", true, "iterator to delete");
+ nameOpt.setArgName("itername");
+
+ allOpt = new Option("a", "all", false, "delete all scan iterators");
+ allOpt.setArgName("all");
+
+ nameGroup.addOption(nameOpt);
+ nameGroup.addOption(allOpt);
+ nameGroup.setRequired(true);
+ o.addOptionGroup(nameGroup);
+
+ profileOpt = new Option("pn", "profile", true, "iterator profile name");
+ profileOpt.setRequired(true);
+ profileOpt.setArgName("profile");
+ o.addOption(profileOpt);
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.java
new file mode 100644
index 0000000..a5aa32a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteTableCommand.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 org.apache.accumulo.core.util.shell.Shell;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class DeleteTableCommand extends TableOperation {
+ private Option forceOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ if (cl.hasOption(forceOpt.getOpt())) {
+ super.force();
+ } else {
+ super.noForce();
+ }
+ return super.execute(fullCommand, cl, shellState);
+ }
+
+ @Override
+ public String description() {
+ return "deletes a table";
+ }
+
+ @Override
+ protected void doTableOp(final Shell shellState, final String tableName) throws Exception {
+ shellState.getConnector().tableOperations().delete(tableName);
+ shellState.getReader().println("Table: [" + tableName + "] has been deleted.");
+
+ if (shellState.getTableName().equals(tableName)) {
+ shellState.setTableName("");
+ }
+ }
+
+ @Override
+ public Options getOptions() {
+ forceOpt = new Option("f", "force", false, "force deletion without prompting");
+ final Options opts = super.getOptions();
+
+ opts.addOption(forceOpt);
+ return opts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
new file mode 100644
index 0000000..4bc563e
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteUserCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+public class DeleteUserCommand extends DropUserCommand {}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
new file mode 100644
index 0000000..3120d6b
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropTableCommand.java
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+public class DropTableCommand extends DeleteTableCommand {}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
new file mode 100644
index 0000000..5aa0fb6
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DropUserCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.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;
+
+public class DropUserCommand extends Command {
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException {
+ final String user = cl.getArgs()[0];
+ if (shellState.getConnector().whoami().equals(user)) {
+ throw new BadArgumentException("You cannot delete yourself", fullCommand, fullCommand.indexOf(user));
+ }
+ shellState.getConnector().securityOperations().dropLocalUser(user);
+ Shell.log.debug("Deleted user " + user);
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "deletes a user";
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <username>";
+ }
+
+ @Override
+ public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+ registerCompletionForUsers(root, completionSet);
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
new file mode 100644
index 0000000..d63991a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/EGrepCommand.java
@@ -0,0 +1,59 @@
+/*
+ * 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.BatchScanner;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.iterators.user.RegExFilter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public class EGrepCommand extends GrepCommand {
+
+ private Option matchSubstringOption;
+
+ @Override
+ protected void setUpIterator(final int prio, final String name, final String term, final BatchScanner scanner, CommandLine cl) throws IOException {
+ if (prio < 0) {
+ throw new IllegalArgumentException("Priority < 0 " + prio);
+ }
+ final IteratorSetting si = new IteratorSetting(prio, name, RegExFilter.class);
+ RegExFilter.setRegexs(si, term, term, term, term, true, cl.hasOption(matchSubstringOption.getOpt()));
+ scanner.addScanIterator(si);
+ }
+
+ @Override
+ public String description() {
+ return "searches each row, column family, column qualifier and value, in parallel, on the server side (using a java Matcher, so put .* before and after your term if you're not matching the whole element)";
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <regex>{ <regex>}";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options opts = super.getOptions();
+ matchSubstringOption = new Option("g", "global", false, "forces the use of the find() expression matcher, causing substring matches to return true");
+ opts.addOption(matchSubstringOption);
+ return opts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
new file mode 100644
index 0000000..f4a2632
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExecfileCommand.java
@@ -0,0 +1,67 @@
+/*
+ * 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.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+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 ExecfileCommand extends Command {
+ private Option verboseOption;
+
+ @Override
+ public String description() {
+ return "specifies a file containing accumulo commands to execute";
+ }
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ Scanner scanner = new Scanner(new File(cl.getArgs()[0]), StandardCharsets.UTF_8.name());
+ try {
+ while (scanner.hasNextLine()) {
+ shellState.execCommand(scanner.nextLine(), true, cl.hasOption(verboseOption.getOpt()));
+ }
+ } finally {
+ scanner.close();
+ }
+ return 0;
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <fileName>";
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options opts = new Options();
+ verboseOption = new Option("v", "verbose", false, "display command prompt as commands are executed");
+ opts.addOption(verboseOption);
+ return opts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
new file mode 100644
index 0000000..c78b020
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExitCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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 ExitCommand extends Command {
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) {
+ shellState.setExit(true);
+ return 0;
+ }
+
+ @Override
+ public String description() {
+ return "exits the shell";
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
new file mode 100644
index 0000000..5fd5abb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExportTableCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.TableExistsException;
+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.Options;
+
+public class ExportTableCommand extends Command {
+
+ private Option tableOpt;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
+ TableExistsException {
+
+ final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+ shellState.getConnector().tableOperations().exportTable(tableName, cl.getArgs()[0]);
+ return 0;
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " <export dir>";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+
+ tableOpt = new Option(Shell.tableOption, "table", true, "table to export");
+
+ tableOpt.setArgName("table");
+
+ o.addOption(tableOpt);
+
+ return o;
+ }
+
+ @Override
+ public String description() {
+ return "exports a table";
+ }
+
+ public void registerCompletion(final Token root, final Map<Command.CompletionSet,Set<String>> completionSet) {
+ registerCompletionForTables(root, completionSet);
+ }
+
+ @Override
+ public int numArgs() {
+ return 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
new file mode 100644
index 0000000..ab29d19
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ExtensionCommand.java
@@ -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;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
new file mode 100644
index 0000000..0196baf
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FateCommand.java
@@ -0,0 +1,180 @@
+/*
+ * 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.Collections;
+import java.util.EnumSet;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.AdminUtil;
+import org.apache.accumulo.fate.ReadOnlyTStore.TStatus;
+import org.apache.accumulo.fate.ZooStore;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Manage FATE transactions
+ *
+ */
+public class FateCommand extends Command {
+
+ private static final String SCHEME = "digest";
+
+ private static final String USER = "accumulo";
+
+ private Option secretOption;
+ private Option statusOption;
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws ParseException, KeeperException, InterruptedException,
+ IOException {
+ Instance instance = shellState.getInstance();
+ String[] args = cl.getArgs();
+ if (args.length <= 0) {
+ throw new ParseException("Must provide a command to execute");
+ }
+ String cmd = args[0];
+ boolean failedCommand = false;
+
+ AdminUtil<FateCommand> admin = new AdminUtil<FateCommand>(false);
+
+ String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
+ String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
+ IZooReaderWriter zk = getZooReaderWriter(shellState.getInstance(), cl.getOptionValue(secretOption.getOpt()));
+ ZooStore<FateCommand> zs = new ZooStore<FateCommand>(path, zk);
+
+ if ("fail".equals(cmd)) {
+ if (args.length <= 1) {
+ throw new ParseException("Must provide transaction ID");
+ }
+ for (int i = 1; i < args.length; i++) {
+ if (!admin.prepFail(zs, zk, masterPath, args[i])) {
+ System.out.printf("Could not fail transaction: %s%n", args[i]);
+ failedCommand = true;
+ }
+ }
+ } else if ("delete".equals(cmd)) {
+ if (args.length <= 1) {
+ throw new ParseException("Must provide transaction ID");
+ }
+ for (int i = 1; i < args.length; i++) {
+ if (admin.prepDelete(zs, zk, masterPath, args[i])) {
+ admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, args[i]);
+ } else {
+ System.out.printf("Could not delete transaction: %s%n", args[i]);
+ failedCommand = true;
+ }
+ }
+ } else if ("list".equals(cmd) || "print".equals(cmd)) {
+ // Parse transaction ID filters for print display
+ Set<Long> filterTxid = null;
+ if (args.length >= 2) {
+ filterTxid = new HashSet<Long>(args.length);
+ for (int i = 1; i < args.length; i++) {
+ try {
+ Long val = Long.parseLong(args[i], 16);
+ filterTxid.add(val);
+ } catch (NumberFormatException nfe) {
+ // Failed to parse, will exit instead of displaying everything since the intention was to potentially filter some data
+ System.out.printf("Invalid transaction ID format: %s%n", args[i]);
+ return 1;
+ }
+ }
+ }
+
+ // Parse TStatus filters for print display
+ EnumSet<TStatus> filterStatus = null;
+ if (cl.hasOption(statusOption.getOpt())) {
+ filterStatus = EnumSet.noneOf(TStatus.class);
+ String[] tstat = cl.getOptionValues(statusOption.getOpt());
+ for (int i = 0; i < tstat.length; i++) {
+ try {
+ filterStatus.add(TStatus.valueOf(tstat[i]));
+ } catch (IllegalArgumentException iae) {
+ System.out.printf("Invalid transaction status name: %s%n", tstat[i]);
+ return 1;
+ }
+ }
+ }
+
+ StringBuilder buf = new StringBuilder(8096);
+ Formatter fmt = new Formatter(buf);
+ admin.print(zs, zk, ZooUtil.getRoot(instance) + Constants.ZTABLE_LOCKS, fmt, filterTxid, filterStatus);
+ shellState.printLines(Collections.singletonList(buf.toString()).iterator(), true);
+ } else {
+ throw new ParseException("Invalid command option");
+ }
+
+ return failedCommand ? 1 : 0;
+ }
+
+ protected synchronized IZooReaderWriter getZooReaderWriter(Instance instance, String secret) {
+
+ if (secret == null) {
+ @SuppressWarnings("deprecation")
+ AccumuloConfiguration conf = AccumuloConfiguration.getSiteConfiguration();
+ secret = conf.get(Property.INSTANCE_SECRET);
+ }
+
+ return new ZooReaderWriter(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut(), SCHEME, (USER + ":" + secret).getBytes());
+ }
+
+ @Override
+ public String description() {
+ return "manage FATE transactions";
+ }
+
+ @Override
+ public String usage() {
+ return getName() + " fail <txid>... | delete <txid>... | print [<txid>...]";
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options o = new Options();
+ secretOption = new Option("s", "secret", true, "specify the instance secret to use");
+ secretOption.setOptionalArg(false);
+ o.addOption(secretOption);
+ statusOption = new Option("t", "status-type", true,
+ "filter 'print' on the transaction status type(s) {NEW, IN_PROGRESS, FAILED_IN_PROGRESS, FAILED, SUCCESSFUL}");
+ statusOption.setArgs(Option.UNLIMITED_VALUES);
+ statusOption.setOptionalArg(false);
+ o.addOption(statusOption);
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ // Arg length varies between 1 to n
+ return -1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/b2b985e2/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.java
new file mode 100644
index 0000000..de175eb
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FlushCommand.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 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.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
+
+public class FlushCommand extends TableOperation {
+ private Text startRow;
+ private Text endRow;
+
+ private boolean wait;
+ private Option waitOpt;
+
+ @Override
+ public String description() {
+ return "flushes a tables data that is currently in memory to disk";
+ }
+
+ protected void doTableOp(final Shell shellState, final String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
+ shellState.getConnector().tableOperations().flush(tableName, startRow, endRow, wait);
+ Shell.log.info("Flush of table " + tableName + (wait ? " completed." : " initiated..."));
+ }
+
+ @Override
+ public int execute(final String fullCommand, final CommandLine cl, final Shell shellState) throws Exception {
+ wait = cl.hasOption(waitOpt.getLongOpt());
+ startRow = OptUtil.getStartRow(cl);
+ endRow = OptUtil.getEndRow(cl);
+ return super.execute(fullCommand, cl, shellState);
+ }
+
+ @Override
+ public Options getOptions() {
+ final Options opts = super.getOptions();
+ waitOpt = new Option("w", "wait", false, "wait for flush to finish");
+ opts.addOption(waitOpt);
+ opts.addOption(OptUtil.startRowOpt());
+ opts.addOption(OptUtil.endRowOpt());
+
+ return opts;
+ }
+}