boolean autoCleanup) throws ThriftSecurityException, ThriftTableOperationException {
authenticate(c);
switch (op) {
case NAMESPACE_CREATE: {
TableOperation tableOp = TableOperation.CREATE;
String namespace = validateNamespaceArgument(arguments.get(0), tableOp, null);
if (!master.security.canCreateNamespace(c, namespace))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new CreateNamespace(c.getPrincipal(), namespace, options)), autoCleanup);
break;
}
case NAMESPACE_RENAME: {
TableOperation tableOp = TableOperation.RENAME;
String oldName = validateNamespaceArgument(arguments.get(0), tableOp, Namespaces.NOT_DEFAULT.and(Namespaces.NOT_ACCUMULO));
String newName = validateNamespaceArgument(arguments.get(1), tableOp, null);
String namespaceId = ClientServiceHandler.checkNamespaceId(master.getInstance(), oldName, tableOp);
if (!master.security.canRenameNamespace(c, namespaceId, oldName, newName))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new RenameNamespace(namespaceId, oldName, newName)), autoCleanup);
break;
}
case NAMESPACE_DELETE: {
TableOperation tableOp = TableOperation.DELETE;
String namespace = validateNamespaceArgument(arguments.get(0), tableOp, Namespaces.NOT_DEFAULT.and(Namespaces.NOT_ACCUMULO));
String namespaceId = ClientServiceHandler.checkNamespaceId(master.getInstance(), namespace, tableOp);
if (!master.security.canDeleteNamespace(c, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new DeleteNamespace(namespaceId)), autoCleanup);
break;
}
case TABLE_CREATE: {
TableOperation tableOp = TableOperation.CREATE;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
TimeType timeType = TimeType.valueOf(ByteBufferUtil.toString(arguments.get(1)));
String namespaceId;
try {
namespaceId = Namespaces.getNamespaceId(master.getInstance(), Tables.qualify(tableName).getFirst());
} catch (NamespaceNotFoundException e) {
throw new ThriftTableOperationException(null, tableName, tableOp, TableOperationExceptionType.NAMESPACE_NOTFOUND, "");
}
if (!master.security.canCreateTable(c, tableName, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new CreateTable(c.getPrincipal(), tableName, timeType, options, namespaceId)), autoCleanup);
break;
}
case TABLE_RENAME: {
TableOperation tableOp = TableOperation.RENAME;
final String oldTableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
String newTableName = validateTableNameArgument(arguments.get(1), tableOp, new Validator<String>() {
@Override
public boolean isValid(String argument) {
// verify they are in the same namespace
String oldNamespace = Tables.qualify(oldTableName).getFirst();
return oldNamespace.equals(Tables.qualify(argument).getFirst());
}
@Override
public String invalidMessage(String argument) {
return "Cannot move tables to a new namespace by renaming. The namespace for " + oldTableName + " does not match " + argument;
}
});
String tableId = ClientServiceHandler.checkTableId(master.getInstance(), oldTableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canRenameTable(c, tableId, oldTableName, newTableName, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
try {
master.fate.seedTransaction(opid, new TraceRepo<Master>(new RenameTable(tableId, oldTableName, newTableName)), autoCleanup);
} catch (NamespaceNotFoundException e) {
throw new ThriftTableOperationException(null, oldTableName, tableOp, TableOperationExceptionType.NAMESPACE_NOTFOUND, "");
}
break;
}
case TABLE_CLONE: {
TableOperation tableOp = TableOperation.CLONE;
String srcTableId = validateTableIdArgument(arguments.get(0), tableOp, Tables.NOT_ROOT_ID);
String tableName = validateTableNameArgument(arguments.get(1), tableOp, Tables.NOT_SYSTEM);
String namespaceId;
try {
namespaceId = Namespaces.getNamespaceId(master.getInstance(), Tables.qualify(tableName).getFirst());
} catch (NamespaceNotFoundException e) {
// shouldn't happen, but possible once cloning between namespaces is supported
throw new ThriftTableOperationException(null, tableName, tableOp, TableOperationExceptionType.NAMESPACE_NOTFOUND, "");
}
if (!master.security.canCloneTable(c, srcTableId, tableName, namespaceId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
Map<String,String> propertiesToSet = new HashMap<String,String>();
Set<String> propertiesToExclude = new HashSet<String>();
for (Entry<String,String> entry : options.entrySet()) {
if (entry.getKey().startsWith(TableOperationsImpl.CLONE_EXCLUDE_PREFIX)) {
propertiesToExclude.add(entry.getKey().substring(TableOperationsImpl.CLONE_EXCLUDE_PREFIX.length()));
continue;
}
if (!TablePropUtil.isPropertyValid(entry.getKey(), entry.getValue())) {
throw new ThriftTableOperationException(null, tableName, tableOp, TableOperationExceptionType.OTHER, "Property or value not valid "
+ entry.getKey() + "=" + entry.getValue());
}
propertiesToSet.put(entry.getKey(), entry.getValue());
}
master.fate.seedTransaction(opid, new TraceRepo<Master>(new CloneTable(c.getPrincipal(), srcTableId, tableName, propertiesToSet, propertiesToExclude)),
autoCleanup);
break;
}
case TABLE_DELETE: {
TableOperation tableOp = TableOperation.DELETE;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
final String tableId = ClientServiceHandler.checkTableId(master.getInstance(), tableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canDeleteTable(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new DeleteTable(tableId)), autoCleanup);
break;
}
case TABLE_ONLINE: {
TableOperation tableOp = TableOperation.ONLINE;
final String tableId = validateTableIdArgument(arguments.get(0), tableOp, Tables.NOT_ROOT_ID);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canOnlineOfflineTable(c, tableId, op, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new ChangeTableState(tableId, tableOp)), autoCleanup);
break;
}
case TABLE_OFFLINE: {
TableOperation tableOp = TableOperation.OFFLINE;
final String tableId = validateTableIdArgument(arguments.get(0), tableOp, Tables.NOT_ROOT_ID);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canOnlineOfflineTable(c, tableId, op, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new ChangeTableState(tableId, tableOp)), autoCleanup);
break;
}
case TABLE_MERGE: {
TableOperation tableOp = TableOperation.MERGE;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, null);
Text startRow = ByteBufferUtil.toText(arguments.get(1));
Text endRow = ByteBufferUtil.toText(arguments.get(2));
final String tableId = ClientServiceHandler.checkTableId(master.getInstance(), tableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canMerge(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
Master.log.debug("Creating merge op: " + tableId + " " + startRow + " " + endRow);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new TableRangeOp(MergeInfo.Operation.MERGE, tableId, startRow, endRow)), autoCleanup);
break;
}
case TABLE_DELETE_RANGE: {
TableOperation tableOp = TableOperation.DELETE_RANGE;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
Text startRow = ByteBufferUtil.toText(arguments.get(1));
Text endRow = ByteBufferUtil.toText(arguments.get(2));
final String tableId = ClientServiceHandler.checkTableId(master.getInstance(), tableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canDeleteRange(c, tableId, tableName, startRow, endRow, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new TableRangeOp(MergeInfo.Operation.DELETE, tableId, startRow, endRow)), autoCleanup);
break;
}
case TABLE_BULK_IMPORT: {
TableOperation tableOp = TableOperation.BULK_IMPORT;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
String dir = ByteBufferUtil.toString(arguments.get(1));
String failDir = ByteBufferUtil.toString(arguments.get(2));
boolean setTime = Boolean.parseBoolean(ByteBufferUtil.toString(arguments.get(3)));
final String tableId = ClientServiceHandler.checkTableId(master.getInstance(), tableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canBulkImport(c, tableId, tableName, dir, failDir, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new BulkImport(tableId, dir, failDir, setTime)), autoCleanup);
break;
}
case TABLE_COMPACT: {
TableOperation tableOp = TableOperation.COMPACT;
String tableId = validateTableIdArgument(arguments.get(0), tableOp, null);
byte[] startRow = ByteBufferUtil.toBytes(arguments.get(1));
byte[] endRow = ByteBufferUtil.toBytes(arguments.get(2));
List<IteratorSetting> iterators = IteratorUtil.decodeIteratorSettings(ByteBufferUtil.toBytes(arguments.get(3)));
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canCompact(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new CompactRange(tableId, startRow, endRow, iterators)), autoCleanup);
break;
}
case TABLE_CANCEL_COMPACT: {
TableOperation tableOp = TableOperation.COMPACT_CANCEL;
String tableId = validateTableIdArgument(arguments.get(0), tableOp, null);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);
if (!master.security.canCompact(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new CancelCompactions(tableId)), autoCleanup);
break;
}
case TABLE_IMPORT: {
TableOperation tableOp = TableOperation.IMPORT;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
String exportDir = ByteBufferUtil.toString(arguments.get(1));
String namespaceId;
try {
namespaceId = Namespaces.getNamespaceId(master.getInstance(), Tables.qualify(tableName).getFirst());
} catch (NamespaceNotFoundException e) {
throw new ThriftTableOperationException(null, tableName, tableOp, TableOperationExceptionType.NAMESPACE_NOTFOUND, "");
}
if (!master.security.canImport(c, tableName, exportDir, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
master.fate.seedTransaction(opid, new TraceRepo<Master>(new ImportTable(c.getPrincipal(), tableName, exportDir, namespaceId)), autoCleanup);
break;
}
case TABLE_EXPORT: {
TableOperation tableOp = TableOperation.EXPORT;
String tableName = validateTableNameArgument(arguments.get(0), tableOp, Tables.NOT_SYSTEM);
String exportDir = ByteBufferUtil.toString(arguments.get(1));
String tableId = ClientServiceHandler.checkTableId(master.getInstance(), tableName, tableOp);
String namespaceId = Tables.getNamespaceId(master.getInstance(), tableId);