Author: ecn
Date: Wed Jan 11 13:24:42 2012
New Revision: 1230006
URL: http://svn.apache.org/viewvc?rev=1230006&view=rev
Log:
ACCUMULO-303: applying patch to allow per-table formatters in the shell
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/conf/Property.java
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/conf/Property.java
URL:
http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/conf/Property.java?rev=1230006&r1=1230005&r2=1230006&view=diff
==============================================================================
---
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/conf/Property.java
(original)
+++
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/conf/Property.java
Wed Jan 11 13:24:42 2012
@@ -286,7 +286,9 @@ public enum Property {
+ "with the category prefix, followed by a name, followed by a
period, and followed by a property for that group.<br />"
+ "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>."), ;
+ + "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");
private String key, defaultValue, description;
private PropertyType type;
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
URL:
http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java?rev=1230006&r1=1230005&r2=1230006&view=diff
==============================================================================
---
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
(original)
+++
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/Shell.java
Wed Jan 11 13:24:42 2012
@@ -163,8 +163,9 @@ public class Shell {
private Connector connector;
private ConsoleReader reader;
private AuthInfo credentials;
- private Class<? extends Formatter> formatterClass = DefaultFormatter.class;
+ private Class<? extends Formatter> defaultFormatterClass =
DefaultFormatter.class;
private Class<? extends Formatter> binaryFormatterClass =
BinaryFormatter.class;
+ private Map<String, Class<? extends Formatter>> tableFormatters = new
HashMap<String, Class<? extends Formatter>>();
public Map<String,List<IteratorSetting>> scanIteratorOptions = new
HashMap<String,List<IteratorSetting>>();
private Token rootToken;
@@ -217,7 +218,7 @@ public class Shell {
Option execCommandOpt = new Option("e", "execute-command", true, "executes
a command, and then exits");
opts.addOption(execCommandOpt);
-
+
OptionGroup execFileGroup = new OptionGroup();
Option execfileOption = new Option("f", "execute-file", true, "executes
commands from a file at startup");
@@ -459,8 +460,13 @@ public class Shell {
else
sb.append("- Authorization timeout: ").append(String.format("%.2fs\n",
authTimeout / 1000.0));
sb.append("- Debug: ").append(isDebuggingEnabled() ? "on" :
"off").append("\n");
- if (formatterClass != null && formatterClass != DefaultFormatter.class) {
- sb.append("- Active formatter class:
").append(formatterClass.getSimpleName()).append("\n");
+ if (!tableFormatters.isEmpty()) {
+ sb.append("- Active Formatters");
+ for (Entry<String, Class<? extends Formatter>> entry :
tableFormatters.entrySet()) {
+ if (null != entry.getValue()) {
+ sb.append("- Table: ").append(entry.getKey()).append(",
").append(entry.getValue().getName()).append("\n");
+ }
+ }
}
if (!scanIteratorOptions.isEmpty()) {
for (Entry<String,List<IteratorSetting>> entry :
scanIteratorOptions.entrySet()) {
@@ -905,6 +911,8 @@ public class Shell {
}
public final void printRecords(Iterable<Entry<Key,Value>> scanner, boolean
printTimestamps, boolean paginate) throws IOException {
+ Class<? extends Formatter> formatterClass =
getFormatterClass(this.tableName);
+
printLines(FormatterFactory.getFormatter(formatterClass, scanner,
printTimestamps), paginate);
}
@@ -989,12 +997,27 @@ public class Shell {
return credentials;
}
- public void setFormatterClass(Class<? extends Formatter> formatterClass) {
- this.formatterClass = formatterClass;
+ public void setFormatterClass(String tableName, Class<? extends Formatter>
formatter) {
+ this.tableFormatters.put(tableName, formatter);
}
- public Class<? extends Formatter> getFormatterClass() {
- return formatterClass;
+ /**
+ * Pull the current formatter for the given table and cache it.
+ * @param tableName
+ * @return The formatter class for the given table
+ */
+ public Class<? extends Formatter> getFormatterClass(String tableName) {
+ if (this.tableFormatters.containsKey(tableName) && null !=
this.tableFormatters.get(tableName)) {
+ return this.tableFormatters.get(tableName);
+ } else {
+ Class<? extends Formatter> formatter =
FormatterCommand.getCurrentFormatter(tableName, this);
+
+ if (null == formatter) {
+ return this.defaultFormatterClass;
+ } else {
+ return formatter;
+ }
+ }
}
}
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
URL:
http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java?rev=1230006&r1=1230005&r2=1230006&view=diff
==============================================================================
---
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
(original)
+++
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/ConfigCommand.java
Wed Jan 11 13:24:42 2012
@@ -32,9 +32,11 @@ import org.apache.accumulo.core.conf.Acc
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.accumulo.core.util.BadArgumentException;
+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.core.util.shell.Token;
+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;
@@ -59,7 +61,7 @@ public class ConfigCommand extends Comma
}
public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
- IOException {
+ IOException, ClassNotFoundException {
reader = shellState.getReader();
String tableName = cl.getOptionValue(tableOpt.getOpt());
@@ -74,6 +76,12 @@ public class ConfigCommand extends Comma
if (tableName != null) {
if (!Property.isValidTablePropertyKey(property))
Shell.log.warn("Invalid per-table property : " + property + ", still
removing from zookeeper if its there.");
+
+ // Fall back to the default formatter
+ if (property.equals(Property.TABLE_FORMATTER_CLASS.getKey())) {
+ shellState.setFormatterClass(tableName,
AccumuloClassLoader.loadClass(Property.TABLE_FORMATTER_CLASS.getDefaultValue(),
Formatter.class));
+ }
+
shellState.getConnector().tableOperations().removeProperty(tableName,
property);
Shell.log.debug("Successfully deleted table configuration option.");
} else {
@@ -100,6 +108,11 @@ public class ConfigCommand extends Comma
new ColumnVisibility(value); // validate that it is a valid
// expression
+ // Load the formatter before setting the parameter
+ if (property.equals(Property.TABLE_FORMATTER_CLASS.getKey())) {
+ shellState.setFormatterClass(tableName,
AccumuloClassLoader.loadClass(value, Formatter.class));
+ }
+
shellState.getConnector().tableOperations().setProperty(tableName,
property, value);
Shell.log.debug("Successfully set table configuration option.");
} else {
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
URL:
http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java?rev=1230006&r1=1230005&r2=1230006&view=diff
==============================================================================
---
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
(original)
+++
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/CreateTableCommand.java
Wed Jan 11 13:24:42 2012
@@ -36,8 +36,11 @@ import org.apache.accumulo.core.iterator
import org.apache.accumulo.core.iterators.conf.PerColumnIteratorConfig;
import org.apache.accumulo.core.security.VisibilityConstraint;
import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.format.DefaultFormatter;
+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;
@@ -56,10 +59,11 @@ public class CreateTableCommand extends
private Option createTableNoDefaultIters;
private Option createTableOptEVC;
private Option base64Opt;
+ private Option createTableOptFormatter;
public static String testTable;
public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableExistsException,
- TableNotFoundException, IOException {
+ TableNotFoundException, IOException, ClassNotFoundException {
String testTableName = cl.getArgs()[0];
@@ -128,11 +132,13 @@ public class CreateTableCommand extends
TimeType timeType = TimeType.MILLIS;
if (cl.hasOption(createTableOptTimeLogical.getOpt()))
timeType = TimeType.LOGICAL;
+
// create table
shellState.getConnector().tableOperations().create(tableName, true,
timeType);
shellState.getConnector().tableOperations().addSplits(tableName,
partitions);
shellState.getConnector().tableOperations().addAggregators(tableName,
aggregators);
+
shellState.setTableName(tableName); // switch shell to new table
// context
@@ -173,6 +179,15 @@ public class CreateTableCommand extends
shellState.getConnector().tableOperations()
.setProperty(tableName, Property.TABLE_CONSTRAINT_PREFIX.getKey()
+ (max + 1), VisibilityConstraint.class.getName());
}
+
+ // Load custom formatter if set
+ if (cl.hasOption(createTableOptFormatter.getOpt())) {
+ String formatterClass =
cl.getOptionValue(createTableOptFormatter.getOpt());
+
+ shellState.setFormatterClass(tableName,
AccumuloClassLoader.loadClass(formatterClass, Formatter.class));
+
+ shellState.getConnector().tableOperations().setProperty(tableName,
Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
+ }
return 0;
}
@@ -200,6 +215,7 @@ public class CreateTableCommand extends
createTableNoDefaultIters = new Option("ndi", "no-default-iterators",
false, "prevents creation of the normal default iterator set");
createTableOptEVC = new Option("evc", "enable-visibility-constraint",
false,
"prevents users from writing data they can not read. When enabling
this may want to consider disabling bulk import and alter table");
+ createTableOptFormatter = new Option("f", "formatter", false, "default
formatter to set");
createTableOptCopyConfig.setArgName("table");
createTableOptCopySplits.setArgName("table");
@@ -226,6 +242,7 @@ public class CreateTableCommand extends
o.addOption(createTableOptCopyConfig);
o.addOption(createTableNoDefaultIters);
o.addOption(createTableOptEVC);
+ o.addOption(createTableOptFormatter);
return o;
}
Modified:
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
URL:
http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java?rev=1230006&r1=1230005&r2=1230006&view=diff
==============================================================================
---
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
(original)
+++
incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/util/shell/commands/FormatterCommand.java
Wed Jan 11 13:24:42 2012
@@ -16,7 +16,12 @@
*/
package org.apache.accumulo.core.util.shell.commands;
-import org.apache.accumulo.core.util.format.DefaultFormatter;
+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.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;
@@ -27,39 +32,106 @@ import org.apache.commons.cli.OptionGrou
import org.apache.commons.cli.Options;
public class FormatterCommand extends Command {
- private Option resetOption, formatterClassOption, listClassOption;
+ private Option removeFormatterOption, formatterClassOption, listClassOption,
tableOption;
@Override
public String description() {
- return "specifies a formatter to use for displaying database entries";
+ return "specifies a formatter to use for displaying table entries";
}
@Override
public int execute(String fullCommand, CommandLine cl, Shell shellState)
throws Exception {
- if (cl.hasOption(resetOption.getOpt()))
- shellState.setFormatterClass(DefaultFormatter.class);
- else if (cl.hasOption(formatterClassOption.getOpt()))
-
shellState.setFormatterClass(AccumuloClassLoader.loadClass(cl.getOptionValue(formatterClassOption.getOpt()),
Formatter.class));
- else if (cl.hasOption(listClassOption.getOpt()))
-
shellState.getReader().printString(shellState.getFormatterClass().getName() +
"\n");
+ String tableName = shellState.getTableName();
+
+ if (cl.hasOption(tableOption.getOpt())) {
+ tableName = cl.getOptionValue(tableOption.getOpt());
+ }
+
+ if (cl.hasOption(removeFormatterOption.getOpt())) {
+ // Remove the property
+ shellState.getConnector().tableOperations().removeProperty(tableName,
Property.TABLE_FORMATTER_CLASS.toString());
+
+ // Reset the shell formatter on this table
+ shellState.setFormatterClass(tableName,
AccumuloClassLoader.loadClass(Property.TABLE_FORMATTER_CLASS.getDefaultValue(),
Formatter.class));
+
+ 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());
+
+ // Update the shell formatter for this table
+ shellState.setFormatterClass(tableName,
AccumuloClassLoader.loadClass(className, Formatter.class));
+
+ 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);
+ shellState.setFormatterClass(tableName, formatter);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+
+ return formatter;
+ }
+ }
+
+ return null;
+ }
+
@Override
public Options getOptions() {
Options o = new Options();
- OptionGroup formatGroup = new OptionGroup();
+ OptionGroup actionGroup = new OptionGroup();
+
+ // Table and formatter class name
+ tableOption = new Option("t", "table", true, "table to set the formatter
on");
+ tableOption.setArgName("table");
+ tableOption.setRequired(false);
- resetOption = new Option("r", "reset", false, "reset to default
formatter");
- formatterClassOption = new Option("f", "formatter", true, "fully qualified
name of formatter class to use");
+ formatterClassOption = new Option("f", "formatter", true, "fully qualified
name of the formatter class to use");
formatterClassOption.setArgName("className");
+
+ // 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");
- formatGroup.addOption(resetOption);
- formatGroup.addOption(formatterClassOption);
- formatGroup.addOption(listClassOption);
- formatGroup.setRequired(true);
- o.addOptionGroup(formatGroup);
+ actionGroup.addOption(formatterClassOption);
+ actionGroup.addOption(removeFormatterOption);
+ actionGroup.addOption(listClassOption);
+ actionGroup.setRequired(true);
+
+ o.addOptionGroup(actionGroup);
+ o.addOption(tableOption);
return o;
}