blob: de89137f74bdd522f2b9799ffe503969de557dcc [file] [log] [blame]
/*
* 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.client.mock;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
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.IteratorSetting;
import org.apache.accumulo.core.client.NamespaceNotFoundException;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.CompactionConfig;
import org.apache.accumulo.core.client.admin.DiskUsage;
import org.apache.accumulo.core.client.admin.FindMax;
import org.apache.accumulo.core.client.admin.Locations;
import org.apache.accumulo.core.client.admin.NewTableConfiguration;
import org.apache.accumulo.core.client.admin.TimeType;
import org.apache.accumulo.core.client.impl.TableOperationsHelper;
import org.apache.accumulo.core.client.impl.Tables;
import org.apache.accumulo.core.client.sample.SamplerConfiguration;
import org.apache.accumulo.core.conf.AccumuloConfiguration;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.file.FileOperations;
import org.apache.accumulo.core.file.FileSKVIterator;
import org.apache.accumulo.core.metadata.MetadataTable;
import org.apache.accumulo.core.metadata.RootTable;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.accumulo.start.classloader.vfs.AccumuloVFSClassLoader;
import org.apache.commons.lang.NotImplementedException;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
/**
* @deprecated since 1.8.0; use MiniAccumuloCluster or a standard mock framework instead.
*/
@Deprecated
class MockTableOperations extends TableOperationsHelper {
private static final Logger log = LoggerFactory.getLogger(MockTableOperations.class);
private static final byte[] ZERO = {0};
private final MockAccumulo acu;
private final String username;
MockTableOperations(MockAccumulo acu, String username) {
this.acu = acu;
this.username = username;
}
@Override
public SortedSet<String> list() {
return new TreeSet<>(acu.tables.keySet());
}
@Override
public boolean exists(String tableName) {
return acu.tables.containsKey(tableName);
}
private boolean namespaceExists(String namespace) {
return acu.namespaces.containsKey(namespace);
}
@Override
public void create(String tableName) throws AccumuloException, AccumuloSecurityException, TableExistsException {
create(tableName, new NewTableConfiguration());
}
@Override
@Deprecated
public void create(String tableName, boolean versioningIter) throws AccumuloException, AccumuloSecurityException, TableExistsException {
create(tableName, versioningIter, TimeType.MILLIS);
}
@Override
@Deprecated
public void create(String tableName, boolean versioningIter, TimeType timeType) throws AccumuloException, AccumuloSecurityException, TableExistsException {
NewTableConfiguration ntc = new NewTableConfiguration().setTimeType(timeType);
if (versioningIter)
create(tableName, ntc);
else
create(tableName, ntc.withoutDefaultIterators());
}
@Override
public void create(String tableName, NewTableConfiguration ntc) throws AccumuloException, AccumuloSecurityException, TableExistsException {
String namespace = Tables.qualify(tableName).getFirst();
checkArgument(tableName.matches(Tables.VALID_NAME_REGEX));
if (exists(tableName))
throw new TableExistsException(tableName, tableName, "");
checkArgument(namespaceExists(namespace), "Namespace (" + namespace + ") does not exist, create it first");
acu.createTable(username, tableName, ntc.getTimeType(), ntc.getProperties());
}
@Override
public void addSplits(String tableName, SortedSet<Text> partitionKeys) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
acu.addSplits(tableName, partitionKeys);
}
@Deprecated
@Override
public Collection<Text> getSplits(String tableName) throws TableNotFoundException {
return listSplits(tableName);
}
@Deprecated
@Override
public Collection<Text> getSplits(String tableName, int maxSplits) throws TableNotFoundException {
return listSplits(tableName);
}
@Override
public Collection<Text> listSplits(String tableName) throws TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
return acu.getSplits(tableName);
}
@Override
public Collection<Text> listSplits(String tableName, int maxSplits) throws TableNotFoundException {
return listSplits(tableName);
}
@Override
public void delete(String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
acu.tables.remove(tableName);
}
@Override
public void rename(String oldTableName, String newTableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException,
TableExistsException {
if (!exists(oldTableName))
throw new TableNotFoundException(oldTableName, oldTableName, "");
if (exists(newTableName))
throw new TableExistsException(newTableName, newTableName, "");
MockTable t = acu.tables.remove(oldTableName);
String namespace = Tables.qualify(newTableName).getFirst();
MockNamespace n = acu.namespaces.get(namespace);
if (n == null) {
n = new MockNamespace();
}
t.setNamespaceName(namespace);
t.setNamespace(n);
acu.namespaces.put(namespace, n);
acu.tables.put(newTableName, t);
}
@Deprecated
@Override
public void flush(String tableName) throws AccumuloException, AccumuloSecurityException {}
@Override
public void setProperty(String tableName, String property, String value) throws AccumuloException, AccumuloSecurityException {
acu.tables.get(tableName).settings.put(property, value);
}
@Override
public void removeProperty(String tableName, String property) throws AccumuloException, AccumuloSecurityException {
acu.tables.get(tableName).settings.remove(property);
}
@Override
public Iterable<Entry<String,String>> getProperties(String tableName) throws TableNotFoundException {
String namespace = Tables.qualify(tableName).getFirst();
if (!exists(tableName)) {
if (!namespaceExists(namespace))
throw new TableNotFoundException(tableName, new NamespaceNotFoundException(null, namespace, null));
throw new TableNotFoundException(null, tableName, null);
}
Set<Entry<String,String>> props = new HashSet<>(acu.namespaces.get(namespace).settings.entrySet());
Set<Entry<String,String>> tableProps = acu.tables.get(tableName).settings.entrySet();
for (Entry<String,String> e : tableProps) {
if (props.contains(e)) {
props.remove(e);
}
props.add(e);
}
return props;
}
@Override
public void setLocalityGroups(String tableName, Map<String,Set<Text>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
acu.tables.get(tableName).setLocalityGroups(groups);
}
@Override
public Map<String,Set<Text>> getLocalityGroups(String tableName) throws AccumuloException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
return acu.tables.get(tableName).getLocalityGroups();
}
@Override
public Set<Range> splitRangeByTablets(String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException,
TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
return Collections.singleton(range);
}
@Override
public void importDirectory(String tableName, String dir, String failureDir, boolean setTime) throws IOException, AccumuloException,
AccumuloSecurityException, TableNotFoundException {
long time = System.currentTimeMillis();
MockTable table = acu.tables.get(tableName);
if (table == null) {
throw new TableNotFoundException(null, tableName, "The table was not found");
}
Path importPath = new Path(dir);
Path failurePath = new Path(failureDir);
FileSystem fs = acu.getFileSystem();
/*
* check preconditions
*/
// directories are directories
if (fs.isFile(importPath)) {
throw new IOException("Import path must be a directory.");
}
if (fs.isFile(failurePath)) {
throw new IOException("Failure path must be a directory.");
}
// failures are writable
Path createPath = failurePath.suffix("/.createFile");
FSDataOutputStream createStream = null;
try {
createStream = fs.create(createPath);
} catch (IOException e) {
throw new IOException("Error path is not writable.");
} finally {
if (createStream != null) {
createStream.close();
}
}
fs.delete(createPath, false);
// failures are empty
FileStatus[] failureChildStats = fs.listStatus(failurePath);
if (failureChildStats.length > 0) {
throw new IOException("Error path must be empty.");
}
/*
* Begin the import - iterate the files in the path
*/
for (FileStatus importStatus : fs.listStatus(importPath)) {
try {
FileSKVIterator importIterator = FileOperations.getInstance().newReaderBuilder().forFile(importStatus.getPath().toString(), fs, fs.getConf())
.withTableConfiguration(AccumuloConfiguration.getDefaultConfiguration()).seekToBeginning().build();
while (importIterator.hasTop()) {
Key key = importIterator.getTopKey();
Value value = importIterator.getTopValue();
if (setTime) {
key.setTimestamp(time);
}
Mutation mutation = new Mutation(key.getRow());
if (!key.isDeleted()) {
mutation.put(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibilityData().toArray()), key.getTimestamp(),
value);
} else {
mutation.putDelete(key.getColumnFamily(), key.getColumnQualifier(), new ColumnVisibility(key.getColumnVisibilityData().toArray()),
key.getTimestamp());
}
table.addMutation(mutation);
importIterator.next();
}
} catch (Exception e) {
FSDataOutputStream failureWriter = null;
DataInputStream failureReader = null;
try {
failureWriter = fs.create(failurePath.suffix("/" + importStatus.getPath().getName()));
failureReader = fs.open(importStatus.getPath());
int read = 0;
byte[] buffer = new byte[1024];
while (-1 != (read = failureReader.read(buffer))) {
failureWriter.write(buffer, 0, read);
}
} finally {
if (failureReader != null)
failureReader.close();
if (failureWriter != null)
failureWriter.close();
}
}
fs.delete(importStatus.getPath(), true);
}
}
@Override
public void offline(String tableName) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
offline(tableName, false);
}
@Override
public void offline(String tableName, boolean wait) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public void online(String tableName) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
online(tableName, false);
}
@Override
public void online(String tableName, boolean wait) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public void clearLocatorCache(String tableName) throws TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public Map<String,String> tableIdMap() {
Map<String,String> result = new HashMap<>();
for (Entry<String,MockTable> entry : acu.tables.entrySet()) {
String table = entry.getKey();
if (RootTable.NAME.equals(table))
result.put(table, RootTable.ID);
else if (MetadataTable.NAME.equals(table))
result.put(table, MetadataTable.ID);
else
result.put(table, entry.getValue().getTableId());
}
return result;
}
@Override
public List<DiskUsage> getDiskUsage(Set<String> tables) throws AccumuloException, AccumuloSecurityException {
List<DiskUsage> diskUsages = new ArrayList<>();
diskUsages.add(new DiskUsage(new TreeSet<>(tables), 0l));
return diskUsages;
}
@Override
public void merge(String tableName, Text start, Text end) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
acu.merge(tableName, start, end);
}
@Override
public void deleteRows(String tableName, Text start, Text end) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
MockTable t = acu.tables.get(tableName);
Text startText = start != null ? new Text(start) : new Text();
if (startText.getLength() == 0 && end == null) {
t.table.clear();
return;
}
Text endText = end != null ? new Text(end) : new Text(t.table.lastKey().getRow().getBytes());
startText.append(ZERO, 0, 1);
endText.append(ZERO, 0, 1);
Set<Key> keep = new TreeSet<>(t.table.subMap(new Key(startText), new Key(endText)).keySet());
t.table.keySet().removeAll(keep);
}
@Override
public void compact(String tableName, Text start, Text end, boolean flush, boolean wait) throws AccumuloSecurityException, TableNotFoundException,
AccumuloException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public void compact(String tableName, Text start, Text end, List<IteratorSetting> iterators, boolean flush, boolean wait) throws AccumuloSecurityException,
TableNotFoundException, AccumuloException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
if (iterators != null && iterators.size() > 0)
throw new UnsupportedOperationException();
}
@Override
public void compact(String tableName, CompactionConfig config) throws AccumuloSecurityException, TableNotFoundException, AccumuloException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
if (config.getIterators().size() > 0 || config.getCompactionStrategy() != null)
throw new UnsupportedOperationException("Mock does not support iterators or compaction strategies for compactions");
}
@Override
public void cancelCompaction(String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public void clone(String srcTableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException {
throw new NotImplementedException();
}
@Override
public void flush(String tableName, Text start, Text end, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
if (!exists(tableName))
throw new TableNotFoundException(tableName, tableName, "");
}
@Override
public Text getMaxRow(String tableName, Authorizations auths, Text startRow, boolean startInclusive, Text endRow, boolean endInclusive)
throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
MockTable table = acu.tables.get(tableName);
if (table == null)
throw new TableNotFoundException(tableName, tableName, "no such table");
return FindMax.findMax(new MockScanner(table, auths), startRow, startInclusive, endRow, endInclusive);
}
@Override
public void importTable(String tableName, String exportDir) throws TableExistsException, AccumuloException, AccumuloSecurityException {
throw new NotImplementedException();
}
@Override
public void exportTable(String tableName, String exportDir) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
throw new NotImplementedException();
}
@Override
public boolean testClassLoad(String tableName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException,
TableNotFoundException {
try {
AccumuloVFSClassLoader.loadClass(className, Class.forName(asTypeName));
} catch (ClassNotFoundException e) {
log.warn("Could not load class '" + className + "' with type name '" + asTypeName + "' in testClassLoad().", e);
return false;
}
return true;
}
@Override
public void setSamplerConfiguration(String tableName, SamplerConfiguration samplerConfiguration) throws TableNotFoundException, AccumuloException,
AccumuloSecurityException {
throw new UnsupportedOperationException();
}
@Override
public void clearSamplerConfiguration(String tableName) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
throw new UnsupportedOperationException();
}
@Override
public SamplerConfiguration getSamplerConfiguration(String tableName) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
throw new UnsupportedOperationException();
}
@Override
public Locations locate(String tableName, Collection<Range> ranges) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
throw new UnsupportedOperationException();
}
}