Author: kturner
Date: Wed Aug 22 19:55:43 2012
New Revision: 1376213
URL: http://svn.apache.org/viewvc?rev=1376213&view=rev
Log:
ACCUMULO-735 added hooks for translating shell's scan range and column arguments
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/conf/Property.java
Wed Aug 22 19:55:43 2012
@@ -21,6 +21,8 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.accumulo.core.file.rfile.RFile;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
import org.apache.accumulo.start.classloader.AccumuloClassLoader;
public enum Property {
@@ -281,8 +283,10 @@ public enum Property {
+ "For example table.group.group1=x,y,z sets the column families for
a group called group1. Once configured, "
+ "group1 can be enabled by adding it to the list of groups in the "
+ TABLE_LOCALITY_GROUPS.getKey() + " property.<br />"
+ "Additional group options may be specified for a named group by
setting table.group.<name>.opt.<key>=<value>."),
- TABLE_FORMATTER_CLASS("table.formatter",
"org.apache.accumulo.core.util.format.DefaultFormatter", PropertyType.STRING,
- "The Formatter class to apply on results in the shell");
+ TABLE_FORMATTER_CLASS("table.formatter", DefaultFormatter.class.getName(),
PropertyType.STRING,
+ "The Formatter class to apply on results in the shell"),
+ TABLE_INTERPRETER_CLASS("table.interepreter",
DefaultScanInterpreter.class.getName(), PropertyType.STRING,
+ "The ScanInterpreter class to apply on scan arguments in the shell");
private String key, defaultValue, description;
private PropertyType type;
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/format/HexFormatter.java
Wed Aug 22 19:55:43 2012
@@ -21,11 +21,13 @@ import java.util.Map.Entry;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.hadoop.io.Text;
/**
* A simple formatter that print the row, column family, column qualifier, and
value as hex
*/
-public class HexFormatter implements Formatter {
+public class HexFormatter implements Formatter, ScanInterpreter {
private char chars[] = new char[] {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private Iterator<Entry<Key,Value>> iter;
@@ -40,6 +42,33 @@ public class HexFormatter implements For
sb.append(chars[0x0f & bin[i]]);
}
}
+
+ private int fromChar(char b) {
+ if (b >= '0' && b <= '9') {
+ return (b - '0');
+ } else if (b >= 'a' && b <= 'f') {
+ return (b - 'a' + 10);
+ }
+
+ throw new IllegalArgumentException("Bad char " + b);
+ }
+
+ private byte[] toBinary(String hex) {
+ hex = hex.replace("-", "");
+
+ byte[] bin = new byte[(hex.length() / 2) + (hex.length() % 2)];
+
+ int j = 0;
+ for (int i = 0; i < bin.length; i++) {
+ bin[i] = (byte) (fromChar(hex.charAt(j++)) << 4);
+ if (j >= hex.length())
+ break;
+ bin[i] |= (byte) fromChar(hex.charAt(j++));
+ }
+
+ return bin;
+ }
+
@Override
public boolean hasNext() {
@@ -80,4 +109,28 @@ public class HexFormatter implements For
this.printTimestamps = printTimestamps;
}
+ @Override
+ public Text interpretRow(Text row) {
+ return new Text(toBinary(row.toString()));
+ }
+
+ @Override
+ public Text interpretBeginRow(Text row) {
+ return new Text(toBinary(row.toString()));
+ }
+
+ @Override
+ public Text interpretEndRow(Text row) {
+ return new Text(toBinary(row.toString()));
+ }
+
+ @Override
+ public Text interpretColumnFamily(Text cf) {
+ return new Text(toBinary(cf.toString()));
+ }
+
+ @Override
+ public Text interpretColumnQualifier(Text cq) {
+ return new Text(toBinary(cq.toString()));
+ }
}
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java?rev=1376213&view=auto
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
(added)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/DefaultScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,51 @@
+/**
+ * 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.interpret;
+
+import org.apache.hadoop.io.Text;
+
+/**
+ *
+ */
+public class DefaultScanInterpreter implements ScanInterpreter {
+
+ @Override
+ public Text interpretRow(Text row) {
+ return row;
+ }
+
+ @Override
+ public Text interpretBeginRow(Text row) {
+ return row;
+ }
+
+ @Override
+ public Text interpretEndRow(Text row) {
+ return row;
+ }
+
+ @Override
+ public Text interpretColumnFamily(Text cf) {
+ return cf;
+ }
+
+ @Override
+ public Text interpretColumnQualifier(Text cq) {
+ return cq;
+ }
+
+}
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java?rev=1376213&view=auto
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
(added)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/HexScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.accumulo.core.util.interpret;
+
+import org.apache.accumulo.core.util.format.HexFormatter;
+
+/**
+ * As simple scan interpreter that converts hex to binary. IT supports
translating the output of {@link HexFormatter} back to binary. The hex input
can contain
+ * dashes (because {@link HexFormatter} outputs dashes) which are ignored.
+ */
+public class HexScanInterpreter extends HexFormatter implements
ScanInterpreter {
+
+}
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java?rev=1376213&view=auto
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
(added)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/interpret/ScanInterpreter.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,35 @@
+/**
+ * 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.interpret;
+
+import org.apache.hadoop.io.Text;
+
+/**
+ * A simple interface for creating shell plugins that translate the range and
column arguments for the shell's scan command.
+ */
+public interface ScanInterpreter {
+
+ public Text interpretRow(Text row);
+
+ public Text interpretBeginRow(Text row);
+
+ public Text interpretEndRow(Text row);
+
+ public Text interpretColumnFamily(Text cf);
+
+ public Text interpretColumnQualifier(Text cq);
+}
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
Wed Aug 22 19:55:43 2012
@@ -103,6 +103,7 @@ import org.apache.accumulo.core.util.she
import org.apache.accumulo.core.util.shell.commands.ImportTableCommand;
import org.apache.accumulo.core.util.shell.commands.InfoCommand;
import org.apache.accumulo.core.util.shell.commands.InsertCommand;
+import org.apache.accumulo.core.util.shell.commands.InterpreterCommand;
import org.apache.accumulo.core.util.shell.commands.ListIterCommand;
import org.apache.accumulo.core.util.shell.commands.ListScansCommand;
import org.apache.accumulo.core.util.shell.commands.MaxRowCommand;
@@ -291,7 +292,7 @@ public class Shell extends ShellOptions
rootToken = new Token();
Command[] dataCommands = {new DeleteCommand(), new DeleteManyCommand(),
new DeleteRowsCommand(), new EGrepCommand(), new FormatterCommand(),
- new GrepCommand(), new ImportDirectoryCommand(), new InsertCommand(),
new MaxRowCommand(), new ScanCommand()};
+ new InterpreterCommand(), new GrepCommand(), new
ImportDirectoryCommand(), new InsertCommand(), new MaxRowCommand(), new
ScanCommand()};
Command[] debuggingCommands = {new ClasspathCommand(), new DebugCommand(),
new ListScansCommand(), new TraceCommand()};
Command[] execCommands = {new ExecfileCommand(), new HistoryCommand()};
Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new
QuitCommand()};
@@ -812,12 +813,6 @@ public class Shell extends ShellOptions
}
}
- public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean
printTimestamps, boolean paginate) throws IOException {
- Class<? extends Formatter> formatterClass = getFormatter();
-
- printRecords(scanner, printTimestamps, paginate, formatterClass);
- }
-
public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean
printTimestamps, boolean paginate, Class<? extends Formatter> formatterClass)
throws IOException {
printLines(FormatterFactory.getFormatter(formatterClass, scanner,
printTimestamps), paginate);
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/DeleteManyCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,30 +16,26 @@
*/
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.BatchWriter;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.iterators.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;
-import org.apache.commons.cli.ParseException;
public class DeleteManyCommand extends ScanCommand {
private Option forceOpt;
- public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
- IOException, ParseException {
+ public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
String tableName = OptUtil.getTableOpt(cl, shellState);
+ ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
// handle first argument, if present, the authorizations list to
// scan with
Authorizations auths = getAuths(cl, shellState);
@@ -48,10 +44,10 @@ public class DeleteManyCommand extends S
scanner.addScanIterator(new IteratorSetting(Integer.MAX_VALUE, "NOVALUE",
SortedKeyIterator.class));
// handle remaining optional arguments
- scanner.setRange(getRange(cl));
+ scanner.setRange(getRange(cl, interpeter));
// handle columns
- fetchColumns(cl, scanner);
+ fetchColumns(cl, scanner, interpeter);
// output / delete the records
BatchWriter writer =
shellState.getConnector().createBatchWriter(tableName, 1024 * 1024, 1000L, 4);
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,114 +16,52 @@
*/
package org.apache.accumulo.core.util.shell.commands;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.util.format.Formatter;
import org.apache.accumulo.core.util.shell.Shell;
-import org.apache.accumulo.core.util.shell.Shell.Command;
-import org.apache.accumulo.start.classloader.AccumuloClassLoader;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
-public class FormatterCommand extends Command {
- private Option removeFormatterOption, formatterClassOption, listClassOption;
+public class FormatterCommand extends ShellPluginConfigurationCommand {
+ private Option interpeterOption;
+
+ public FormatterCommand() {
+ super("formatter", Property.TABLE_FORMATTER_CLASS, "f");
+ }
+
@Override
public String description() {
return "specifies a formatter to use for displaying table entries";
}
-
- @Override
- public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
- String tableName = OptUtil.getTableOpt(cl, shellState);
-
- if (cl.hasOption(removeFormatterOption.getOpt())) {
- // Remove the property
- shellState.getConnector().tableOperations().removeProperty(tableName,
Property.TABLE_FORMATTER_CLASS.toString());
-
- shellState.getReader().printString("Removed formatter on " + tableName +
"\n");
- } else if (cl.hasOption(listClassOption.getOpt())) {
- // Get the options for this table
- Iterator<Entry<String,String>> iter =
shellState.getConnector().tableOperations().getProperties(tableName).iterator();
-
- while (iter.hasNext()) {
- Entry<String,String> ent = iter.next();
-
- // List all parameters with the property name
- if
(ent.getKey().startsWith(Property.TABLE_FORMATTER_CLASS.toString())) {
- shellState.getReader().printString(ent.getKey() + ": " +
ent.getValue() + "\n");
- }
- }
- } else {
- // Set the formatter with the provided options
- String className = cl.getOptionValue(formatterClassOption.getOpt());
-
- // Set the formatter property on the table
- shellState.getConnector().tableOperations().setProperty(tableName,
Property.TABLE_FORMATTER_CLASS.toString(), className);
- }
-
- return 0;
- }
-
+
public static Class<? extends Formatter> getCurrentFormatter(String
tableName, Shell shellState) {
- Iterator<Entry<String,String>> props;
- try {
- props =
shellState.getConnector().tableOperations().getProperties(tableName).iterator();
- } catch (AccumuloException e) {
- return null;
- } catch (TableNotFoundException e) {
- return null;
- }
-
- while (props.hasNext()) {
- Entry<String,String> ent = props.next();
- if (ent.getKey().equals(Property.TABLE_FORMATTER_CLASS.toString())) {
- Class<? extends Formatter> formatter;
- try {
- formatter = AccumuloClassLoader.loadClass(ent.getValue(),
Formatter.class);
- } catch (ClassNotFoundException e) {
- return null;
- }
-
- return formatter;
- }
- }
-
- return null;
+ return ShellPluginConfigurationCommand.getPluginClass(tableName,
shellState, Formatter.class, Property.TABLE_FORMATTER_CLASS);
}
@Override
public Options getOptions() {
- Options o = new Options();
- OptionGroup actionGroup = new OptionGroup();
+ Options options = super.getOptions();
- formatterClassOption = new Option("f", "formatter", true, "fully qualified
name of the formatter class to use");
- formatterClassOption.setArgName("className");
+ interpeterOption = new Option("i", "interpeter", false, "configure class
as interpreter also");
- // Action to take: apply (default), remove, list
- removeFormatterOption = new Option("r", "remove", false, "remove the
current formatter");
- listClassOption = new Option("l", "list", false, "display the current
formatter");
+ options.addOption(interpeterOption);
- actionGroup.addOption(formatterClassOption);
- actionGroup.addOption(removeFormatterOption);
- actionGroup.addOption(listClassOption);
- actionGroup.setRequired(true);
-
- o.addOptionGroup(actionGroup);
- o.addOption(OptUtil.tableOpt("table to set the formatter on"));
-
- return o;
+ return options;
}
- @Override
- public int numArgs() {
- return 0;
+ protected void setPlugin(CommandLine cl, Shell shellState, String tableName,
String className) throws AccumuloException, AccumuloSecurityException {
+ super.setPlugin(cl, shellState, tableName, className);
+ if (cl.hasOption(interpeterOption.getOpt()))
+ shellState.getConnector().tableOperations().setProperty(tableName,
Property.TABLE_INTERPRETER_CLASS.toString(), className);
}
+ protected void removePlugin(CommandLine cl, Shell shellState, String
tableName) throws AccumuloException, AccumuloSecurityException {
+ super.removePlugin(cl, shellState, tableName);
+ if (cl.hasOption(interpeterOption.getOpt()))
+ shellState.getConnector().tableOperations().removeProperty(tableName,
Property.TABLE_INTERPRETER_CLASS.toString());
+ }
}
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrepCommand.java
Wed Aug 22 19:55:43 2012
@@ -19,13 +19,12 @@ package org.apache.accumulo.core.util.sh
import java.io.IOException;
import java.util.Collections;
-import org.apache.accumulo.core.client.AccumuloException;
-import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.BatchScanner;
import org.apache.accumulo.core.client.IteratorSetting;
-import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.iterators.user.GrepIterator;
import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.util.format.Formatter;
+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.MissingArgumentException;
@@ -36,14 +35,16 @@ public class GrepCommand extends ScanCom
private Option numThreadsOpt;
- public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
- IOException, MissingArgumentException {
+ public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
String tableName = OptUtil.getTableOpt(cl, shellState);
if (cl.getArgList().isEmpty())
throw new MissingArgumentException("No terms specified");
+ Class<? extends Formatter> formatter = getFormatter(cl, tableName,
shellState);
+ ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
// handle first argument, if present, the authorizations list to
// scan with
int numThreads = 20;
@@ -52,17 +53,17 @@ public class GrepCommand extends ScanCom
}
Authorizations auths = getAuths(cl, shellState);
BatchScanner scanner =
shellState.getConnector().createBatchScanner(tableName, auths, numThreads);
- scanner.setRanges(Collections.singletonList(getRange(cl)));
+ scanner.setRanges(Collections.singletonList(getRange(cl, interpeter)));
for (int i = 0; i < cl.getArgs().length; i++)
setUpIterator(Integer.MAX_VALUE - cl.getArgs().length + i, "grep" + i,
cl.getArgs()[i], scanner);
try {
// handle columns
- fetchColumns(cl, scanner);
+ fetchColumns(cl, scanner, interpeter);
// output the records
- printRecords(cl, shellState, scanner);
+ printRecords(cl, shellState, scanner, formatter);
} finally {
scanner.close();
}
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java?rev=1376213&view=auto
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
(added)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/InterpreterCommand.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,45 @@
+/**
+ * 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.conf.Property;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
+import org.apache.accumulo.core.util.shell.Shell;
+
+/**
+ *
+ */
+public class InterpreterCommand extends ShellPluginConfigurationCommand {
+
+ /**
+ * @param typeName
+ * @param tableProp
+ * @param classOpt
+ */
+ public InterpreterCommand() {
+ super("interpreter", Property.TABLE_INTERPRETER_CLASS, "i");
+ }
+
+ @Override
+ public String description() {
+ return "specifies a scan interpreter to interpret scan range and column
arguments";
+ }
+
+ public static Class<? extends ScanInterpreter> getCurrentInterpreter(String
tableName, Shell shellState) {
+ return ShellPluginConfigurationCommand.getPluginClass(tableName,
shellState, ScanInterpreter.class, Property.TABLE_INTERPRETER_CLASS);
+ }
+}
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/MaxRowCommand.java
Wed Aug 22 19:55:43 2012
@@ -16,24 +16,21 @@
*/
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.TableNotFoundException;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.security.Authorizations;
+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.ParseException;
import org.apache.hadoop.io.Text;
public class MaxRowCommand extends ScanCommand {
- public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
- IOException, ParseException {
+ public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
String tableName = OptUtil.getTableOpt(cl, shellState);
- Range range = getRange(cl);
+
+ ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
+
+ Range range = getRange(cl, interpeter);
Authorizations auths = getAuths(cl, shellState);
Text startRow = range.getStartKey() == null ? null :
range.getStartKey().getRow();
Text endRow = range.getEndKey() == null ? null :
range.getEndKey().getRow();
Modified:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
(original)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ScanCommand.java
Wed Aug 22 19:55:43 2012
@@ -32,6 +32,8 @@ import org.apache.accumulo.core.data.Val
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.util.format.BinaryFormatter;
import org.apache.accumulo.core.util.format.Formatter;
+import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
+import org.apache.accumulo.core.util.interpret.ScanInterpreter;
import org.apache.accumulo.core.util.shell.Shell;
import org.apache.accumulo.core.util.shell.Shell.Command;
import org.apache.accumulo.start.classloader.AccumuloClassLoader;
@@ -42,7 +44,7 @@ import org.apache.hadoop.io.Text;
public class ScanCommand extends Command {
- private Option scanOptAuths, scanOptRow, scanOptColumns,
disablePaginationOpt, showFewOpt, formatterOpt;
+ private Option scanOptAuths, scanOptRow, scanOptColumns,
disablePaginationOpt, showFewOpt, formatterOpt, interpreterOpt,
formatterInterpeterOpt;
protected Option timestampOpt;
private Option optStartRowExclusive;
private Option optEndRowExclusive;
@@ -50,12 +52,8 @@ public class ScanCommand extends Command
public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
String tableName = OptUtil.getTableOpt(cl, shellState);
- Class<? extends Formatter> formatter = null;
-
- // Use the configured formatter unless one was provided
- if (!cl.hasOption(formatterOpt.getOpt())) {
- formatter = FormatterCommand.getCurrentFormatter(tableName, shellState);
- }
+ Class<? extends Formatter> formatter = getFormatter(cl, tableName,
shellState);
+ ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);
// handle first argument, if present, the authorizations list to
// scan with
@@ -66,10 +64,10 @@ public class ScanCommand extends Command
addScanIterators(shellState, scanner, tableName);
// handle remaining optional arguments
- scanner.setRange(getRange(cl));
+ scanner.setRange(getRange(cl, interpeter));
// handle columns
- fetchColumns(cl, scanner);
+ fetchColumns(cl, scanner, interpeter);
// output the records
if (cl.hasOption(showFewOpt.getOpt())) {
@@ -88,11 +86,7 @@ public class ScanCommand extends Command
}
} else {
- if (null == formatter) {
- printRecords(cl, shellState, scanner);
- } else {
printRecords(cl, shellState, scanner, formatter);
- }
}
return 0;
@@ -116,21 +110,6 @@ public class ScanCommand extends Command
}
}
- protected void printRecords(CommandLine cl, Shell shellState,
Iterable<Entry<Key,Value>> scanner) throws IOException {
- if (cl.hasOption(formatterOpt.getOpt())) {
- try {
- String className = cl.getOptionValue(formatterOpt.getOpt());
- Class<? extends Formatter> formatterClass =
AccumuloClassLoader.loadClass(className, Formatter.class);
-
- printRecords(cl, shellState, scanner, formatterClass);
- } catch (ClassNotFoundException e) {
- shellState.getReader().printString("Formatter class could not be
loaded.\n" + e.getMessage() + "\n");
- }
- } else {
- shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()),
!cl.hasOption(disablePaginationOpt.getOpt()));
- }
- }
-
protected void printRecords(CommandLine cl, Shell shellState,
Iterable<Entry<Key,Value>> scanner, Class<? extends Formatter> formatter)
throws IOException {
shellState.printRecords(scanner, cl.hasOption(timestampOpt.getOpt()),
!cl.hasOption(disablePaginationOpt.getOpt()), formatter);
}
@@ -139,19 +118,58 @@ public class ScanCommand extends Command
shellState.printBinaryRecords(scanner,
cl.hasOption(timestampOpt.getOpt()),
!cl.hasOption(disablePaginationOpt.getOpt()));
}
- protected void fetchColumns(CommandLine cl, ScannerBase scanner) throws
UnsupportedEncodingException {
+ protected ScanInterpreter getInterpreter(CommandLine cl, String tableName,
Shell shellState) throws Exception {
+
+ Class<? extends ScanInterpreter> clazz = null;
+ try {
+ if (cl.hasOption(interpreterOpt.getOpt())) {
+ clazz =
AccumuloClassLoader.loadClass(cl.getOptionValue(interpreterOpt.getOpt()),
ScanInterpreter.class);
+ } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+ clazz =
AccumuloClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()),
ScanInterpreter.class);
+ }
+ } catch (ClassNotFoundException e) {
+ shellState.getReader().printString("Interpreter class could not be
loaded.\n" + e.getMessage() + "\n");
+ }
+
+ if (clazz == null)
+ clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);
+
+ if (clazz == null)
+ clazz = DefaultScanInterpreter.class;
+
+ return clazz.newInstance();
+ }
+
+ protected Class<? extends Formatter> getFormatter(CommandLine cl, String
tableName, Shell shellState) throws IOException {
+
+ try {
+ if (cl.hasOption(formatterOpt.getOpt())) {
+ return
AccumuloClassLoader.loadClass(cl.getOptionValue(formatterOpt.getOpt()),
Formatter.class);
+
+ } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
+ return
AccumuloClassLoader.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()),
Formatter.class);
+ }
+ } catch (ClassNotFoundException e) {
+ shellState.getReader().printString("Formatter class could not be
loaded.\n" + e.getMessage() + "\n");
+ }
+
+ return shellState.getFormatter(tableName);
+ }
+
+ protected void fetchColumns(CommandLine cl, ScannerBase scanner,
ScanInterpreter formatter) throws UnsupportedEncodingException {
if (cl.hasOption(scanOptColumns.getOpt())) {
for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
String sa[] = a.split(":", 2);
if (sa.length == 1)
- scanner.fetchColumnFamily(new Text(a.getBytes(Shell.CHARSET)));
+ scanner.fetchColumnFamily(formatter.interpretColumnFamily(new
Text(a.getBytes(Shell.CHARSET))));
else
- scanner.fetchColumn(new Text(sa[0].getBytes(Shell.CHARSET)), new
Text(sa[1].getBytes(Shell.CHARSET)));
+ scanner.fetchColumn(formatter.interpretColumnFamily(new
Text(sa[0].getBytes(Shell.CHARSET))),
+ formatter.interpretColumnQualifier(new
Text(sa[1].getBytes(Shell.CHARSET))));
}
}
}
- protected Range getRange(CommandLine cl) throws UnsupportedEncodingException
{
+ protected Range getRange(CommandLine cl, ScanInterpreter formatter) throws
UnsupportedEncodingException {
if ((cl.hasOption(OptUtil.START_ROW_OPT) ||
cl.hasOption(OptUtil.END_ROW_OPT)) && cl.hasOption(scanOptRow.getOpt())) {
// did not see a way to make commons cli do this check... it has
mutually exclusive options but does not support the or
throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + "
AND (-" + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT
@@ -159,10 +177,14 @@ public class ScanCommand extends Command
}
if (cl.hasOption(scanOptRow.getOpt())) {
- return new Range(new
Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET)));
+ return new Range(formatter.interpretRow(new
Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
} else {
Text startRow = OptUtil.getStartRow(cl);
+ if (startRow != null)
+ startRow = formatter.interpretBeginRow(startRow);
Text endRow = OptUtil.getEndRow(cl);
+ if (endRow != null)
+ endRow = formatter.interpretEndRow(endRow);
boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
return new Range(startRow, startInclusive, endRow, endInclusive);
@@ -198,6 +220,8 @@ public class ScanCommand extends Command
disablePaginationOpt = new Option("np", "no-pagination", false, "disable
pagination of output");
showFewOpt = new Option("f", "show few", true, "show only a specified
number of characters");
formatterOpt = new Option("fm", "formatter", true, "fully qualified name
of the formatter class to use");
+ interpreterOpt = new Option("i", "interpreter", true, "fully qualified
name of the interpreter class to use");
+ formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true, "fully
qualified name of a class that is a formatter and interpreter");
scanOptAuths.setArgName("comma-separated-authorizations");
scanOptRow.setArgName("row");
@@ -218,6 +242,8 @@ public class ScanCommand extends Command
o.addOption(OptUtil.tableOpt("table to be scanned"));
o.addOption(showFewOpt);
o.addOption(formatterOpt);
+ o.addOption(interpreterOpt);
+ o.addOption(formatterInterpeterOpt);
return o;
}
Added:
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java?rev=1376213&view=auto
==============================================================================
---
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
(added)
+++
accumulo/trunk/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ShellPluginConfigurationCommand.java
Wed Aug 22 19:55:43 2012
@@ -0,0 +1,146 @@
+/*
+ * 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.Map.Entry;
+
+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.conf.Property;
+import org.apache.accumulo.core.util.shell.Shell;
+import org.apache.accumulo.core.util.shell.Shell.Command;
+import org.apache.accumulo.start.classloader.AccumuloClassLoader;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.log4j.Logger;
+
+public abstract class ShellPluginConfigurationCommand extends Command {
+ private Option removePluginOption, pluginClassOption, listPluginOption;
+
+ private String pluginType;
+
+ private Property tableProp;
+
+ private String classOpt;
+
+ ShellPluginConfigurationCommand(String typeName, Property tableProp, String
classOpt) {
+ this.pluginType = typeName;
+ this.tableProp = tableProp;
+ this.classOpt = classOpt;
+ }
+
+ @Override
+ public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
+ String tableName = OptUtil.getTableOpt(cl, shellState);
+
+ if (cl.hasOption(removePluginOption.getOpt())) {
+ // Remove the property
+ removePlugin(cl, shellState, tableName);
+
+ shellState.getReader().printString("Removed "+pluginType+" on " +
tableName + "\n");
+ } else if (cl.hasOption(listPluginOption.getOpt())) {
+ // Get the options for this table
+ Iterator<Entry<String,String>> iter =
shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+
+ while (iter.hasNext()) {
+ Entry<String,String> ent = iter.next();
+
+ // List all parameters with the property name
+ if (ent.getKey().startsWith(tableProp.toString())) {
+ shellState.getReader().printString(ent.getKey() + ": " +
ent.getValue() + "\n");
+ }
+ }
+ } else {
+ // Set the plugin with the provided options
+ String className = cl.getOptionValue(pluginClassOption.getOpt());
+
+ // Set the plugin property on the table
+ setPlugin(cl, shellState, tableName, className);
+ }
+
+ return 0;
+ }
+
+ protected void setPlugin(CommandLine cl, Shell shellState, String tableName,
String className) throws AccumuloException, AccumuloSecurityException {
+ shellState.getConnector().tableOperations().setProperty(tableName,
tableProp.toString(), className);
+ }
+
+ protected void removePlugin(CommandLine cl, Shell shellState, String
tableName) throws AccumuloException, AccumuloSecurityException {
+ shellState.getConnector().tableOperations().removeProperty(tableName,
tableProp.toString());
+ }
+
+ public static <T> Class<? extends T> getPluginClass(String tableName, Shell
shellState, Class<T> clazz, Property pluginProp) {
+ Iterator<Entry<String,String>> props;
+ try {
+ props =
shellState.getConnector().tableOperations().getProperties(tableName).iterator();
+ } catch (AccumuloException e) {
+ return null;
+ } catch (TableNotFoundException e) {
+ return null;
+ }
+
+ while (props.hasNext()) {
+ Entry<String,String> ent = props.next();
+ if (ent.getKey().equals(pluginProp.toString())) {
+ Class<? extends T> pluginClazz;
+ try {
+ pluginClazz = AccumuloClassLoader.loadClass(ent.getValue(), clazz);
+ } catch (ClassNotFoundException e) {
+ Logger.getLogger(ShellPluginConfigurationCommand.class).warn("Class
not found" + e.getMessage());
+ return null;
+ }
+
+ return pluginClazz;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Options getOptions() {
+ Options o = new Options();
+ OptionGroup actionGroup = new OptionGroup();
+
+ pluginClassOption = new Option(classOpt, pluginType, true, "fully
qualified name of the " + pluginType + " class to use");
+ pluginClassOption.setArgName("className");
+
+ // Action to take: apply (default), remove, list
+ removePluginOption = new Option("r", "remove", false, "remove the current
"+pluginType+"");
+ listPluginOption = new Option("l", "list", false, "display the current
"+pluginType+"");
+
+ actionGroup.addOption(pluginClassOption);
+ actionGroup.addOption(removePluginOption);
+ actionGroup.addOption(listPluginOption);
+ actionGroup.setRequired(true);
+
+ o.addOptionGroup(actionGroup);
+ o.addOption(OptUtil.tableOpt("table to set the "+pluginType+" on"));
+
+ return o;
+ }
+
+ @Override
+ public int numArgs() {
+ return 0;
+ }
+
+}
Modified:
accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
URL:
http://svn.apache.org/viewvc/accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java?rev=1376213&r1=1376212&r2=1376213&view=diff
==============================================================================
---
accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
(original)
+++
accumulo/trunk/core/src/test/java/org/apache/accumulo/core/util/shell/command/FormatterCommandTest.java
Wed Aug 22 19:55:43 2012
@@ -211,7 +211,6 @@ public class FormatterCommandTest {
this.iter = scanner.iterator();
this.printTs = printTimestamps;
}
-
}
}