Return-Path: X-Original-To: apmail-accumulo-commits-archive@www.apache.org Delivered-To: apmail-accumulo-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8A93A10AB1 for ; Tue, 8 Apr 2014 03:04:12 +0000 (UTC) Received: (qmail 38514 invoked by uid 500); 8 Apr 2014 03:03:40 -0000 Delivered-To: apmail-accumulo-commits-archive@accumulo.apache.org Received: (qmail 37843 invoked by uid 500); 8 Apr 2014 03:03:18 -0000 Mailing-List: contact commits-help@accumulo.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@accumulo.apache.org Delivered-To: mailing list commits@accumulo.apache.org Received: (qmail 37343 invoked by uid 99); 8 Apr 2014 03:03:05 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 08 Apr 2014 03:03:05 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 7EC5394D7B4; Tue, 8 Apr 2014 03:03:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: elserj@apache.org To: commits@accumulo.apache.org Date: Tue, 08 Apr 2014 03:03:27 -0000 Message-Id: <919fb6faf49c47008bc16e66c8653c82@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [31/53] [abbrv] 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 partitions = new TreeSet(); + 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> configuration = shellState.getConnector().tableOperations() + .getProperties(cl.getOptionValue(createTableOptCopyConfig.getOpt())); + for (Entry 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() + " "; + } + + @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> 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() + " "; + } + + @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 tables = new TreeSet(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() + " {
}"; + } + + @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> 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() + " "; + } + + @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 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 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> 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 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 tableScanIterators = shellState.scanIteratorOptions.get(tableName); + if (tableScanIterators != null) { + boolean found = false; + for (Iterator 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 iterSettings = shellState.iteratorProfiles.get(profile); + String name = cl.getOptionValue(nameOpt.getOpt()); + boolean found = false; + for (Iterator 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() + " "; + } + + @Override + public void registerCompletion(final Token root, final Map> 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() + " { }"; + } + + @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() + " "; + } + + @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() + " "; + } + + @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> 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 extensions = null; + + private Set loadedHeaders = new HashSet(); + private Set loadedCommands = new HashSet(); + private Set loadedExtensions = new TreeSet(); + + 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 admin = new AdminUtil(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 zs = new ZooStore(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 filterTxid = null; + if (args.length >= 2) { + filterTxid = new HashSet(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 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 ... | delete ... | print [...]"; + } + + @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; + } +}