Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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
*
* https://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.shell.commands;
import static org.apache.accumulo.core.util.Validators.NEW_TABLE_NAME;
import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.NewTableConfiguration;
import org.apache.accumulo.core.client.admin.TimeType;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.data.constraints.VisibilityConstraint;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.iteratorsImpl.IteratorConfigUtil;
import org.apache.accumulo.shell.Shell;
import org.apache.accumulo.shell.Shell.Command;
import org.apache.accumulo.shell.ShellUtil;
import org.apache.accumulo.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;
private Option createTableOptInitProp;
private Option createTableOptLocalityProps;
private Option createTableOptIteratorProps;
private Option createTableOptOffline;
@Override
public int execute(final String fullCommand, final CommandLine cl, final Shell shellState)
throws AccumuloException, AccumuloSecurityException, TableExistsException,
TableNotFoundException, IOException {
final String tableName = cl.getArgs()[0];
NewTableConfiguration ntc = new NewTableConfiguration();
NEW_TABLE_NAME.validate(tableName);
if (shellState.getAccumuloClient().tableOperations().exists(tableName)) {
throw new TableExistsException(null, tableName, null);
}
final boolean decode = cl.hasOption(base64Opt.getOpt());
// Prior to 2.0, if splits were provided at table creation the table was created separately
// and then the addSplits method was called. Starting with 2.0, the splits will be
// stored on the file system and created before the table is brought online.
if (cl.hasOption(createTableOptSplit.getOpt())) {
ntc = ntc.withSplits(new TreeSet<>(
ShellUtil.scanFile(cl.getOptionValue(createTableOptSplit.getOpt()), decode)));
} else if (cl.hasOption(createTableOptCopySplits.getOpt())) {
final String oldTable = cl.getOptionValue(createTableOptCopySplits.getOpt());
if (!shellState.getAccumuloClient().tableOperations().exists(oldTable)) {
throw new TableNotFoundException(null, oldTable, null);
}
ntc = ntc.withSplits(
new TreeSet<>(shellState.getAccumuloClient().tableOperations().listSplits(oldTable)));
}
if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
final String oldTable = cl.getOptionValue(createTableOptCopyConfig.getOpt());
if (!shellState.getAccumuloClient().tableOperations().exists(oldTable)) {
throw new TableNotFoundException(null, oldTable, null);
}
}
TimeType timeType = TimeType.MILLIS;
if (cl.hasOption(createTableOptTimeLogical.getOpt())) {
timeType = TimeType.LOGICAL;
}
Map props = ShellUtil.parseMapOpt(cl, createTableOptInitProp);
// Set iterator if supplied
if (cl.hasOption(createTableOptIteratorProps.getOpt())) {
ntc = attachIteratorToNewTable(cl, shellState, ntc);
}
// Set up locality groups, if supplied
if (cl.hasOption(createTableOptLocalityProps.getOpt())) {
ntc = setLocalityForNewTable(cl, ntc);
}
// set offline table creation property
if (cl.hasOption(createTableOptOffline.getOpt())) {
ntc = ntc.createOffline();
}
// create table.
shellState.getAccumuloClient().tableOperations().create(tableName,
ntc.setTimeType(timeType).setProperties(props));
shellState.setTableName(tableName); // switch shell to new table context
if (cl.hasOption(createTableNoDefaultIters.getOpt())) {
Set initialProps = IteratorConfigUtil.generateInitialTableProperties(true).keySet();
shellState.getAccumuloClient().tableOperations().modifyProperties(tableName,
properties -> initialProps.forEach(properties::remove));
}
// Copy options if flag was set
if (cl.hasOption(createTableOptCopyConfig.getOpt())) {
if (shellState.getAccumuloClient().tableOperations().exists(tableName)) {
final Map configuration = shellState.getAccumuloClient().tableOperations()
.getConfiguration(cl.getOptionValue(createTableOptCopyConfig.getOpt()));
shellState.getAccumuloClient().tableOperations().modifyProperties(tableName,
properties -> configuration.entrySet().stream()
.filter(entry -> Property.isValidTablePropertyKey(entry.getKey()))
.forEach(entry -> properties.put(entry.getKey(), entry.getValue())));
}
}
if (cl.hasOption(createTableOptEVC.getOpt())) {
try {
shellState.getAccumuloClient().tableOperations().addConstraint(tableName,
VisibilityConstraint.class.getName());
} catch (AccumuloException e) {
Shell.log.warn("{} while setting visibility constraint, but table was created",
e.getMessage(), e);
}
}
// Load custom formatter if set
if (cl.hasOption(createTableOptFormatter.getOpt())) {
final String formatterClass = cl.getOptionValue(createTableOptFormatter.getOpt());
shellState.getAccumuloClient().tableOperations().setProperty(tableName,
Property.TABLE_FORMATTER_CLASS.toString(), formatterClass);
}
return 0;
}
/**
* Add supplied locality groups information to a NewTableConfiguration object.
*
* Used in conjunction with createtable shell command to allow locality groups to be configured
* upon table creation.
*/
private NewTableConfiguration setLocalityForNewTable(CommandLine cl, NewTableConfiguration ntc) {
HashMap> localityGroupMap = new HashMap<>();
String[] options = cl.getOptionValues(createTableOptLocalityProps.getOpt());
for (String localityInfo : options) {
final String[] parts = localityInfo.split("=", 2);
if (parts.length < 2)
throw new IllegalArgumentException("Missing '=' or there are spaces between entries");
final String groupName = parts[0];
final HashSet colFams = new HashSet<>();
for (String family : parts[1].split(","))
colFams.add(new Text(family.getBytes(Shell.CHARSET)));
// check that group names are not duplicated on usage line
if (localityGroupMap.put(groupName, colFams) != null)
throw new IllegalArgumentException(
"Duplicate locality group name found. Group names must be unique");
}
ntc.setLocalityGroups(localityGroupMap);
return ntc;
}
/**
* Add supplied iterator information to NewTableConfiguration object.
*
* Used in conjunction with createtable shell command to allow an iterator to be configured upon
* table creation.
*/
private NewTableConfiguration attachIteratorToNewTable(final CommandLine cl,
final Shell shellState, NewTableConfiguration ntc) {
EnumSet scopeEnumSet;
IteratorSetting iteratorSetting;
if (shellState.iteratorProfiles.isEmpty())
throw new IllegalArgumentException("No shell iterator profiles have been created.");
String[] options = cl.getOptionValues(createTableOptIteratorProps.getOpt());
for (String profileInfo : options) {
String[] parts = profileInfo.split(":", 2);
String profileName = parts[0];
// The iteratorProfiles.get calls below will throw an NPE if the profile does not exist
// This can occur when the profile actually does not exist or if there is
// extraneous spacing in the iterator profile argument list causing the parser to read a scope
// as a profile.
try {
iteratorSetting = shellState.iteratorProfiles.get(profileName).get(0);
} catch (NullPointerException ex) {
throw new IllegalArgumentException("invalid iterator argument. Either"
+ " profile does not exist or unexpected spaces in argument list.", ex);
}
// handle case where only the profile is supplied. Use all scopes by default if no scope args
// are provided.
if (parts.length == 1) {
// add all scopes to enum set
scopeEnumSet = EnumSet.allOf(IteratorScope.class);
} else {
// user provided scope arguments exist, parse them
List scopeArgs = Arrays.asList(parts[1].split(","));
// there are only three allowable scope values
if (scopeArgs.size() > 3)
throw new IllegalArgumentException("Too many scope arguments supplied");
// handle the 'all' argument separately since it is not an allowable enum value for
// IteratorScope
// if 'all' is used, it should be the only scope provided
if (scopeArgs.contains("all")) {
if (scopeArgs.size() > 1)
throw new IllegalArgumentException("Cannot use 'all' in conjunction with other scopes");
scopeEnumSet = EnumSet.allOf(IteratorScope.class);
} else {
// 'all' is not involved, examine the scope arguments and populate iterator scope EnumSet
scopeEnumSet = validateScopes(scopeArgs);
}
}
ntc.attachIterator(iteratorSetting, scopeEnumSet);
}
return ntc;
}
/**
* Validate that the provided scope arguments are valid iterator scope settings. Checking for
* duplicate entries and invalid scope values.
*
* Returns an EnumSet of scopes to be set.
*/
private EnumSet validateScopes(final List scopeList) {
EnumSet scopes = EnumSet.noneOf(IteratorScope.class);
for (String scopeStr : scopeList) {
try {
IteratorScope scope = IteratorScope.valueOf(scopeStr);
if (!scopes.add(scope))
throw new IllegalArgumentException("duplicate scope arguments found");
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException("illegal scope arguments: " + ex.getMessage(), ex);
}
}
return scopes;
}
@Override
public String description() {
return "creates a new table, with optional aggregators, iterators, locality"
+ " groups 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");
createTableOptInitProp =
new Option("prop", "init-properties", true, "user defined initial properties");
createTableOptCopyConfig.setArgName("table");
createTableOptCopySplits.setArgName("table");
createTableOptSplit.setArgName("filename");
createTableOptFormatter.setArgName("className");
createTableOptInitProp.setArgName("properties");
createTableOptLocalityProps =
new Option("l", "locality", true, "create locality groups at table creation");
createTableOptLocalityProps.setArgName("group=col_fam[,col_fam]");
createTableOptLocalityProps.setArgs(Option.UNLIMITED_VALUES);
createTableOptIteratorProps = new Option("i", "iter", true,
"initialize iterator at table creation using profile. If no scope supplied, all"
+ " scopes are activated.");
createTableOptIteratorProps.setArgName("profile[:[all]|[scan[,]][minc[,]][majc]]");
createTableOptIteratorProps.setArgs(Option.UNLIMITED_VALUES);
createTableOptOffline = new Option("o", "offline", false, "create table in offline mode");
// 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);
o.addOption(createTableOptInitProp);
o.addOption(createTableOptLocalityProps);
o.addOption(createTableOptIteratorProps);
o.addOption(createTableOptOffline);
return o;
}
@Override
public int numArgs() {
return 1;
}
@Override
public void registerCompletion(final Token root,
final Map> special) {
registerCompletionForNamespaces(root, special);
}
}