initial import

This commit is contained in:
Dennis Patrone
2015-09-02 15:42:52 -04:00
commit 365b11fd6b
46 changed files with 6155 additions and 0 deletions

95
proxy-instance/pom.xml Normal file
View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>edu.jhuapl.accumulo</groupId>
<artifactId>proxy-instance-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>proxy-instance</artifactId>
<name>proxy-instance</name>
<description>Implements Accumulo Java API through the Accumulo Thrift-based Proxy server.</description>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-core</artifactId>
<version>${accumulo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-proxy</artifactId>
<version>${accumulo.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>stec.va.core.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.maven-java-formatter-plugin</groupId>
<artifactId>maven-java-formatter-plugin</artifactId>
<version>0.4</version>
<configuration>
<configFile>${project.basedir}/src/main/resources/Eclipse-Codestyle.xml</configFile>
<lineEnding>LF</lineEnding>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.11</version>
<configuration>
<header>license.txt</header>
<useDefaultExcludes>true</useDefaultExcludes>
<excludes>
<exclude>**/pom.xml</exclude>
<exclude>**/resources/**</exclude>
<exclude>**/**.txt</exclude>
<exclude>**/**.asciidoc</exclude>
<exclude>LICENSE</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
<goal>check</goal>
</goals>
<phase>process-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>edu.jhuapl.accumulo</groupId>
<artifactId>proxy-instance-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>proxy-instance</artifactId>
<name>proxy-instance</name>
<description>Implements Accumulo Java API through the Accumulo Thrift-based Proxy server.</description>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-core</artifactId>
<version>${accumulo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-proxy</artifactId>
<version>${accumulo.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>stec.va.core.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.maven-java-formatter-plugin</groupId>
<artifactId>maven-java-formatter-plugin</artifactId>
<version>0.4</version>
<configuration>
<configFile>${project.basedir}/src/main/resources/Eclipse-Codestyle.xml</configFile>
<lineEnding>LF</lineEnding>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.11</version>
<configuration>
<header>license.txt</header>
<useDefaultExcludes>true</useDefaultExcludes>
<excludes>
<exclude>**/pom.xml</exclude>
<exclude>**/resources/**</exclude>
<exclude>**/**.txt</exclude>
<exclude>**/**.asciidoc</exclude>
<exclude>LICENSE</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
<goal>check</goal>
</goals>
<phase>process-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,90 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.ScannerBase;
import org.apache.accumulo.proxy.thrift.ScanColumn;
import org.apache.hadoop.io.Text;
/**
* Parent class for proxy scanners.
*/
abstract class AbstractProxyScanner implements ScannerBase {
/**
* The connector that created this scanner.
*/
protected ProxyConnector connector;
/**
* The token used when making proxy requests.
*/
protected ByteBuffer token;
/**
* Table name for this scanner.
*/
protected String tableName;
/**
* Id assigned to this scanner by the proxy server.
*/
protected String scannerId = null;
protected AbstractProxyScanner(ProxyConnector connector, ByteBuffer token, String tableName) {
this.connector = connector;
this.token = token;
this.tableName = tableName;
}
public void setTimeout(long timeOut, TimeUnit timeUnit) {
// proxy API does not support time outs for scanners
throw ExceptionFactory.unsupported();
}
public long getTimeout(TimeUnit timeUnit) {
// proxy API does not support time outs for scanners
throw ExceptionFactory.unsupported();
}
public void fetchColumnFamily(Text col) {
fetchColumn(col, null);
}
public void fetchColumn(Text colFam, Text colQual) {
ScanColumn sc = new ScanColumn();
if (colFam != null) {
sc.setColFamily(colFam.getBytes());
}
if (colQual != null) {
sc.setColQualifier(colQual.getBytes());
}
addToFetchOptions(sc);
}
/**
* Subclasses must set themselves up to fetch the given ScanColumn. This allows Scanners and BatchScanners to handle the ScanColumn option differently.
*
* @param col
* the column to add to the current set of fetch options
*/
protected abstract void addToFetchOptions(ScanColumn col);
}

View File

@@ -0,0 +1,113 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
/**
* A factory to create standard exceptions for specific conditions.
* */
final class ExceptionFactory {
/**
* As a utility, this should not be instantiated.
*/
private ExceptionFactory() {}
/**
* Exception to throw when a Java Client API method is not supported in the Proxy Client API.
*
* @return a new UnsupportedOperationException that tells the user this feature is not supported by the Proxy Thrift interface.
*/
public static UnsupportedOperationException unsupported() {
return new UnsupportedOperationException("Operation not supported by Accumulo Proxy API.");
}
/**
* Exception to throw when the ProxyInstace has not yet implemented a Java API method.
*
* @return a new UnsupportedOperationException that tells the user this feature is not implemented yet.
*/
public static UnsupportedOperationException notYetImplemented() {
return new UnsupportedOperationException("Not yet implemented.");
}
/**
* Creates an AccumuloException with the given Throwable embedded as the cause.
*
* @param cause
* the root cause of this exception
* @return a new AccumuloException with the given root cause
*/
public static AccumuloException accumuloException(Throwable cause) {
return new AccumuloException(cause);
}
/**
* Wraps the thrift exception with a core client exception.
*
* @param tableName
* the table name that was not found.
* @param tnfe
* the Thrift TableNotFoundException
* @return a new (non-Thrift) TableNotFoundException
*/
public static TableNotFoundException tableNotFoundException(String tableName, org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
return new TableNotFoundException(null, tableName, tnfe.getMsg(), tnfe);
}
/**
* Wraps the thrift exception with a core client exception.
*
* @param tableName
* the table name that already exists
* @param tee
* the Thrift TableExistsException
* @return a new (non-Thrift) TableExistsException
*/
public static TableExistsException tableExistsException(String tableName, org.apache.accumulo.proxy.thrift.TableExistsException tee) {
return new TableExistsException(null, tableName, tee.getMsg(), tee);
}
/**
* Creates a new RuntimeException with the given Throwable as the cause.
*
* @param cause
* the cause of this exception
* @return a new RuntimeException with the given cause
*/
public static RuntimeException runtimeException(Throwable cause) {
return new RuntimeException(cause);
}
/**
* Used when we expect to be able to convert a particular value from one enum type (e.g., Java API) in another enum type (e.g., Proxy API) but can't. As we
* expect this to always work, this is an Error, not an Exception.
*
* @param val
* the original enumeration value
* @param otherCls
* the other Enumeration type we were trying to which we were trying to map {@code val}
* @return a new ProxyInstanceError that informs the user we expected but were unable to find a valid enumeration mapping.
*/
public static ProxyInstanceError noEnumMapping(Enum<?> val, Class<? extends Enum<?>> otherCls) {
return new ProxyInstanceError("Expected mapping from value " + val + " (" + val.getClass().getCanonicalName() + ") to " + otherCls.getCanonicalName()
+ " but it does not exist.");
}
}

View File

@@ -0,0 +1,177 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.proxy.thrift.ColumnUpdate;
import org.apache.accumulo.proxy.thrift.MutationsRejectedException;
import org.apache.thrift.TException;
/**
* A class used to buffer mutation on the client side in a user-sized memory buffer and/or for a user-defined amount of time before sending to the
* ProxyInstance. By buffering and sending many requests at once, performance may be improved some situations.
*
* This class does not actually do the sending when thresholds are exceeded; rather it just provides the access to the buffered Mutations and tracks the time
* and memory in order to be able to inform other classes when the buffer need to be flushed.
*
*/
class MutationBuffer {
/**
* The map of writerIds to a list of buffered mutations.
*/
private Map<String,List<Mutation>> mutations;
/**
* The maximum amount of memory (in bytes) to use before automatically pushing the buffered mutations to the Proxy server.
*/
long maxMemory;
/**
* The maximum amount of time (in milliseconds) to wait before automatically pushing the buffered mutations to the Proxy server.
*/
long maxLatencyMs;
/**
* The current estimate of buffered mutation memory in bytes.
*/
long memory;
ProxyConnector connector;
Timer timer;
/**
* Create a new MutationBuffer with the given configuration parameters.
*
* @param config
* the configuration for this buffer
*/
MutationBuffer(ProxyConnector connector, BatchWriterConfig config) {
this.connector = connector;
this.maxMemory = config.getMaxMemory();
this.maxLatencyMs = config.getMaxLatency(TimeUnit.MILLISECONDS);
this.memory = 0L;
this.mutations = new HashMap<String,List<Mutation>>();
}
/**
* Add a mutation to this buffer.
*
* @param mutation
* the mutation to add
* @throws org.apache.accumulo.core.client.MutationsRejectedException
* throws if the mutation cannot be accepted
*/
public synchronized void addMutation(String writerId, Mutation mutation) throws org.apache.accumulo.core.client.MutationsRejectedException {
if (mutations.isEmpty()) {
// this is the first entry... start watching latency...
timer = new Timer("", true);
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
latencyFlush();
} catch (org.apache.accumulo.core.client.MutationsRejectedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, maxLatencyMs);
}
// create our own copy...
mutation = new Mutation(mutation);
List<Mutation> list = mutations.get(writerId);
if (list == null) {
list = new ArrayList<Mutation>();
mutations.put(writerId, list);
}
list.add(mutation);
memory += mutation.estimatedMemoryUsed();
checkMemoryFlush();
}
void checkMemoryFlush() throws org.apache.accumulo.core.client.MutationsRejectedException {
if (memory >= maxMemory) {
// memory threshold exceeded
flush();
}
}
void latencyFlush() throws org.apache.accumulo.core.client.MutationsRejectedException {
if (mutations.size() != 0) {
// latency threshold exceeded
flush();
}
}
/**
* Called to flush the buffer. The method returns a map of rowIDs (as ByteBuffers) to lists of Thrift-based ColumnUpdates suitable for sending directly to the
* ProxyInstance. As a side effect, this method also resets this buffer.
*
* @throws org.apache.accumulo.core.client.MutationsRejectedException
* thrown if any buffered mutations are rejected while flushing
*/
public synchronized void flush() throws org.apache.accumulo.core.client.MutationsRejectedException {
for (Entry<String,List<Mutation>> entry : mutations.entrySet()) {
String writerId = entry.getKey();
Map<ByteBuffer,List<ColumnUpdate>> updates = new HashMap<ByteBuffer,List<ColumnUpdate>>();
for (Mutation m : entry.getValue()) {
ByteBuffer key = ByteBuffer.wrap(m.getRow());
List<ColumnUpdate> updateList = updates.get(key);
if (updateList == null) {
updateList = new ArrayList<ColumnUpdate>();
updates.put(key, updateList);
}
ThriftHelper.addThriftColumnUpdates(updateList, m.getUpdates());
}
try {
connector.getClient().update(writerId, updates);
connector.getClient().flush(writerId);
} catch (MutationsRejectedException mre) {
throw ThriftHelper.fromThrift(mre, connector.getInstance());
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
// and reset...
memory = 0;
if (timer != null) {
timer.cancel();
timer = null;
}
mutations.clear();
}
}

View File

@@ -0,0 +1,121 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.util.List;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.ActiveCompaction;
import org.apache.accumulo.core.data.KeyExtent;
/**
* Implementation of an ActiveCompaction for the ProxyInstance. This is basically a data structure to hold all of the provided details about an active
* compaction.
*/
class ProxyActiveCompaction extends ActiveCompaction {
String table;
KeyExtent extent;
long age;
List<String> inputFiles;
String outputFile;
CompactionType type;
CompactionReason reason;
String localityGroup;
long entriesRead;
long entriesWritten;
List<IteratorSetting> iterators;
ProxyActiveCompaction(String table, KeyExtent extent, long age, List<String> inputFiles, String outputFile, CompactionType type, CompactionReason reason,
String localityGroup, long entriesRead, long entriesWritten, List<IteratorSetting> iterators) {
super();
this.table = table;
this.extent = extent;
this.age = age;
this.inputFiles = inputFiles;
this.outputFile = outputFile;
this.type = type;
this.reason = reason;
this.localityGroup = localityGroup;
this.entriesRead = entriesRead;
this.entriesWritten = entriesWritten;
this.iterators = iterators;
}
@Override
public String getTable() throws TableNotFoundException {
return table;
}
@Override
public KeyExtent getExtent() {
return extent;
}
@Override
public long getAge() {
return age;
}
@Override
public List<String> getInputFiles() {
return inputFiles;
}
@Override
public String getOutputFile() {
return outputFile;
}
@Override
public CompactionType getType() {
return type;
}
@Override
public CompactionReason getReason() {
return reason;
}
@Override
public String getLocalityGroup() {
return localityGroup;
}
@Override
public long getEntriesRead() {
return entriesRead;
}
@Override
public long getEntriesWritten() {
return entriesWritten;
}
@Override
public List<IteratorSetting> getIterators() {
return iterators;
}
@Override
public String toString() {
return "ProxyActiveCompaction [table=" + table + ", extent=" + extent + ", age=" + age + ", inputFiles=" + inputFiles + ", outputFile=" + outputFile
+ ", type=" + type + ", reason=" + reason + ", localityGroup=" + localityGroup + ", entriesRead=" + entriesRead + ", entriesWritten=" + entriesWritten
+ ", iterators=" + iterators + "]";
}
}

View File

@@ -0,0 +1,141 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import org.apache.accumulo.core.client.admin.ActiveScan;
import org.apache.accumulo.core.client.admin.ScanState;
import org.apache.accumulo.core.client.admin.ScanType;
import org.apache.accumulo.core.data.Column;
import org.apache.accumulo.core.data.KeyExtent;
import org.apache.accumulo.core.security.Authorizations;
/**
* Implementation of an ActiveScan for the ProxyInstance. This is basically a data structure to hold all of the provided details about an active scan.
*/
class ProxyActiveScan extends ActiveScan {
long scanId;
String client;
String user;
String table;
long age;
long lastContactTime;
ScanType type;
ScanState state;
KeyExtent extent;
List<Column> columns;
Authorizations authorizations;
long idleTime;
ProxyActiveScan(long scanId, String client, String user, String table, long age, long lastContactTime, ScanType type, ScanState state, KeyExtent extent,
List<Column> columns, List<ByteBuffer> authorizations, long idleTime) {
super();
this.scanId = scanId;
this.client = client;
this.user = user;
this.table = table;
this.age = age;
this.lastContactTime = lastContactTime;
this.type = type;
this.state = state;
this.extent = extent;
this.columns = columns;
this.authorizations = new Authorizations(authorizations);
this.idleTime = idleTime;
}
@Override
public long getScanid() {
return scanId;
}
@Override
public String getClient() {
return client;
}
@Override
public String getUser() {
return user;
}
@Override
public String getTable() {
return table;
}
@Override
public long getAge() {
return age;
}
@Override
public long getLastContactTime() {
return lastContactTime;
}
@Override
public ScanType getType() {
return type;
}
@Override
public ScanState getState() {
return state;
}
@Override
public KeyExtent getExtent() {
return extent;
}
@Override
public List<Column> getColumns() {
return columns;
}
@Override
public List<String> getSsiList() {
throw ExceptionFactory.unsupported();
}
@Override
public Map<String,Map<String,String>> getSsio() {
throw ExceptionFactory.unsupported();
}
@Override
public Authorizations getAuthorizations() {
return authorizations;
}
@Override
public long getIdleTime() {
return idleTime;
}
@Override
public String toString() {
return "ProxyActiveScan [scanId=" + scanId + ", client=" + client + ", user=" + user + ", table=" + table + ", age=" + age + ", lastContactTime="
+ lastContactTime + ", type=" + type + ", state=" + state + ", extent=" + extent + ", columns=" + columns + ", authorizations=" + authorizations
+ ", idleTime=" + idleTime + "]";
}
}

View File

@@ -0,0 +1,134 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import org.apache.accumulo.core.client.BatchScanner;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.BatchScanOptions;
import org.apache.accumulo.proxy.thrift.ScanColumn;
import org.apache.thrift.TException;
import org.slf4j.LoggerFactory;
/**
* Implementation of a BatchScanner for the ProxyInstance.
*
*/
class ProxyBatchScanner extends AbstractProxyScanner implements BatchScanner {
/**
* The scan options set for this batch scanner.
*/
protected BatchScanOptions batchOptions;
protected int fetchSize;
ProxyBatchScanner(ProxyConnector connector, ByteBuffer token, String tableName, Authorizations authorizations, int numQueryThreads, int fetchSize) {
super(connector, token, tableName);
this.fetchSize = fetchSize;
batchOptions = new BatchScanOptions();
batchOptions.setThreads(numQueryThreads);
for (ByteBuffer auth : authorizations.getAuthorizationsBB()) {
batchOptions.addToAuthorizations(auth);
}
}
public void setRanges(Collection<Range> ranges) {
if (ranges == null) {
batchOptions.unsetRanges();
} else {
batchOptions.setRanges(ThriftHelper.toThriftRanges(ranges));
}
}
public void addScanIterator(IteratorSetting cfg) {
batchOptions.addToIterators(ThriftHelper.toThrift(cfg));
}
public void removeScanIterator(String iteratorName) {
for (org.apache.accumulo.proxy.thrift.IteratorSetting is : batchOptions.iterators) {
if (is.getName().equals(iteratorName)) {
batchOptions.iterators.remove(is);
break;
}
}
}
public void updateScanIteratorOption(String iteratorName, String key, String value) {
for (org.apache.accumulo.proxy.thrift.IteratorSetting is : batchOptions.iterators) {
if (is.getName().equals(iteratorName)) {
is.putToProperties(key, value);
}
}
}
@Override
protected void addToFetchOptions(ScanColumn col) {
batchOptions.addToColumns(col);
}
public void clearColumns() {
if (batchOptions.getColumns() != null) {
batchOptions.getColumns().clear();
}
}
public void clearScanIterators() {
if (batchOptions.getIterators() != null) {
batchOptions.getIterators().clear();
}
}
public Iterator<Entry<Key,Value>> iterator() {
AccumuloProxy.Iface client = connector.getClient();
try {
scannerId = client.createBatchScanner(token, tableName, batchOptions);
return new ScannerIterator(scannerId, connector, fetchSize);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public void close() {
try {
connector.getClient().closeScanner(scannerId);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
} finally {
scannerId = null;
}
}
@Override
protected void finalize() {
if (scannerId != null) {
close();
LoggerFactory.getLogger(ProxyBatchScanner.class).warn(
"BatchScanner " + scannerId + " in finalize but not closed; " + "you forgot to close a batch scanner!");
}
}
}

View File

@@ -0,0 +1,148 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.MutationsRejectedException;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.proxy.thrift.AccumuloException;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
import org.apache.accumulo.proxy.thrift.TableNotFoundException;
import org.apache.accumulo.proxy.thrift.UnknownWriter;
import org.apache.accumulo.proxy.thrift.WriterOptions;
import org.apache.thrift.TException;
import org.slf4j.LoggerFactory;
/**
* Implementation of a BatchWriter to a Proxy Server.
*/
class ProxyBatchWriter implements BatchWriter {
/**
* Parent connector.
*/
ProxyConnector connector;
/**
* Local copy of connector's Thrift RPC object to Proxy Server.
*/
private AccumuloProxy.Iface client;
/**
* Token used when communicating with the proxy server.
*/
ByteBuffer token;
/**
* The id for this writer.
*/
String writerId;
/**
* An internal buffer to provide in-memory, time-based buffering of mutations to send in batches. This uses the same memory and latency parameters the actual
* BatchWriter will use on the Proxy Server side as well.
*/
private MutationBuffer mutationBuffer;
private boolean closed;
ProxyBatchWriter(ProxyConnector connector, ByteBuffer token, String table, BatchWriterConfig config) throws AccumuloException, AccumuloSecurityException,
TableNotFoundException, TException {
this.connector = connector;
this.client = connector.getClient();
this.token = token;
WriterOptions opts = new WriterOptions();
opts.setLatencyMs(config.getMaxLatency(TimeUnit.MILLISECONDS));
opts.setMaxMemory(config.getMaxMemory());
opts.setThreads(config.getMaxWriteThreads());
writerId = client.createWriter(token, table, opts);
mutationBuffer = new MutationBuffer(connector, config);
closed = false;
}
private void checkClosed() throws IllegalStateException {
if (closed) {
throw new IllegalStateException("Closed.");
}
}
@Override
public void addMutation(Mutation m) throws MutationsRejectedException {
checkClosed();
addMutationNoCloseCheck(m);
}
@Override
public void addMutations(Iterable<Mutation> iterable) throws MutationsRejectedException {
checkClosed();
for (Mutation m : iterable) {
addMutationNoCloseCheck(m);
}
}
private void addMutationNoCloseCheck(Mutation m) throws MutationsRejectedException {
if (m.size() == 0) {
throw new IllegalArgumentException("Cannot add empty mutation.");
}
mutationBuffer.addMutation(writerId, m);
}
@Override
public void flush() throws MutationsRejectedException {
checkClosed();
mutationBuffer.flush();
}
@Override
public void close() throws MutationsRejectedException {
checkClosed();
mutationBuffer.flush();
try {
client.closeWriter(writerId);
closed = true;
} catch (UnknownWriter e) {
throw ExceptionFactory.runtimeException(e);
} catch (org.apache.accumulo.proxy.thrift.MutationsRejectedException e) {
throw ThriftHelper.fromThrift(e, connector.getInstance());
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
@Override
protected void finalize() {
if (!closed) {
LoggerFactory.getLogger(ProxyBatchWriter.class).warn(
"ProxyBatchWriter ID " + writerId + " in finalize but not closed; " + "you forgot to close a ProxyBatchWriter!");
try {
close();
} catch (MutationsRejectedException mre) {
LoggerFactory.getLogger(ProxyBatchScanner.class).warn("Problem closing ProxyMultiTableBatchWriter.", mre);
}
}
}
}

View File

@@ -0,0 +1,126 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.ConditionalWriter;
import org.apache.accumulo.core.client.ConditionalWriterConfig;
import org.apache.accumulo.core.data.ConditionalMutation;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.ColumnUpdate;
import org.apache.accumulo.proxy.thrift.ConditionalStatus;
import org.apache.accumulo.proxy.thrift.ConditionalUpdates;
import org.apache.accumulo.proxy.thrift.ConditionalWriterOptions;
import org.apache.thrift.TException;
class ProxyConditionalWriter implements ConditionalWriter {
AccumuloProxy.Iface client;
String writerId;
ProxyConditionalWriter(ProxyConnector connector, ByteBuffer token, String table, ConditionalWriterConfig config) {
this.client = connector.getClient();
ConditionalWriterOptions options = new ConditionalWriterOptions();
options.setAuthorizations(new HashSet<ByteBuffer>(config.getAuthorizations().getAuthorizationsBB()));
options.setThreads(config.getMaxWriteThreads());
options.setTimeoutMs(config.getTimeout(TimeUnit.MILLISECONDS));
try {
writerId = client.createConditionalWriter(token, table, options);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Iterator<Result> write(Iterator<ConditionalMutation> mutations) {
Map<ByteBuffer,ConditionalUpdates> updates = new HashMap<ByteBuffer,ConditionalUpdates>();
Map<ByteBuffer,ConditionalMutation> mutationMap = new HashMap<ByteBuffer,ConditionalMutation>();
while (mutations.hasNext()) {
ConditionalMutation mutation = mutations.next();
ByteBuffer key = ByteBuffer.wrap(mutation.getRow());
ConditionalUpdates update = updates.get(key);
// NOTE: API seems to imply you will provide a mutation against
// any single row ID at most once within this iterator or
// conditional mutations. Otherwise, the mutations and the
// conditions all get co-mingled when placed in the parameter
// map! TODO- should we check for this and throw an exception?
// working under the assumption you do not want to co-mingle updates
// for a single row within a single call here, we will *replace*
// (vs. update) anything that was existing in the map. This feels
// wrong...
update = new ConditionalUpdates();
updates.put(key, update);
mutationMap.put(key, mutation);
update.setConditions(ThriftHelper.toThriftCondition(mutation.getConditions()));
List<ColumnUpdate> tupdates = new LinkedList<ColumnUpdate>();
ThriftHelper.addThriftColumnUpdates(tupdates, mutation.getUpdates());
update.setUpdates(tupdates);
}
try {
Map<ByteBuffer,ConditionalStatus> status = client.updateRowsConditionally(writerId, updates);
List<Result> results = new LinkedList<Result>();
for (Entry<ByteBuffer,ConditionalStatus> entry : status.entrySet()) {
ConditionalMutation cm = mutationMap.get(entry.getKey());
Status staus = ThriftHelper.convertEnum(entry.getValue(), Status.class);
Result r = new Result(staus, cm, null) {
@Override
public String getTabletServer() {
// we are not given the tablet server nor have any way
// to find out what it is...
throw ExceptionFactory.unsupported();
}
};
results.add(r);
}
return results.iterator();
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Result write(ConditionalMutation mutation) {
Iterator<Result> results = write(Collections.singleton(mutation).iterator());
return results.next();
}
public void close() {
try {
client.closeConditionalWriter(writerId);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
}

View File

@@ -0,0 +1,170 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import static edu.jhuapl.accumulo.proxy.ThriftHelper.UTF8;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.BatchDeleter;
import org.apache.accumulo.core.client.BatchScanner;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.ConditionalWriter;
import org.apache.accumulo.core.client.ConditionalWriterConfig;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.MultiTableBatchWriter;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.InstanceOperations;
import org.apache.accumulo.core.client.admin.NamespaceOperations;
import org.apache.accumulo.core.client.admin.SecurityOperations;
import org.apache.accumulo.core.client.admin.TableOperations;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
import org.apache.thrift.TException;
class ProxyConnector extends Connector {
ProxyInstance instance;
String principal;
ByteBuffer token;
ProxyConnector(ProxyInstance instance, String principal, AuthenticationToken auth) throws AccumuloSecurityException, TException {
// TODO probably a better way to do this...
if (!(auth instanceof PasswordToken)) {
throw new IllegalArgumentException("Currently only works with PasswordTokens.");
}
this.instance = instance;
this.principal = principal;
String passwd = new String(((PasswordToken) auth).getPassword(), UTF8);
Map<String,String> password = new HashMap<String,String>();
password.put("password", passwd);
token = instance.getClient().login(principal, password);
}
@Override
public BatchScanner createBatchScanner(String tableName, Authorizations authorizations, int numQueryThreads) throws TableNotFoundException {
if (!tableOperations().exists(tableName)) {
throw new TableNotFoundException(null, tableName, null);
}
return new ProxyBatchScanner(this, token, tableName, authorizations, numQueryThreads, instance.getBatchScannerFetchSize());
}
@Override
@Deprecated
public BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations, int numQueryThreads, long maxMemory, long maxLatency,
int maxWriteThreads) throws TableNotFoundException {
return createBatchDeleter(tableName, authorizations, numQueryThreads, new BatchWriterConfig().setMaxLatency(maxLatency, TimeUnit.MILLISECONDS)
.setMaxMemory(maxMemory).setMaxWriteThreads(maxWriteThreads));
}
@Override
public BatchDeleter createBatchDeleter(String tableName, Authorizations authorizations, int numQueryThreads, BatchWriterConfig config)
throws TableNotFoundException {
throw ExceptionFactory.notYetImplemented();
}
@Override
@Deprecated
public BatchWriter createBatchWriter(String tableName, long maxMemory, long maxLatency, int maxWriteThreads) throws TableNotFoundException {
return createBatchWriter(tableName,
new BatchWriterConfig().setMaxMemory(maxMemory).setMaxLatency(maxLatency, TimeUnit.MILLISECONDS).setMaxWriteThreads(maxWriteThreads));
}
@Override
public BatchWriter createBatchWriter(String tableName, BatchWriterConfig config) throws TableNotFoundException {
if (!tableOperations().exists(tableName)) {
throw new TableNotFoundException(null, tableName, null);
}
try {
return new ProxyBatchWriter(this, token, tableName, config);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
@Override
@Deprecated
public MultiTableBatchWriter createMultiTableBatchWriter(long maxMemory, long maxLatency, int maxWriteThreads) {
return createMultiTableBatchWriter(new BatchWriterConfig().setMaxMemory(maxMemory).setMaxLatency(maxLatency, TimeUnit.MILLISECONDS)
.setMaxWriteThreads(maxWriteThreads));
}
@Override
public MultiTableBatchWriter createMultiTableBatchWriter(BatchWriterConfig config) {
return new ProxyMultiTableBatchWriter(this, this.token, config);
}
@Override
public Scanner createScanner(String tableName, Authorizations authorizations) throws TableNotFoundException {
if (!tableOperations().exists(tableName)) {
throw new TableNotFoundException(null, tableName, null);
}
return new ProxyScanner(this, token, tableName, authorizations);
}
@Override
public ConditionalWriter createConditionalWriter(String tableName, ConditionalWriterConfig config) throws TableNotFoundException {
if (!tableOperations().exists(tableName)) {
throw new TableNotFoundException(null, tableName, null);
}
return new ProxyConditionalWriter(this, token, tableName, config);
}
AccumuloProxy.Iface getClient() {
return instance.getClient();
}
@Override
public Instance getInstance() {
return instance;
}
@Override
public String whoami() {
return principal;
}
@Override
public TableOperations tableOperations() {
return new ProxyTableOperations(this, token);
}
@Override
public NamespaceOperations namespaceOperations() {
throw ExceptionFactory.unsupported();
}
@Override
public SecurityOperations securityOperations() {
return new ProxySecurityOperations(this, token);
}
@Override
public InstanceOperations instanceOperations() {
return new ProxyInstanceOperations(this, token);
}
}

View File

@@ -0,0 +1,722 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.io.Closeable;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.conf.AccumuloConfiguration;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.accumulo.proxy.thrift.ActiveCompaction;
import org.apache.accumulo.proxy.thrift.ActiveScan;
import org.apache.accumulo.proxy.thrift.BatchScanOptions;
import org.apache.accumulo.proxy.thrift.ColumnUpdate;
import org.apache.accumulo.proxy.thrift.ConditionalStatus;
import org.apache.accumulo.proxy.thrift.ConditionalUpdates;
import org.apache.accumulo.proxy.thrift.ConditionalWriterOptions;
import org.apache.accumulo.proxy.thrift.DiskUsage;
import org.apache.accumulo.proxy.thrift.IteratorScope;
import org.apache.accumulo.proxy.thrift.IteratorSetting;
import org.apache.accumulo.proxy.thrift.Key;
import org.apache.accumulo.proxy.thrift.KeyValueAndPeek;
import org.apache.accumulo.proxy.thrift.MutationsRejectedException;
import org.apache.accumulo.proxy.thrift.NoMoreEntriesException;
import org.apache.accumulo.proxy.thrift.PartialKey;
import org.apache.accumulo.proxy.thrift.Range;
import org.apache.accumulo.proxy.thrift.ScanOptions;
import org.apache.accumulo.proxy.thrift.ScanResult;
import org.apache.accumulo.proxy.thrift.SystemPermission;
import org.apache.accumulo.proxy.thrift.TableExistsException;
import org.apache.accumulo.proxy.thrift.TableNotFoundException;
import org.apache.accumulo.proxy.thrift.TablePermission;
import org.apache.accumulo.proxy.thrift.TimeType;
import org.apache.accumulo.proxy.thrift.UnknownScanner;
import org.apache.accumulo.proxy.thrift.UnknownWriter;
import org.apache.accumulo.proxy.thrift.WriterOptions;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.LoggerFactory;
/**
* A proxy instance that uses the Accumulo Proxy Thrift interface to fulfill the Accumulo client APIs. Note this instance implements Closeable and, while not
* part of the public Instance API, should be closed when no longer needed.
*/
public class ProxyInstance implements Instance, Closeable {
/**
* Default fetch size to be used for BatchScanners. Currently equal to 1,000.
*/
private static final int DEFAULT_FETCH_SIZE = 1_000;
private AccumuloProxy.Iface client;
private TTransport transport;
private int fetchSize;
/**
* Assumes a TSocket transport wrapped by a TFramedTransport.
*
* @param host
* the host name or IP address where the Accumulo Thrift Proxy server is running
* @param port
* the port where the Accumulo Thrift Proxy server is listening
* @throws TTransportException
* thrown if the Thrift TTransport cannot be established.
*/
public ProxyInstance(String host, int port) throws TTransportException {
this(host, port, DEFAULT_FETCH_SIZE);
}
/**
* Assumes a TSocket transport wrapped by a TFramedTransport.
*
* @param host
* the host name or IP address where the Accumulo Thrift Proxy server is running
* @param port
* the port where the Accumulo Thrift Proxy server is listening
* @param fetchSize
* the fetch size for BatchScanners
* @throws TTransportException
* thrown if the Thrift TTransport cannot be established.
*/
public ProxyInstance(String host, int port, int fetchSize) throws TTransportException {
this(new TFramedTransport(new TSocket(host, port)), fetchSize);
}
public ProxyInstance(TTransport transport) throws TTransportException {
this(transport, DEFAULT_FETCH_SIZE);
}
/**
*
* @param transport
* Thrift transport to communicate with Proxy Server
* @param fetchSize
* the fetch size for BatchScanners. Must be 0 < fetchSize <= 2000. If fetchSize is outside of this range, a warning will be logged and the
* {@link #DEFAULT_FETCH_SIZE} will be used.
* @throws TTransportException
* thrown if the Thrift TTransport cannot be established.
*/
public ProxyInstance(TTransport transport, int fetchSize) throws TTransportException {
if (!transport.isOpen()) {
transport.open();
}
TProtocol protocol = new TCompactProtocol(transport);
client = new SynchronizedProxy(new AccumuloProxy.Client(protocol));
this.transport = transport;
if (fetchSize <= 0 || fetchSize > 2000) {
LoggerFactory.getLogger(ProxyInstance.class).warn(
"Fetch size out of range (0 < fetchSize <= 2000): " + fetchSize + "; using default: " + DEFAULT_FETCH_SIZE);
this.fetchSize = DEFAULT_FETCH_SIZE;
} else {
this.fetchSize = fetchSize;
}
}
public int getBatchScannerFetchSize() {
return fetchSize;
}
public String getRootTabletLocation() {
throw ExceptionFactory.unsupported();
}
public List<String> getMasterLocations() {
throw ExceptionFactory.unsupported();
}
public String getInstanceID() {
throw ExceptionFactory.unsupported();
}
public String getInstanceName() {
throw ExceptionFactory.unsupported();
}
public String getZooKeepers() {
throw ExceptionFactory.unsupported();
}
public int getZooKeepersSessionTimeOut() {
throw ExceptionFactory.unsupported();
}
@Deprecated
public Connector getConnector(String user, byte[] pass) throws AccumuloException, AccumuloSecurityException {
return getConnector(user, new PasswordToken(pass));
}
@Deprecated
public Connector getConnector(String user, ByteBuffer pass) throws AccumuloException, AccumuloSecurityException {
return getConnector(user, new PasswordToken(pass));
}
@Deprecated
public Connector getConnector(String user, CharSequence pass) throws AccumuloException, AccumuloSecurityException {
return getConnector(user, new PasswordToken(pass));
}
@Deprecated
public AccumuloConfiguration getConfiguration() {
throw ExceptionFactory.unsupported();
}
@Deprecated
public void setConfiguration(AccumuloConfiguration conf) {
throw ExceptionFactory.unsupported();
}
public Connector getConnector(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
try {
return new ProxyConnector(this, principal, token);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
AccumuloProxy.Iface getClient() {
return client;
}
public void close() {
// TODO- Neither Instance API nor Connector have a "close" method. But
// we need to close the transport when done. How to handle it? Currently
// clients must cast their Instance as a ProxyInstance and call close,
// *hope* the finalize method is called, or just be a bad citizen and
// not clean up resources on the proxy server.
if (transport != null) {
try {
transport.close();
} finally {
transport = null;
client = null;
}
}
}
@Override
protected void finalize() {
close();
}
/**
* A wrapper class that synchronizes every method in the Iface interface against this object, and then passes the call through to the wrapped Iface delegate.
* Due to the asynchronous nature of Thrift internals, if multiple threads use the same Iface object, the server may receive requests out-of-order and fail.
* This class helps mitigate that risk by ensuring only one thread is ever communicating with the proxy at one time. This incurs a performance hit, but if you
* are using the proxy instance, you probably aren't too concerned about throughput anyway...
*/
private static class SynchronizedProxy implements AccumuloProxy.Iface {
AccumuloProxy.Iface delegate;
SynchronizedProxy(AccumuloProxy.Iface delegate) {
this.delegate = delegate;
}
@Override
public synchronized ByteBuffer login(String principal, Map<String,String> loginProperties)
throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.login(principal, loginProperties);
}
@Override
public synchronized int addConstraint(ByteBuffer login, String tableName, String constraintClassName)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.addConstraint(login, tableName, constraintClassName);
}
@Override
public synchronized void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.addSplits(login, tableName, splits);
}
@Override
public synchronized void attachIterator(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes)
throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.AccumuloException, TableNotFoundException,
TException {
delegate.attachIterator(login, tableName, setting, scopes);
}
@Override
public synchronized void checkIteratorConflicts(ByteBuffer login, String tableName, IteratorSetting setting, Set<IteratorScope> scopes)
throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.AccumuloException, TableNotFoundException,
TException {
delegate.checkIteratorConflicts(login, tableName, setting, scopes);
}
@Override
public synchronized void clearLocatorCache(ByteBuffer login, String tableName) throws TableNotFoundException, TException {
delegate.clearLocatorCache(login, tableName);
}
@Override
public synchronized void cloneTable(ByteBuffer login, String tableName, String newTableName, boolean flush, Map<String,String> propertiesToSet,
Set<String> propertiesToExclude) throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
TableNotFoundException, TableExistsException, TException {
delegate.cloneTable(login, tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
}
@Override
public synchronized void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, List<IteratorSetting> iterators,
boolean flush, boolean wait) throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
org.apache.accumulo.proxy.thrift.AccumuloException, TException {
delegate.compactTable(login, tableName, startRow, endRow, iterators, flush, wait);
}
@Override
public synchronized void cancelCompaction(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
TableNotFoundException, org.apache.accumulo.proxy.thrift.AccumuloException, TException {
delegate.cancelCompaction(login, tableName);
}
@Override
public synchronized void createTable(ByteBuffer login, String tableName, boolean versioningIter, TimeType type)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableExistsException, TException {
delegate.createTable(login, tableName, versioningIter, type);
}
@Override
public synchronized void deleteTable(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.deleteTable(login, tableName);
}
@Override
public synchronized void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.deleteRows(login, tableName, startRow, endRow);
}
@Override
public synchronized void exportTable(ByteBuffer login, String tableName, String exportDir) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.exportTable(login, tableName, exportDir);
}
@Override
public synchronized void flushTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow, boolean wait)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.flushTable(login, tableName, startRow, endRow, wait);
}
@Override
public synchronized List<DiskUsage> getDiskUsage(ByteBuffer login, Set<String> tables) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.getDiskUsage(login, tables);
}
@Override
public synchronized Map<String,Set<String>> getLocalityGroups(ByteBuffer login, String tableName)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.getLocalityGroups(login, tableName);
}
@Override
public synchronized IteratorSetting getIteratorSetting(ByteBuffer login, String tableName, String iteratorName, IteratorScope scope)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.getIteratorSetting(login, tableName, iteratorName, scope);
}
@Override
public synchronized ByteBuffer getMaxRow(ByteBuffer login, String tableName, Set<ByteBuffer> auths, ByteBuffer startRow, boolean startInclusive,
ByteBuffer endRow, boolean endInclusive) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.getMaxRow(login, tableName, auths, startRow, startInclusive, endRow, endInclusive);
}
@Override
public synchronized Map<String,String> getTableProperties(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.getTableProperties(login, tableName);
}
@Override
public synchronized void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime)
throws TableNotFoundException, org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
TException {
delegate.importDirectory(login, tableName, importDir, failureDir, setTime);
}
@Override
public synchronized void importTable(ByteBuffer login, String tableName, String importDir) throws TableExistsException,
org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.importTable(login, tableName, importDir);
}
@Override
public synchronized List<ByteBuffer> listSplits(ByteBuffer login, String tableName, int maxSplits)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.listSplits(login, tableName, maxSplits);
}
@Override
public synchronized Set<String> listTables(ByteBuffer login) throws TException {
return delegate.listTables(login);
}
@Override
public synchronized Map<String,Set<IteratorScope>> listIterators(ByteBuffer login, String tableName)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.listIterators(login, tableName);
}
@Override
public synchronized Map<String,Integer> listConstraints(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.listConstraints(login, tableName);
}
@Override
public synchronized void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.mergeTablets(login, tableName, startRow, endRow);
}
@Override
public synchronized void offlineTable(ByteBuffer login, String tableName, boolean wait) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.offlineTable(login, tableName, wait);
}
@Override
public synchronized void onlineTable(ByteBuffer login, String tableName, boolean wait) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.onlineTable(login, tableName, wait);
}
@Override
public synchronized void removeConstraint(ByteBuffer login, String tableName, int constraint) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
delegate.removeConstraint(login, tableName, constraint);
}
@Override
public synchronized void removeIterator(ByteBuffer login, String tableName, String iterName, Set<IteratorScope> scopes)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.removeIterator(login, tableName, iterName, scopes);
}
@Override
public synchronized void removeTableProperty(ByteBuffer login, String tableName, String property)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.removeTableProperty(login, tableName, property);
}
@Override
public synchronized void renameTable(ByteBuffer login, String oldTableName, String newTableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TableExistsException, TException {
delegate.renameTable(login, oldTableName, newTableName);
}
@Override
public synchronized void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groups)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.setLocalityGroups(login, tableName, groups);
}
@Override
public synchronized void setTableProperty(ByteBuffer login, String tableName, String property, String value)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.setTableProperty(login, tableName, property, value);
}
@Override
public synchronized Set<Range> splitRangeByTablets(ByteBuffer login, String tableName, Range range, int maxSplits)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.splitRangeByTablets(login, tableName, range, maxSplits);
}
@Override
public synchronized boolean tableExists(ByteBuffer login, String tableName) throws TException {
return delegate.tableExists(login, tableName);
}
@Override
public synchronized Map<String,String> tableIdMap(ByteBuffer login) throws TException {
return delegate.tableIdMap(login);
}
@Override
public synchronized boolean testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.testClassLoad(login, className, asTypeName);
}
@Override
public synchronized void pingTabletServer(ByteBuffer login, String tserver) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.pingTabletServer(login, tserver);
}
@Override
public synchronized List<ActiveScan> getActiveScans(ByteBuffer login, String tserver) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.getActiveScans(login, tserver);
}
@Override
public synchronized List<ActiveCompaction> getActiveCompactions(ByteBuffer login, String tserver)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.getActiveCompactions(login, tserver);
}
@Override
public synchronized Map<String,String> getSiteConfiguration(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.getSiteConfiguration(login);
}
@Override
public synchronized Map<String,String> getSystemConfiguration(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.getSystemConfiguration(login);
}
@Override
public synchronized List<String> getTabletServers(ByteBuffer login) throws TException {
return delegate.getTabletServers(login);
}
@Override
public synchronized void removeProperty(ByteBuffer login, String property) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.removeProperty(login, property);
}
@Override
public synchronized void setProperty(ByteBuffer login, String property, String value) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.setProperty(login, property, value);
}
@Override
public synchronized boolean testClassLoad(ByteBuffer login, String className, String asTypeName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.testClassLoad(login, className, asTypeName);
}
@Override
public synchronized boolean authenticateUser(ByteBuffer login, String user, Map<String,String> properties)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.authenticateUser(login, user, properties);
}
@Override
public synchronized void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.changeUserAuthorizations(login, user, authorizations);
}
@Override
public synchronized void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.changeLocalUserPassword(login, user, password);
}
@Override
public synchronized void createLocalUser(ByteBuffer login, String user, ByteBuffer password) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.createLocalUser(login, user, password);
}
@Override
public synchronized void dropLocalUser(ByteBuffer login, String user) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.dropLocalUser(login, user);
}
@Override
public synchronized List<ByteBuffer> getUserAuthorizations(ByteBuffer login, String user) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.getUserAuthorizations(login, user);
}
@Override
public synchronized void grantSystemPermission(ByteBuffer login, String user, SystemPermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.grantSystemPermission(login, user, perm);
}
@Override
public synchronized void grantTablePermission(ByteBuffer login, String user, String table, TablePermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.grantTablePermission(login, user, table, perm);
}
@Override
public synchronized boolean hasSystemPermission(ByteBuffer login, String user, SystemPermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.hasSystemPermission(login, user, perm);
}
@Override
public synchronized boolean hasTablePermission(ByteBuffer login, String user, String table, TablePermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.hasTablePermission(login, user, table, perm);
}
@Override
public synchronized Set<String> listLocalUsers(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.listLocalUsers(login);
}
@Override
public synchronized void revokeSystemPermission(ByteBuffer login, String user, SystemPermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
delegate.revokeSystemPermission(login, user, perm);
}
@Override
public synchronized void revokeTablePermission(ByteBuffer login, String user, String table, TablePermission perm)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
delegate.revokeTablePermission(login, user, table, perm);
}
@Override
public synchronized String createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions options)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.createBatchScanner(login, tableName, options);
}
@Override
public synchronized String createScanner(ByteBuffer login, String tableName, ScanOptions options)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.createScanner(login, tableName, options);
}
@Override
public synchronized boolean hasNext(String scanner) throws UnknownScanner, TException {
return delegate.hasNext(scanner);
}
@Override
public synchronized KeyValueAndPeek nextEntry(String scanner) throws NoMoreEntriesException, UnknownScanner,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.nextEntry(scanner);
}
@Override
public synchronized ScanResult nextK(String scanner, int k) throws NoMoreEntriesException, UnknownScanner,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.nextK(scanner, k);
}
@Override
public synchronized void closeScanner(String scanner) throws UnknownScanner, TException {
delegate.closeScanner(scanner);
}
@Override
public synchronized void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
MutationsRejectedException, TException {
delegate.updateAndFlush(login, tableName, cells);
}
@Override
public synchronized String createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws org.apache.accumulo.proxy.thrift.AccumuloException,
org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException, TException {
return delegate.createWriter(login, tableName, opts);
}
@Override
public synchronized void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells) throws TException {
delegate.update(writer, cells);
}
@Override
public synchronized void flush(String writer) throws UnknownWriter, MutationsRejectedException, TException {
delegate.flush(writer);
}
@Override
public synchronized void closeWriter(String writer) throws UnknownWriter, MutationsRejectedException, TException {
delegate.closeWriter(writer);
}
@Override
public synchronized ConditionalStatus updateRowConditionally(ByteBuffer login, String tableName, ByteBuffer row, ConditionalUpdates updates)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.updateRowConditionally(login, tableName, row, updates);
}
@Override
public synchronized String createConditionalWriter(ByteBuffer login, String tableName, ConditionalWriterOptions options)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TableNotFoundException,
TException {
return delegate.createConditionalWriter(login, tableName, options);
}
@Override
public synchronized Map<ByteBuffer,ConditionalStatus> updateRowsConditionally(String conditionalWriter, Map<ByteBuffer,ConditionalUpdates> updates)
throws UnknownWriter, org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
return delegate.updateRowsConditionally(conditionalWriter, updates);
}
@Override
public synchronized void closeConditionalWriter(String conditionalWriter) throws TException {
delegate.closeConditionalWriter(conditionalWriter);
}
@Override
public synchronized Range getRowRange(ByteBuffer row) throws TException {
return delegate.getRowRange(row);
}
@Override
public synchronized Key getFollowing(Key key, PartialKey part) throws TException {
return delegate.getFollowing(key, part);
}
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
/**
* Error throws when an unrecoverable condition has been reached.
*/
public class ProxyInstanceError extends Error {
private static final long serialVersionUID = -6542283312575106269L;
/**
* Creates a new error with the given cause.
*
* @param cause
* the root cause of this error
*/
public ProxyInstanceError(Throwable cause) {
super(cause);
}
public ProxyInstanceError(String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,114 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.admin.ActiveCompaction;
import org.apache.accumulo.core.client.admin.ActiveScan;
import org.apache.accumulo.core.client.admin.InstanceOperations;
import org.apache.thrift.TException;
/**
* Provides a pass through for InstaceOperations to a proxy server.
*/
class ProxyInstanceOperations implements InstanceOperations {
ProxyConnector connector;
ByteBuffer token;
ProxyInstanceOperations(ProxyConnector connector, ByteBuffer token) {
this.connector = connector;
this.token = token;
}
public void setProperty(String property, String value) throws AccumuloException, AccumuloSecurityException {
try {
connector.getClient().setProperty(token, property, value);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void removeProperty(String property) throws AccumuloException, AccumuloSecurityException {
try {
connector.getClient().removeProperty(token, property);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Map<String,String> getSystemConfiguration() throws AccumuloException, AccumuloSecurityException {
try {
return connector.getClient().getSystemConfiguration(token);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Map<String,String> getSiteConfiguration() throws AccumuloException, AccumuloSecurityException {
try {
return connector.getClient().getSiteConfiguration(token);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public List<String> getTabletServers() {
try {
return connector.getClient().getTabletServers(token);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public List<ActiveScan> getActiveScans(String tserver) throws AccumuloException, AccumuloSecurityException {
try {
return ThriftHelper.fromThriftActiveScans(connector.getClient().getActiveScans(token, tserver));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public List<ActiveCompaction> getActiveCompactions(String tserver) throws AccumuloException, AccumuloSecurityException {
try {
return ThriftHelper.fromThriftActiveCompactions(connector.tableOperations().tableIdMap(), connector.getClient().getActiveCompactions(token, tserver));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void ping(String tserver) throws AccumuloException {
try {
connector.getClient().pingTabletServer(token, tserver);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public boolean testClassLoad(String className, String asTypeName) throws AccumuloException, AccumuloSecurityException {
try {
return connector.getClient().testClassLoad(token, className, asTypeName);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
}

View File

@@ -0,0 +1,215 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.BatchWriterConfig;
import org.apache.accumulo.core.client.MultiTableBatchWriter;
import org.apache.accumulo.core.client.MutationsRejectedException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.security.SecurityErrorCode;
import org.apache.accumulo.core.data.ConstraintViolationSummary;
import org.apache.accumulo.core.data.KeyExtent;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.proxy.thrift.UnknownWriter;
import org.apache.accumulo.proxy.thrift.WriterOptions;
import org.apache.thrift.TException;
import org.slf4j.LoggerFactory;
/**
* Implementation of a MultiTableBatchWriter for the Proxy Server. The ProxyServer API does not actually expose a MultiTableBatchWriter. Instead, we will "fake"
* it by managing our own internal list of "regular" ProxyBatchWriters in this class, one for each table requested.
*/
class ProxyMultiTableBatchWriter implements MultiTableBatchWriter {
ProxyConnector connector;
ByteBuffer token;
BatchWriterConfig config;
MutationBuffer buffer;
Map<String,MultiProxyBatchWriter> writers;
ProxyMultiTableBatchWriter(ProxyConnector connector, ByteBuffer token, BatchWriterConfig config) {
this.connector = connector;
this.token = token;
this.config = config;
writers = new HashMap<String,MultiProxyBatchWriter>();
buffer = new MutationBuffer(connector, config);
}
private void checkClosed() throws IllegalStateException {
if (isClosed()) {
throw new IllegalStateException("Closed.");
}
}
public BatchWriter getBatchWriter(String table) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
checkClosed();
MultiProxyBatchWriter pbw = writers.get(table);
if (pbw == null) {
try {
pbw = new MultiProxyBatchWriter(connector, token, table, buffer);
writers.put(table, pbw);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
return pbw;
}
public void flush() throws MutationsRejectedException {
flushOrClose(false);
}
public void close() throws MutationsRejectedException {
flushOrClose(true);
}
private void flushOrClose(boolean close) throws MutationsRejectedException {
checkClosed();
buffer.flush();
List<MutationsRejectedException> exceptions = null;
try {
try {
for (MultiProxyBatchWriter pbw : writers.values()) {
if (close) {
pbw.multiClose();
} else {
pbw.multiFlush();
}
}
} catch (UnknownWriter e) {
throw ExceptionFactory.runtimeException(e);
} catch (org.apache.accumulo.proxy.thrift.MutationsRejectedException e) {
if (exceptions == null) {
exceptions = new ArrayList<MutationsRejectedException>();
}
exceptions.add(ThriftHelper.fromThrift(e, connector.getInstance()));
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
writers.clear();
} finally {
writers = null;
}
checkExceptions(exceptions);
}
private void checkExceptions(List<MutationsRejectedException> mres) throws MutationsRejectedException {
if (mres == null || mres.isEmpty()) {
return;
}
List<ConstraintViolationSummary> cvsList = new LinkedList<ConstraintViolationSummary>();
HashMap<KeyExtent,Set<SecurityErrorCode>> map = new HashMap<KeyExtent,Set<SecurityErrorCode>>();
Collection<String> serverSideErrors = new LinkedList<String>();
int unknownErrors = 0;
for (MutationsRejectedException mre : mres) {
cvsList.addAll(mre.getConstraintViolationSummaries());
map.putAll(mre.getAuthorizationFailuresMap());
serverSideErrors.addAll(mre.getErrorServers());
unknownErrors += mre.getUnknownExceptions();
}
throw new MutationsRejectedException(null, cvsList, map, serverSideErrors, unknownErrors, null);
}
public boolean isClosed() {
return writers == null;
}
@Override
protected void finalize() {
if (!isClosed()) {
LoggerFactory.getLogger(ProxyMultiTableBatchWriter.class).warn(
"ProxyMultiTableBatchWriter" + " in finalize but not closed; " + "you forgot to close a MultiTableBatchWriter!");
try {
close();
} catch (MutationsRejectedException mre) {
LoggerFactory.getLogger(ProxyBatchScanner.class).warn("Problem closing ProxyMultiTableBatchWriter.", mre);
}
}
}
private class MultiProxyBatchWriter implements BatchWriter {
ProxyConnector connector;
String writerId;
MutationBuffer buffer;
MultiProxyBatchWriter(ProxyConnector connector, ByteBuffer token, String table, MutationBuffer buffer)
throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
this.connector = connector;
this.buffer = buffer;
writerId = connector.getClient().createWriter(token, table, new WriterOptions());
}
@Override
public void addMutation(Mutation m) throws MutationsRejectedException {
checkClosed();
buffer.addMutation(writerId, m);
}
@Override
public void addMutations(Iterable<Mutation> iterable) throws MutationsRejectedException {
for (Mutation m : iterable) {
addMutation(m);
}
}
@Override
public void flush() throws MutationsRejectedException {
throw new RuntimeException("Cannot flush BatchWriter created by MultiTableBatchWriter directly; " + "flush MultiTableBatchWriter instead.");
}
@Override
public void close() throws MutationsRejectedException {
throw new RuntimeException("Cannot close BatchWriter created by MultiTableBatchWriter directly; " + "close MultiTableBatchWriter instead.");
}
void multiClose() throws UnknownWriter, org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
connector.getClient().closeWriter(writerId);
}
void multiFlush() throws UnknownWriter, org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
connector.getClient().flush(writerId);
}
}
}

View File

@@ -0,0 +1,172 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.proxy.thrift.ScanColumn;
import org.apache.accumulo.proxy.thrift.ScanOptions;
import org.apache.thrift.TException;
import org.slf4j.LoggerFactory;
class ProxyScanner extends AbstractProxyScanner implements Scanner {
protected ScanOptions options;
int batchSize = 50;
ProxyScanner(ProxyConnector connector, ByteBuffer token, String tableName, Authorizations auths) {
super(connector, token, tableName);
options = new ScanOptions();
for (ByteBuffer auth : auths.getAuthorizationsBB()) {
options.addToAuthorizations(auth);
}
}
public void addScanIterator(IteratorSetting cfg) {
options.addToIterators(ThriftHelper.toThrift(cfg));
}
public void removeScanIterator(String iteratorName) {
for (org.apache.accumulo.proxy.thrift.IteratorSetting is : options.iterators) {
if (is.getName().equals(iteratorName)) {
options.iterators.remove(is);
break;
}
}
}
public void updateScanIteratorOption(String iteratorName, String key, String value) {
for (org.apache.accumulo.proxy.thrift.IteratorSetting is : options.iterators) {
if (is.getName().equals(iteratorName)) {
is.putToProperties(key, value);
}
}
}
@Override
protected void addToFetchOptions(ScanColumn col) {
options.addToColumns(col);
}
public void clearColumns() {
if (options.getColumns() != null) {
options.getColumns().clear();
}
}
public void clearScanIterators() {
if (options.getIterators() != null) {
options.getIterators().clear();
}
}
public Iterator<Entry<Key,Value>> iterator() {
// TODO Close if older instance open?
try {
scannerId = connector.getClient().createScanner(token, tableName, options);
// TODO Someone needs to close this scannerID!
return new ScannerIterator(scannerId, connector, batchSize);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public void setTimeout(long timeOut, TimeUnit timeUnit) {
throw ExceptionFactory.unsupported();
}
public long getTimeout(TimeUnit timeUnit) {
throw ExceptionFactory.unsupported();
}
public void close() {
try {
connector.getClient().closeScanner(scannerId);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
} finally {
scannerId = null;
}
}
@Override
protected void finalize() {
if (scannerId != null) {
close();
LoggerFactory.getLogger(ProxyBatchScanner.class).warn("Scanner " + scannerId + " in finalize but not closed; " + "you forgot to close a scanner!");
}
}
public void setRange(Range range) {
if (range == null) {
options.unsetRange();
} else {
options.setRange(ThriftHelper.toThrift(range));
}
}
public Range getRange() {
return ThriftHelper.fromThrift(options.getRange());
}
public void setBatchSize(int size) {
if (size < 1) {
throw new IllegalArgumentException("Batch size must be > 0; provided " + size);
}
this.batchSize = size;
}
public int getBatchSize() {
return batchSize;
}
public void enableIsolation() {
throw ExceptionFactory.unsupported();
}
public void disableIsolation() {
throw ExceptionFactory.unsupported();
}
public long getReadaheadThreshold() {
throw ExceptionFactory.unsupported();
}
public void setReadaheadThreshold(long batches) {
throw ExceptionFactory.unsupported();
}
@Deprecated
public void setTimeOut(int timeOut) {
setTimeout(timeOut, TimeUnit.SECONDS);
}
@Deprecated
public int getTimeOut() {
return (int) this.getTimeout(TimeUnit.SECONDS);
}
}

View File

@@ -0,0 +1,209 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import static edu.jhuapl.accumulo.proxy.ThriftHelper.UTF8;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.admin.SecurityOperations;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.NamespacePermission;
import org.apache.accumulo.core.security.SystemPermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.thrift.TException;
/**
* Implements SecurityOperations as a pass through to a proxy server.
*/
class ProxySecurityOperations implements SecurityOperations {
AccumuloProxy.Iface client;
ByteBuffer token;
ProxySecurityOperations(ProxyConnector connector, ByteBuffer token) {
this.client = connector.getClient();
this.token = token;
}
@Deprecated
public void createUser(String user, byte[] password, Authorizations authorizations) throws AccumuloException, AccumuloSecurityException {
createLocalUser(user, new PasswordToken(password));
changeUserAuthorizations(user, authorizations);
}
public void createLocalUser(String principal, PasswordToken password) throws AccumuloException, AccumuloSecurityException {
try {
client.createLocalUser(token, principal, ByteBuffer.wrap(password.getPassword()));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
@Deprecated
public void dropUser(String user) throws AccumuloException, AccumuloSecurityException {
dropLocalUser(user);
}
public void dropLocalUser(String principal) throws AccumuloException, AccumuloSecurityException {
try {
client.dropLocalUser(token, principal);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
@Deprecated
public boolean authenticateUser(String user, byte[] password) throws AccumuloException, AccumuloSecurityException {
return this.authenticateUser(user, new PasswordToken(password));
}
public boolean authenticateUser(String principal, AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
if (!(token instanceof PasswordToken)) {
throw ExceptionFactory.notYetImplemented();
}
PasswordToken passwd = (PasswordToken) token;
try {
Map<String,String> properties = new HashMap<String,String>();
properties.put("password", new String(passwd.getPassword(), UTF8));
return client.authenticateUser(this.token, principal, properties);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
@Deprecated
public void changeUserPassword(String user, byte[] password) throws AccumuloException, AccumuloSecurityException {
changeLocalUserPassword(user, new PasswordToken(password));
}
public void changeLocalUserPassword(String principal, PasswordToken token) throws AccumuloException, AccumuloSecurityException {
try {
client.changeLocalUserPassword(this.token, principal, ByteBuffer.wrap(token.getPassword()));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void changeUserAuthorizations(String principal, Authorizations authorizations) throws AccumuloException, AccumuloSecurityException {
try {
client.changeUserAuthorizations(token, principal, new HashSet<ByteBuffer>(authorizations.getAuthorizationsBB()));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Authorizations getUserAuthorizations(String principal) throws AccumuloException, AccumuloSecurityException {
try {
return new Authorizations(client.getUserAuthorizations(token, principal));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
/**
* ProxyAPI specifies AccumuloException and AccumuloSecurityException may be thrown. The IllegalArgumentException may be thrown if the
* {@link ThriftHelper#convertEnum(Enum, Class)} fails because the Java and Thrift SystemPermission no longer match; this should never happen.
*/
public boolean hasSystemPermission(String principal, SystemPermission perm) throws AccumuloException, AccumuloSecurityException, InternalError {
try {
return client.hasSystemPermission(token, principal, ThriftHelper.convertEnum(perm, org.apache.accumulo.proxy.thrift.SystemPermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public boolean hasTablePermission(String principal, String table, TablePermission perm) throws AccumuloException, AccumuloSecurityException {
try {
return client.hasTablePermission(token, principal, table, ThriftHelper.convertEnum(perm, org.apache.accumulo.proxy.thrift.TablePermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public boolean hasNamespacePermission(String principal, String namespace, NamespacePermission perm) throws AccumuloException, AccumuloSecurityException {
throw ExceptionFactory.unsupported();
}
public void grantSystemPermission(String principal, SystemPermission permission) throws AccumuloException, AccumuloSecurityException {
try {
client.grantSystemPermission(token, principal, ThriftHelper.convertEnum(permission, org.apache.accumulo.proxy.thrift.SystemPermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void grantTablePermission(String principal, String table, TablePermission permission) throws AccumuloException, AccumuloSecurityException {
try {
client.grantTablePermission(token, principal, table, ThriftHelper.convertEnum(permission, org.apache.accumulo.proxy.thrift.TablePermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void grantNamespacePermission(String principal, String namespace, NamespacePermission permission) throws AccumuloException, AccumuloSecurityException {
throw ExceptionFactory.unsupported();
}
public void revokeSystemPermission(String principal, SystemPermission permission) throws AccumuloException, AccumuloSecurityException {
try {
client.revokeSystemPermission(token, principal, ThriftHelper.convertEnum(permission, org.apache.accumulo.proxy.thrift.SystemPermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void revokeTablePermission(String principal, String table, TablePermission permission) throws AccumuloException, AccumuloSecurityException {
try {
client.revokeTablePermission(token, principal, table, ThriftHelper.convertEnum(permission, org.apache.accumulo.proxy.thrift.TablePermission.class));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void revokeNamespacePermission(String principal, String namespace, NamespacePermission permission) throws AccumuloException, AccumuloSecurityException {
throw ExceptionFactory.unsupported();
}
@Deprecated
public Set<String> listUsers() throws AccumuloException, AccumuloSecurityException {
return listLocalUsers();
}
public Set<String> listLocalUsers() throws AccumuloException, AccumuloSecurityException {
try {
return client.listLocalUsers(token);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
}

View File

@@ -0,0 +1,528 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
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.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.DiskUsage;
import org.apache.accumulo.core.client.admin.TableOperations;
import org.apache.accumulo.core.client.admin.TimeType;
import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.proxy.thrift.AccumuloProxy;
import org.apache.hadoop.io.Text;
import org.apache.thrift.TException;
/**
* Implements TableOperations as a pass through to a proxy server.
*/
class ProxyTableOperations implements TableOperations {
ProxyConnector connector;
AccumuloProxy.Iface client;
ByteBuffer token;
ProxyTableOperations(ProxyConnector connector, ByteBuffer token) {
this.connector = connector;
this.client = connector.getClient();
this.token = token;
}
public SortedSet<String> list() {
try {
return new TreeSet<String>(client.listTables(token));
} catch (TException te) {
throw ExceptionFactory.runtimeException(te);
}
}
public boolean exists(String tableName) {
return list().contains(tableName);
}
public void create(String tableName) throws AccumuloException, AccumuloSecurityException, TableExistsException {
create(tableName, true);
}
public void create(String tableName, boolean limitVersion) throws AccumuloException, AccumuloSecurityException, TableExistsException {
create(tableName, limitVersion, TimeType.MILLIS);
}
public void create(String tableName, boolean versioningIter, TimeType timeType) throws AccumuloException, AccumuloSecurityException, TableExistsException {
org.apache.accumulo.proxy.thrift.TimeType ttype = org.apache.accumulo.proxy.thrift.TimeType.valueOf(timeType.toString());
try {
client.createTable(token, tableName, versioningIter, ttype);
} catch (org.apache.accumulo.proxy.thrift.TableExistsException tee) {
throw ExceptionFactory.tableExistsException(tableName, tee);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void importTable(String tableName, String importDir) throws TableExistsException, AccumuloException, AccumuloSecurityException {
try {
client.importTable(token, tableName, importDir);
} catch (org.apache.accumulo.proxy.thrift.TableExistsException tee) {
throw ExceptionFactory.tableExistsException(tableName, tee);
} catch (TException te) {
throw ExceptionFactory.accumuloException(te);
}
}
public void exportTable(String tableName, String exportDir) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
try {
client.exportTable(token, tableName, exportDir);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException te) {
throw ExceptionFactory.accumuloException(te);
}
}
public void addSplits(String tableName, SortedSet<Text> partitionKeys) throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
Set<ByteBuffer> tsplits = new TreeSet<ByteBuffer>();
for (Text key : partitionKeys) {
tsplits.add(ByteBuffer.wrap(key.getBytes()));
}
try {
client.addSplits(token, tableName, tsplits);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException te) {
throw ExceptionFactory.accumuloException(te);
}
}
@Deprecated
public Collection<Text> getSplits(String tableName) throws TableNotFoundException {
try {
return listSplits(tableName);
} catch (AccumuloSecurityException e) {
throw ExceptionFactory.runtimeException(e);
} catch (AccumuloException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Collection<Text> listSplits(String tableName) throws TableNotFoundException, AccumuloSecurityException, AccumuloException {
return listSplits(tableName, Integer.MAX_VALUE);
}
@Deprecated
public Collection<Text> getSplits(String tableName, int maxSplits) throws TableNotFoundException {
try {
return listSplits(tableName, maxSplits);
} catch (AccumuloSecurityException e) {
throw ExceptionFactory.runtimeException(e);
} catch (AccumuloException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Collection<Text> listSplits(String tableName, int maxSplits) throws TableNotFoundException, AccumuloSecurityException, AccumuloException {
try {
List<ByteBuffer> list = client.listSplits(token, tableName, maxSplits);
List<Text> text = new ArrayList<Text>(list.size());
for (ByteBuffer bb : list) {
text.add(new Text(bb.array()));
}
return text;
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException te) {
throw ExceptionFactory.accumuloException(te);
}
}
public Text getMaxRow(String tableName, Authorizations auths, Text startRow, boolean startInclusive, Text endRow, boolean endInclusive)
throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
try {
ByteBuffer answer = client.getMaxRow(token, tableName, new HashSet<ByteBuffer>(auths.getAuthorizationsBB()), ThriftHelper.toByteBuffer(startRow),
startInclusive, ThriftHelper.toByteBuffer(endRow), endInclusive);
return new Text(answer.array());
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void merge(String tableName, Text start, Text end) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
client.mergeTablets(token, tableName, ThriftHelper.toByteBuffer(start), ThriftHelper.toByteBuffer(end));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void deleteRows(String tableName, Text start, Text end) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
client.deleteRows(token, tableName, ThriftHelper.toByteBuffer(start), ThriftHelper.toByteBuffer(end));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void compact(String tableName, Text start, Text end, boolean flush, boolean wait) throws AccumuloSecurityException, TableNotFoundException,
AccumuloException {
compact(tableName, start, end, null, flush, wait);
}
public void compact(String tableName, Text start, Text end, List<IteratorSetting> iterators, boolean flush, boolean wait) throws AccumuloSecurityException,
TableNotFoundException, AccumuloException {
try {
client.compactTable(token, tableName, ThriftHelper.toByteBuffer(start), ThriftHelper.toByteBuffer(end), ThriftHelper.toThriftIteratorSettings(iterators),
flush, wait);
} catch (org.apache.accumulo.proxy.thrift.AccumuloSecurityException e) {
throw new AccumuloSecurityException(connector.whoami(), SecurityErrorCode.DEFAULT_SECURITY_ERROR, "", e);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (org.apache.accumulo.proxy.thrift.AccumuloException e) {
throw ExceptionFactory.accumuloException(e);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void cancelCompaction(String tableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException {
try {
client.cancelCompaction(token, tableName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void delete(String tableName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
client.deleteTable(token, tableName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void clone(String srcTableName, String newTableName, boolean flush, Map<String,String> propertiesToSet, Set<String> propertiesToExclude)
throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException {
try {
client.cloneTable(token, srcTableName, newTableName, flush, propertiesToSet, propertiesToExclude);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(srcTableName, tnfe);
} catch (org.apache.accumulo.proxy.thrift.TableExistsException tee) {
throw ExceptionFactory.tableExistsException(newTableName, tee);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void rename(String oldTableName, String newTableName) throws AccumuloSecurityException, TableNotFoundException, AccumuloException,
TableExistsException {
try {
client.renameTable(token, oldTableName, newTableName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(oldTableName, tnfe);
} catch (org.apache.accumulo.proxy.thrift.TableExistsException tee) {
throw ExceptionFactory.tableExistsException(newTableName, tee);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
@Deprecated
public void flush(String tableName) throws AccumuloException, AccumuloSecurityException {
try {
flush(tableName, null, null, true);
} catch (TableNotFoundException tnfe) {
throw ExceptionFactory.accumuloException(tnfe);
}
}
public void flush(String tableName, Text start, Text end, boolean wait) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
client.flushTable(token, tableName, ThriftHelper.toByteBuffer(start), ThriftHelper.toByteBuffer(end), wait);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void setProperty(String tableName, String property, String value) throws AccumuloException, AccumuloSecurityException {
try {
client.setProperty(token, property, value);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void removeProperty(String tableName, String property) throws AccumuloException, AccumuloSecurityException {
try {
client.removeProperty(token, property);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Iterable<Entry<String,String>> getProperties(String tableName) throws AccumuloException, TableNotFoundException {
try {
return client.getTableProperties(token, tableName).entrySet();
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void setLocalityGroups(String tableName, Map<String,Set<Text>> groups) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
Map<String,Set<String>> tgroups = new HashMap<String,Set<String>>();
for (Entry<String,Set<Text>> entry : groups.entrySet()) {
Set<String> tset = new HashSet<String>();
tgroups.put(entry.getKey(), tset);
for (Text t : entry.getValue()) {
tset.add(t.toString());
}
}
client.setLocalityGroups(token, tableName, tgroups);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Map<String,Set<Text>> getLocalityGroups(String tableName) throws AccumuloException, TableNotFoundException {
try {
Map<String,Set<String>> tgroups = client.getLocalityGroups(token, tableName);
Map<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
for (Entry<String,Set<String>> tentry : tgroups.entrySet()) {
Set<Text> set = new HashSet<Text>();
groups.put(tentry.getKey(), set);
for (String t : tentry.getValue()) {
set.add(new Text(t));
}
}
return groups;
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Set<Range> splitRangeByTablets(String tableName, Range range, int maxSplits) throws AccumuloException, AccumuloSecurityException,
TableNotFoundException {
try {
return ThriftHelper.fromThriftRanges(client.splitRangeByTablets(token, tableName, ThriftHelper.toThrift(range), maxSplits));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void importDirectory(String tableName, String dir, String failureDir, boolean setTime) throws TableNotFoundException, IOException, AccumuloException,
AccumuloSecurityException {
try {
client.importDirectory(token, tableName, dir, failureDir, setTime);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void offline(String tableName) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
offline(tableName, true);
}
public void offline(String tableName, boolean wait) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
try {
client.offlineTable(token, tableName, wait);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void online(String tableName) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
online(tableName, true);
}
public void online(String tableName, boolean wait) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
try {
client.onlineTable(token, tableName, wait);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void clearLocatorCache(String tableName) throws TableNotFoundException {
try {
client.clearLocatorCache(token, tableName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Map<String,String> tableIdMap() {
try {
return client.tableIdMap(token);
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public void attachIterator(String tableName, IteratorSetting setting) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
attachIterator(tableName, setting, null);
}
public void attachIterator(String tableName, IteratorSetting setting, EnumSet<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException,
TableNotFoundException {
try {
client.attachIterator(token, tableName, ThriftHelper.toThrift(setting), ThriftHelper.toThrift(scopes));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void removeIterator(String tableName, String name, EnumSet<IteratorScope> scopes) throws AccumuloSecurityException, AccumuloException,
TableNotFoundException {
try {
client.removeIterator(token, tableName, name, ThriftHelper.toThrift(scopes));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public IteratorSetting getIteratorSetting(String tableName, String name, IteratorScope scope) throws AccumuloSecurityException, AccumuloException,
TableNotFoundException {
try {
return ThriftHelper.fromThrift(client.getIteratorSetting(token, tableName, name, ThriftHelper.toThrift(scope)));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Map<String,EnumSet<IteratorScope>> listIterators(String tableName) throws AccumuloSecurityException, AccumuloException, TableNotFoundException {
try {
return ThriftHelper.fromThrift(client.listIterators(token, tableName));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void checkIteratorConflicts(String tableName, IteratorSetting setting, EnumSet<IteratorScope> scopes) throws AccumuloException, TableNotFoundException {
try {
client.checkIteratorConflicts(token, tableName, ThriftHelper.toThrift(setting), ThriftHelper.toThrift(scopes));
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public int addConstraint(String tableName, String constraintClassName) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
return client.addConstraint(token, tableName, constraintClassName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public void removeConstraint(String tableName, int constraint) throws AccumuloException, AccumuloSecurityException {
try {
client.removeConstraint(token, tableName, constraint);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public Map<String,Integer> listConstraints(String tableName) throws AccumuloException, TableNotFoundException {
try {
return client.listConstraints(token, tableName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public List<DiskUsage> getDiskUsage(Set<String> tables) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
try {
return new ArrayList<DiskUsage>(ThriftHelper.fromThriftDiskUsage(client.getDiskUsage(token, tables)));
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
public boolean testClassLoad(String tableName, String className, String asTypeName) throws AccumuloException, AccumuloSecurityException,
TableNotFoundException {
try {
return client.testClassLoad(token, className, asTypeName);
} catch (org.apache.accumulo.proxy.thrift.TableNotFoundException tnfe) {
throw ExceptionFactory.tableNotFoundException(tableName, tnfe);
} catch (TException e) {
throw ExceptionFactory.accumuloException(e);
}
}
}

View File

@@ -0,0 +1,99 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.KeyValue;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.proxy.thrift.ScanResult;
import org.apache.thrift.TException;
/**
* Givens a scanner id and connection to a proxy server, creates an iterator for the KV provided for the scanner id from the proxy.
*/
class ScannerIterator implements Iterator<Entry<Key,Value>> {
String id;
ProxyConnector connector;
int fetchSize;
private boolean hasMore;
private Iterator<org.apache.accumulo.proxy.thrift.KeyValue> results;
ScannerIterator(String id, ProxyConnector connector, int fetchSize) {
this.id = id;
this.connector = connector;
this.fetchSize = fetchSize;
// setup to make the class look for "more" data on 1st pass...
this.results = Collections.emptyListIterator();
this.hasMore = true;
}
public boolean hasNext() {
try {
while (!results.hasNext()) {
// either first pass or we are at the end of the current batch.
if (!hasMore) {
// last check told us we were done at the end of this;
// hasMore is initialized to true to ensure this does not
// fail on 1st call
return false;
}
ScanResult sr = connector.getClient().nextK(id, fetchSize);
results = sr.getResultsIterator();
hasMore = sr.isMore();
// We cannot return true from this method unless there is at
// least one result in the results list. There is a possibility
// that the results are empty now, but hasMore is still true.
// Therefore, we iterate until either hasMore is false (we are
// done!) or results.hasNext() is true
}
// if we got here, there is something in results
return true;
} catch (TException e) {
throw ExceptionFactory.runtimeException(e);
}
}
public Entry<Key,Value> next() {
if (!hasNext()) {
// need to call hasNext to make sure results is setup correctly;
// might as well use the return to throw our own exception here
// instead of waiting for the call to results.next() to generate
// it...
throw new NoSuchElementException();
}
org.apache.accumulo.proxy.thrift.KeyValue kv = results.next();
org.apache.accumulo.proxy.thrift.Key k = kv.getKey();
Key key = new Key(k.getRow(), k.getColFamily(), k.getColQualifier(), k.getColVisibility(), k.getTimestamp());
return new KeyValue(key, kv.getValue());
}
public void remove() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,489 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.MutationsRejectedException;
import org.apache.accumulo.core.client.admin.ActiveCompaction;
import org.apache.accumulo.core.client.admin.ActiveCompaction.CompactionReason;
import org.apache.accumulo.core.client.admin.ActiveCompaction.CompactionType;
import org.apache.accumulo.core.client.admin.ActiveScan;
import org.apache.accumulo.core.client.admin.DiskUsage;
import org.apache.accumulo.core.client.admin.ScanState;
import org.apache.accumulo.core.client.admin.ScanType;
import org.apache.accumulo.core.data.Column;
import org.apache.accumulo.core.data.ColumnUpdate;
import org.apache.accumulo.core.data.Condition;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.KeyExtent;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.hadoop.io.Text;
/**
* Utility class to translate between Accumulo<->Thrift objects.
*
*/
final class ThriftHelper {
/**
* UTF-8 charset that can be used to convert String to/from byte arrays.
*/
static final Charset UTF8 = Charset.forName("UTF-8");
/**
* As a utility should not be instantiated.
*/
private ThriftHelper() {
}
public static Map<String,EnumSet<IteratorScope>> fromThrift(Map<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> tmap) {
if (tmap == null) {
return null;
}
Map<String,EnumSet<IteratorScope>> map = new HashMap<String,EnumSet<IteratorScope>>();
for (Entry<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> entry : tmap.entrySet()) {
map.put(entry.getKey(), fromThrift(entry.getValue()));
}
return map;
}
public static Set<org.apache.accumulo.proxy.thrift.IteratorScope> toThrift(EnumSet<IteratorScope> scopes) {
if (scopes == null) {
return null;
}
HashSet<org.apache.accumulo.proxy.thrift.IteratorScope> set = new HashSet<org.apache.accumulo.proxy.thrift.IteratorScope>();
for (IteratorScope is : scopes) {
set.add(toThrift(is));
}
return set;
}
public static EnumSet<IteratorScope> fromThrift(Set<org.apache.accumulo.proxy.thrift.IteratorScope> tscopes) {
if (tscopes == null) {
return null;
}
LinkedList<IteratorScope> list = new LinkedList<IteratorScope>();
for (org.apache.accumulo.proxy.thrift.IteratorScope tis : tscopes) {
list.add(fromThrift(tis));
}
return EnumSet.copyOf(list);
}
public static org.apache.accumulo.proxy.thrift.IteratorScope toThrift(IteratorScope is) {
// we can't just use the enum values, since thrift MINC=0 but Apache
// minc=1. we can't just use the names, since thrift are in upper case,
// and/ Apache are lower. assuming Thrift will remain uppercase and use
// the same characters as Apache
try {
return org.apache.accumulo.proxy.thrift.IteratorScope.valueOf(is.name().toUpperCase());
} catch (IllegalArgumentException ex) {
throw ExceptionFactory.noEnumMapping(is, org.apache.accumulo.proxy.thrift.IteratorScope.class);
}
}
public static IteratorScope fromThrift(org.apache.accumulo.proxy.thrift.IteratorScope tis) {
if (tis == null) {
return null;
}
// we can't just use the enum values, since thrift MINC=0 but Apache
// minc=1. we can't just use the names, since thrift are in upper case,
// and Apache are lower. assuming Thrift will remain uppercase and use
// the same characters as Apache
try {
return IteratorScope.valueOf(tis.name().toLowerCase());
} catch (IllegalArgumentException ex) {
throw ExceptionFactory.noEnumMapping(tis, IteratorScope.class);
}
}
public static org.apache.accumulo.proxy.thrift.IteratorSetting toThrift(IteratorSetting is) {
if (is == null) {
return null;
}
org.apache.accumulo.proxy.thrift.IteratorSetting tis = new org.apache.accumulo.proxy.thrift.IteratorSetting();
tis.setIteratorClass(is.getIteratorClass());
tis.setName(is.getName());
tis.setPriority(is.getPriority());
tis.setProperties(is.getOptions());
return tis;
}
public static org.apache.accumulo.proxy.thrift.Key toThrift(Key key) {
if (key == null) {
return null;
}
org.apache.accumulo.proxy.thrift.Key tkey = new org.apache.accumulo.proxy.thrift.Key();
tkey.setRow(key.getRow().getBytes());
tkey.setColFamily(key.getColumnFamily().getBytes());
tkey.setColQualifier(key.getColumnQualifier().getBytes());
tkey.setColVisibility(key.getColumnVisibility().getBytes());
tkey.setTimestamp(key.getTimestamp());
return tkey;
}
public static Key fromThrift(org.apache.accumulo.proxy.thrift.Key tkey) {
if (tkey == null) {
return null;
}
return new Key(tkey.getRow(), tkey.getColFamily(), tkey.getColQualifier(), tkey.getColVisibility(), tkey.getTimestamp());
}
public static List<org.apache.accumulo.proxy.thrift.Range> toThriftRanges(Collection<Range> ranges) {
if (ranges == null) {
return null;
}
List<org.apache.accumulo.proxy.thrift.Range> tranges = new ArrayList<org.apache.accumulo.proxy.thrift.Range>(ranges.size());
for (Range range : ranges) {
tranges.add(toThrift(range));
}
return tranges;
}
public static org.apache.accumulo.proxy.thrift.Range toThrift(Range range) {
if (range == null) {
return null;
}
org.apache.accumulo.proxy.thrift.Range trange = new org.apache.accumulo.proxy.thrift.Range();
trange.setStart(toThrift(range.getStartKey()));
trange.setStop(toThrift(range.getEndKey()));
trange.setStartInclusive(range.isStartKeyInclusive());
trange.setStopInclusive(range.isEndKeyInclusive());
return trange;
}
public static Set<Range> fromThriftRanges(Set<org.apache.accumulo.proxy.thrift.Range> tranges) {
if (tranges == null) {
return null;
}
Set<Range> ranges = new HashSet<Range>();
for (org.apache.accumulo.proxy.thrift.Range trange : tranges) {
ranges.add(fromThrift(trange));
}
return ranges;
}
public static Range fromThrift(org.apache.accumulo.proxy.thrift.Range trange) {
if (trange == null) {
return null;
}
return new Range(fromThrift(trange.getStart()), trange.isStartInclusive(), fromThrift(trange.getStop()), trange.isStopInclusive());
}
/**
* Converts each non-thrift ColumnUpdate in {@code list} to a Thrift ColumnUpdate (see {@link #toThrift(ColumnUpdate)}) and adds it to the provided
* {@code thriftUpdates} list. If {@code updates} is null or empty, {@code thriftUpdates} will not be changed.
*
* @param thriftUpdates
* the list where the newly created Thrift ColumnUpdates will be added.
* @param updates
* the list of ColumnUpdates to be converted to Thrift ColumnUpdates
*/
public static void addThriftColumnUpdates(List<org.apache.accumulo.proxy.thrift.ColumnUpdate> thriftUpdates, List<ColumnUpdate> updates) {
if (updates == null) {
return;
}
for (ColumnUpdate cu : updates) {
thriftUpdates.add(toThrift(cu));
}
}
public static org.apache.accumulo.proxy.thrift.ColumnUpdate toThrift(ColumnUpdate update) {
if (update == null) {
return null;
}
org.apache.accumulo.proxy.thrift.ColumnUpdate tcu = new org.apache.accumulo.proxy.thrift.ColumnUpdate();
tcu.setColFamily(update.getColumnFamily());
tcu.setColQualifier(update.getColumnQualifier());
tcu.setColVisibility(update.getColumnVisibility());
tcu.setTimestamp(update.getTimestamp());
tcu.setValue(update.getValue());
// Work around for ACCUMULO-3474
if (update.isDeleted()) {
tcu.setDeleteCell(update.isDeleted());
}
return tcu;
}
public static List<ActiveScan> fromThriftActiveScans(List<org.apache.accumulo.proxy.thrift.ActiveScan> tscans) {
if (tscans == null) {
return null;
}
List<ActiveScan> scans = new ArrayList<ActiveScan>(tscans.size());
for (org.apache.accumulo.proxy.thrift.ActiveScan tscan : tscans) {
scans.add(fromThrift(tscan));
}
return scans;
}
public static ActiveScan fromThrift(org.apache.accumulo.proxy.thrift.ActiveScan scan) {
if (scan == null) {
return null;
}
// Note- scanId is not provided by the server and does not appear to be
// set/used in actual implementation... we will just set it to 0.
return new ProxyActiveScan(0, scan.getClient(), scan.getUser(), scan.getTable(), scan.getAge(), System.currentTimeMillis() - scan.getIdleTime(),
convertEnum(scan.getType(), ScanType.class), convertEnum(scan.getState(), ScanState.class), fromThrift(scan.getExtent()),
fromThriftColumns(scan.getColumns()), scan.getAuthorizations(), scan.getIdleTime());
}
public static KeyExtent fromThrift(org.apache.accumulo.proxy.thrift.KeyExtent textent) {
if (textent == null) {
return null;
}
return new KeyExtent(toText(textent.getTableId()), toText(textent.getEndRow()), toText(textent.getPrevEndRow()));
}
public static List<Column> fromThriftColumns(List<org.apache.accumulo.proxy.thrift.Column> tcolumns) {
if (tcolumns == null) {
return null;
}
List<Column> columns = new ArrayList<Column>(tcolumns.size());
for (org.apache.accumulo.proxy.thrift.Column tcolumn : tcolumns) {
columns.add(fromThrift(tcolumn));
}
return columns;
}
public static Column fromThrift(org.apache.accumulo.proxy.thrift.Column tcolumn) {
if (tcolumn == null) {
return null;
}
return new Column(tcolumn.getColFamily(), tcolumn.getColQualifier(), tcolumn.getColVisibility());
}
public static List<ActiveCompaction> fromThriftActiveCompactions(Map<String,String> tableIdMap,
List<org.apache.accumulo.proxy.thrift.ActiveCompaction> tcompactions) {
if (tcompactions == null) {
return null;
}
List<ActiveCompaction> compactions = new ArrayList<ActiveCompaction>(tcompactions.size());
for (org.apache.accumulo.proxy.thrift.ActiveCompaction tcompaction : tcompactions) {
compactions.add(fromThrift(getTableNameFromId(tableIdMap, tcompaction.getExtent().getTableId()), tcompaction));
}
return compactions;
}
public static ActiveCompaction fromThrift(String tableName, org.apache.accumulo.proxy.thrift.ActiveCompaction tcompaction) {
if (tcompaction == null) {
return null;
}
return new ProxyActiveCompaction(tableName, fromThrift(tcompaction.getExtent()), tcompaction.getAge(), tcompaction.getInputFiles(),
tcompaction.getOutputFile(), convertEnum(tcompaction.getType(), CompactionType.class), convertEnum(tcompaction.getReason(), CompactionReason.class),
tcompaction.getLocalityGroup(), tcompaction.getEntriesRead(), tcompaction.getEntriesWritten(), fromThriftIteratorSettings(tcompaction.getIterators()));
}
public static String getTableNameFromId(Map<String,String> tableIdMap, String id) {
if (id == null) {
return null;
}
for (Entry<String,String> entry : tableIdMap.entrySet()) {
if (id.equalsIgnoreCase(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
public static List<IteratorSetting> fromThriftIteratorSettings(List<org.apache.accumulo.proxy.thrift.IteratorSetting> tsettings) {
if (tsettings == null) {
return null;
}
List<IteratorSetting> settings = new ArrayList<IteratorSetting>(tsettings.size());
for (org.apache.accumulo.proxy.thrift.IteratorSetting tsetting : tsettings) {
settings.add(fromThrift(tsetting));
}
return settings;
}
public static IteratorSetting fromThrift(org.apache.accumulo.proxy.thrift.IteratorSetting tsetting) {
if (tsetting == null) {
return null;
}
return new IteratorSetting(tsetting.getPriority(), tsetting.getName(), tsetting.getIteratorClass(), tsetting.getProperties());
}
public static List<org.apache.accumulo.proxy.thrift.IteratorSetting> toThriftIteratorSettings(List<IteratorSetting> settings) {
if (settings == null) {
return null;
}
List<org.apache.accumulo.proxy.thrift.IteratorSetting> tsettings = new ArrayList<org.apache.accumulo.proxy.thrift.IteratorSetting>(settings.size());
for (IteratorSetting setting : settings) {
tsettings.add(toThrift(setting));
}
return tsettings;
}
public static List<DiskUsage> fromThriftDiskUsage(List<org.apache.accumulo.proxy.thrift.DiskUsage> tusage) {
if (tusage == null) {
return null;
}
List<DiskUsage> usage = new ArrayList<DiskUsage>(tusage.size());
for (org.apache.accumulo.proxy.thrift.DiskUsage tdu : tusage) {
usage.add(fromThrift(tdu));
}
return usage;
}
public static DiskUsage fromThrift(org.apache.accumulo.proxy.thrift.DiskUsage tusage) {
if (tusage == null) {
return null;
}
return new DiskUsage(new TreeSet<String>(tusage.getTables()), tusage.getUsage());
}
public static List<org.apache.accumulo.proxy.thrift.Condition> toThriftCondition(List<Condition> conditions) {
if (conditions == null) {
return null;
}
List<org.apache.accumulo.proxy.thrift.Condition> tconditions = new ArrayList<org.apache.accumulo.proxy.thrift.Condition>(conditions.size());
for (Condition c : conditions) {
tconditions.add(toThrift(c));
}
return tconditions;
}
public static org.apache.accumulo.proxy.thrift.Condition toThrift(Condition condition) {
if (condition == null) {
return null;
}
org.apache.accumulo.proxy.thrift.Condition tcondition = new org.apache.accumulo.proxy.thrift.Condition();
org.apache.accumulo.proxy.thrift.Column col = new org.apache.accumulo.proxy.thrift.Column();
if (condition.getFamily() != null) {
col.setColFamily(condition.getFamily().getBackingArray());
}
if (condition.getQualifier() != null) {
col.setColQualifier(condition.getQualifier().getBackingArray());
}
if (col.getColVisibility() != null) {
col.setColVisibility(condition.getQualifier().getBackingArray());
}
tcondition.setColumn(col);
if (condition.getTimestamp() != null) {
tcondition.setTimestamp(condition.getTimestamp());
}
if (condition.getValue() != null) {
tcondition.setValue(condition.getValue().getBackingArray());
}
tcondition.setIterators(toThriftIteratorSettings(Arrays.asList(condition.getIterators())));
return tcondition;
}
public static MutationsRejectedException fromThrift(org.apache.accumulo.proxy.thrift.MutationsRejectedException mre, Instance instance) {
return new MutationsRejectedException(instance, null, null, Collections.singleton(mre.getMsg()), 0, mre);
}
/**
* Converts the enumeration of class F to the enumeration of class S assuming both F and S define the same values. This is used in mapping between Accumulo
* client-side enumerations and their equivalent Thrift-based enumerations.
*
* @param first
* the enumeration to convert
* @param cls
* the new class of the enumeration
* @return an enumeration of type <code>cls</code> with the same name as <code>first</code>.
* @exception ProxyInstanceError
* thrown if the text of <code>first</code> is not a valid enumerated value in the class <code>cls</code>.
*/
public static <F extends Enum<F>,S extends Enum<S>> S convertEnum(F first, Class<S> cls) throws ProxyInstanceError {
if (first == null) {
return null;
}
try {
return Enum.valueOf(cls, first.toString());
} catch (IllegalArgumentException e) {
throw ExceptionFactory.noEnumMapping(first, cls);
}
}
public static Text toText(String val) {
if (val == null) {
return null;
} else {
return new Text(val.getBytes(UTF8));
}
}
public static Text toText(byte[] val) {
if (val == null) {
return null;
} else {
return new Text(val);
}
}
public static ByteBuffer toByteBuffer(Text val) {
if (val == null) {
return null;
} else {
return ByteBuffer.wrap(val.getBytes());
}
}
}

View File

@@ -0,0 +1,292 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="AccumuloProxy" version="12">
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
</profile>
</profiles>

View File

@@ -0,0 +1,13 @@
Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
Licensed 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.

View File

@@ -0,0 +1,116 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.proxy.Proxy;
import org.apache.thrift.transport.TTransportException;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
/**
* Base class for unit and integration tests that want to get access to an Instance and/or Connector. This class provides the means to setup a ProxyInstace
* connection to a local ProxyServer backed by a mock (in-memory) Accumulo instance for unit tests, or to create a ProxyInstace connection to a real (external)
* ProxyServer for integration tests.
*/
public class ConnectorBase {
protected static volatile ProxyInstance instance = null;
protected static volatile Connector connector = null;
private static Thread proxyServerThread = null;
/**
* Initializes the instance and connector variables (and proxyServerThread, if needed) if they are currently null. This will be done once per class, but we
* cannot do this with a @BeforeClass because we want to use the type of the subclass to determine if it is a unit or integration test.
*/
@Before
public void prepare() throws TTransportException, AccumuloException, AccumuloSecurityException, InterruptedException {
if (instance == null) {
synchronized (ConnectorBase.class) {
if (instance == null) {
ProxyInstance locInst = null;
Connector locConn = null;
if (IntegrationTest.class.isAssignableFrom(getClass())) {
String host = getString("accumulo.proxy.host");
int port = getInt("accumulo.proxy.port");
String user = getString("accumulo.proxy.user");
String passwd = getString("accumulo.proxy.password");
locInst = new ProxyInstance(host, port);
locConn = locInst.getConnector(user, new PasswordToken(passwd));
} else {
createLocalServer();
locInst = new ProxyInstance("localhost", 45678);
locConn = locInst.getConnector("root", new PasswordToken(""));
}
instance = locInst;
connector = locConn;
}
}
}
}
@AfterClass
public static void teardown() {
try {
if (instance != null) {
instance.close();
}
} finally {
instance = null;
}
try {
if (proxyServerThread != null) {
proxyServerThread.interrupt();
}
} finally {
proxyServerThread = null;
}
}
private static String getString(String key) {
String val = System.getProperty(key);
if (val == null) {
Assert.fail("You must specify the system property: " + key);
}
return val.trim();
}
private static int getInt(String key) throws NumberFormatException {
return Integer.parseInt(getString(key));
}
private static void createLocalServer() throws InterruptedException {
proxyServerThread = new Thread() {
public void run() {
try {
String[] args = new String[] {"-p", "src/test/resources/mock.props"};
Proxy.main(args);
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
proxyServerThread.setDaemon(true);
proxyServerThread.start();
Thread.sleep(150);
}
}

View File

@@ -0,0 +1,24 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
/**
* A flag interface that signals a test is an integration test (vs. a unit test). When used in conjunction with the {@link ConnectorBase} class, the appropriate
* Instance type will be instantiated.
*/
public interface IntegrationTest {
}

View File

@@ -0,0 +1,140 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.charset.StandardCharsets;
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.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
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.security.Authorizations;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ScannerTest extends ConnectorBase {
String table = "__TEST_TABLE__";
int noAuthCount;
@Before
public void createTable() throws AccumuloException, AccumuloSecurityException, TableExistsException, TableNotFoundException {
connector.tableOperations().create(table);
BatchWriter bw = connector.createBatchWriter(table, new BatchWriterConfig());
for (char ch = 'a'; ch <= 'z'; ch++) {
Mutation m = new Mutation(ch + "_row");
m.put("fam1", "qual1", "val1:1");
m.put("fam1", "qual2", "val1:2");
m.put("fam2", "qual1", "val2:1");
m.put("fam2", "qual2", "val2:2");
m.put("fam2", "qual3", "val2:3");
noAuthCount = m.getUpdates().size();
bw.addMutation(m);
}
bw.close();
}
@After
public void dropTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
connector.tableOperations().delete(table);
}
@Test
public void simpleTest() throws TableNotFoundException {
Scanner s = connector.createScanner(table, Authorizations.EMPTY);
validate(noAuthCount * 26, s);
}
@Test
public void testRanges() throws TableNotFoundException {
// first row
Scanner scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("a_row"), noAuthCount, scanner);
// last row
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("z_row"), noAuthCount, scanner);
// "random" inner row
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("q_row"), noAuthCount, scanner);
// some actual ranges
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("d_row", true, "h_row", true), 5 * noAuthCount, scanner);
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("d_row", false, "h_row", true), 4 * noAuthCount, scanner);
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("d_row", true, "h_row", false), 4 * noAuthCount, scanner);
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("d_row", false, "h_row", false), 3 * noAuthCount, scanner);
// no start
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range(null, "j_row"), 10 * noAuthCount, scanner);
// no end
scanner = connector.createScanner(table, Authorizations.EMPTY);
testRange(new Range("j_row", null), 17 * noAuthCount, scanner);
}
private void testRange(Range range, int expected, Scanner scanner) {
scanner.setRange(range);
Assert.assertEquals(range, scanner.getRange());
validate(expected, scanner);
}
private void validate(int expected, Scanner scanner) {
int count = 0;
for (Entry<Key,Value> entry : scanner) {
validate(entry);
count++;
}
Assert.assertEquals(expected, count);
scanner.close();
}
/**
* expects ("famX", "qualY") -> "valX:Y"
*
* @param entry
* entry to validate
*/
private void validate(Entry<Key,Value> entry) {
String fam = entry.getKey().getColumnFamily().toString().substring(3);
String qual = entry.getKey().getColumnQualifier().toString().substring(4);
String val = new String(entry.getValue().get(), StandardCharsets.UTF_8).substring(3);
String[] parts = val.split(":");
Assert.assertEquals("Family and value did not line up.", fam, parts[0]);
Assert.assertEquals("Qualifier and value did not line up.", qual, parts[1]);
}
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
public class ScannerTestIT extends ScannerTest implements IntegrationTest {}

View File

@@ -0,0 +1,78 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.TableOperations;
import org.junit.Assert;
import org.junit.Test;
public class TableOpsTest extends ConnectorBase {
String table = "__TEST_TABLE__";
@Test
public void testTableOps() throws AccumuloException, AccumuloSecurityException, TableExistsException, TableNotFoundException {
TableOperations tops = connector.tableOperations();
Assert.assertFalse(tops.exists(table));
tops.create(table);
Assert.assertTrue(tops.exists(table));
tops.delete(table);
Assert.assertFalse(tops.exists(table));
}
@Test
public void testCreateExistingTable() throws AccumuloException, AccumuloSecurityException, TableNotFoundException, TableExistsException {
TableOperations tops = connector.tableOperations();
try {
Assert.assertFalse(tops.exists(table));
tops.create(table);
Assert.assertTrue(tops.exists(table));
try {
tops.create(table);
Assert.fail("Expected second table create to fail.");
} catch (TableExistsException tee) {
// expected
Assert.assertTrue(true);
}
} finally {
if (tops.exists(table)) {
tops.delete(table);
}
Assert.assertFalse(tops.exists(table));
}
}
@Test
public void testDeleteNonExistentTable() throws AccumuloException, AccumuloSecurityException {
TableOperations tops = connector.tableOperations();
Assert.assertFalse(tops.exists(table));
try {
tops.delete(table);
Assert.fail("Expected second table create to fail.");
} catch (TableNotFoundException tnfe) {
// expected
Assert.assertTrue(true);
}
}
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
public class TableOpsTestIT extends TableOpsTest implements IntegrationTest {}

View File

@@ -0,0 +1,129 @@
/**
* Copyright 2014-2015 The Johns Hopkins University / Applied Physics Laboratory
*
* Licensed 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 edu.jhuapl.accumulo.proxy;
import java.nio.ByteBuffer;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.hadoop.io.Text;
import org.junit.Assert;
import org.junit.Test;
public class ThiftHelperTest {
/**
* Used for enum mapping testing
*/
public enum FirstEnum {
val1, val2
};
/**
* Used for enum mapping testing
*/
public enum SecondEnum {
val1
};
@Test
public void testToText() {
String test = "test";
Text txt = ThriftHelper.toText(test);
Assert.assertEquals(test, txt.toString());
txt = ThriftHelper.toText(test.getBytes());
Assert.assertEquals(test, txt.toString());
txt = ThriftHelper.toText((byte[]) null);
Assert.assertNull(txt);
}
@Test
public void testEnum() {
SecondEnum se = ThriftHelper.convertEnum(null, SecondEnum.class);
Assert.assertNull(se);
se = ThriftHelper.convertEnum(FirstEnum.val1, SecondEnum.class);
Assert.assertEquals(SecondEnum.val1, se);
}
@Test(expected = ProxyInstanceError.class)
public void testEnumBadMapping() {
ThriftHelper.convertEnum(FirstEnum.val2, SecondEnum.class);
}
@Test
public void testToByteBuffer() {
ByteBuffer buf = ThriftHelper.toByteBuffer(null);
Assert.assertNull(buf);
Text text = new Text("test test");
buf = ThriftHelper.toByteBuffer(text);
Assert.assertArrayEquals(text.getBytes(), buf.array());
}
@Test
public void testRanges() {
testConvertRange(new Range("a", "b"));
testConvertRange(new Range(null, "b"));
testConvertRange(new Range("a", null));
testConvertRange(null);
testConvertRange(new Range("a", true, "b", false));
testConvertRange(new Range("a", false, "b", false));
testConvertRange(new Range("a", false, "b", true));
}
private void testConvertRange(Range range) {
org.apache.accumulo.proxy.thrift.Range r2 = ThriftHelper.toThrift(range);
checkRanges(range, r2);
range = ThriftHelper.fromThrift(r2);
checkRanges(range, r2);
}
private void checkRanges(Range r1, org.apache.accumulo.proxy.thrift.Range r2) {
if (r1 == null) {
Assert.assertNull("t1 was null, but r2 was not!", r2);
return;
} else if (r2 == null) {
Assert.fail("r1 was not null, but r2 was!");
return;
}
checkKeys(r1.getStartKey(), r2.getStart());
checkKeys(r1.getEndKey(), r2.getStop());
Assert.assertEquals(r1.isStartKeyInclusive(), r2.isStartInclusive());
Assert.assertEquals(r1.isEndKeyInclusive(), r2.isStopInclusive());
}
private void checkKeys(Key k, org.apache.accumulo.proxy.thrift.Key k2) {
if (k == null) {
Assert.assertNull("k was null, but k2 was not!", k2);
return;
} else if (k2 == null) {
Assert.fail("k was not null, but k2 was!");
return;
}
Assert.assertArrayEquals(k.getRow().getBytes(), k2.getRow());
Assert.assertArrayEquals(k.getColumnFamily().getBytes(), k2.getColFamily());
Assert.assertArrayEquals(k.getColumnQualifier().getBytes(), k2.getColQualifier());
Assert.assertArrayEquals(k.getColumnVisibility().getBytes(), k2.getColVisibility());
Assert.assertEquals(k.getTimestamp(), k2.getTimestamp());
}
}

View File

@@ -0,0 +1,3 @@
useMockInstance=true
port=45678