You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ec...@apache.org on 2013/10/22 16:29:45 UTC

[1/4] git commit: ACCUMULO-1800 fix deletes, added test

Updated Branches:
  refs/heads/master fb8294541 -> 8ec4cb840


ACCUMULO-1800 fix deletes, added test


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/ffd16c7a
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/ffd16c7a
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/ffd16c7a

Branch: refs/heads/master
Commit: ffd16c7adbfd99f7acbba08ad9934acd5c80a7df
Parents: 19e24ab
Author: Eric Newton <er...@gmail.com>
Authored: Tue Oct 22 10:20:59 2013 -0400
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Oct 22 10:20:59 2013 -0400

----------------------------------------------------------------------
 .../org/apache/accumulo/proxy/ProxyServer.java  | 10 ++++----
 .../org/apache/accumulo/proxy/SimpleTest.java   | 25 ++++++++++++++++++++
 2 files changed, 30 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/ffd16c7a/src/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
----------------------------------------------------------------------
diff --git a/src/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java b/src/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
index 6241d19..d749723 100644
--- a/src/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
+++ b/src/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
@@ -1094,14 +1094,14 @@ public class ProxyServer implements AccumuloProxy.Iface {
           if (update.isSetDeleteCell()) {
             m.putDelete(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, update.getTimestamp());
           } else {
-            if (update.isSetDeleteCell()) {
-              m.putDelete(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, update.getTimestamp());
-            } else {
               m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, update.getTimestamp(), new Value(value));
             }
-          }
         } else {
-          m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, new Value(value));
+          if (update.isSetDeleteCell()) {
+            m.putDelete(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz);
+          } else {
+            m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, new Value(value));
+          }
         }
       }
       try {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/ffd16c7a/src/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
----------------------------------------------------------------------
diff --git a/src/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java b/src/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
index dd1bb19..f6533c2 100644
--- a/src/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
+++ b/src/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
@@ -385,6 +385,31 @@ public class SimpleTest {
   }
   
   @Test(timeout = 10000)
+  public void testDelete() throws Exception {
+    if (client.tableExists(creds, TABLE_TEST))
+      client.deleteTable(creds, TABLE_TEST);
+
+    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
+    client.updateAndFlush(creds, TABLE_TEST, mutation("row0", "cf", "cq", "value"));
+    String scanner = client.createScanner(creds, TABLE_TEST, null);
+    ScanResult entries = client.nextK(scanner, 10);
+    client.closeScanner(scanner);
+    assertFalse(entries.more);
+    assertEquals(1, entries.results.size());
+    
+    ColumnUpdate upd = new ColumnUpdate(s2bb("cf"), s2bb("cq"));
+    upd.setDeleteCell(true);
+    Map<ByteBuffer,List<ColumnUpdate>> delete = Collections.singletonMap(s2bb("row0"), Collections.singletonList(upd));
+    
+    client.updateAndFlush(creds, TABLE_TEST, delete);
+    
+    scanner = client.createScanner(creds, TABLE_TEST, null);
+    entries = client.nextK(scanner, 10);
+    client.closeScanner(scanner);
+    assertEquals(0, entries.results.size());
+  }
+
+  @Test(timeout = 10000)
   public void testInstanceOperations() throws Exception {
     int tservers = 0;
     for (String tserver : client.getTabletServers(creds)) {


[2/4] ACCUMULO-1800 fix deletes, added test

Posted by ec...@apache.org.
http://git-wip-us.apache.org/repos/asf/accumulo/blob/3143b9c5/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
----------------------------------------------------------------------
diff --cc proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
index 3fd0a8f,0000000..3bd552d
mode 100644,000000..100644
--- a/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
+++ b/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
@@@ -1,1134 -1,0 +1,1159 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.accumulo.proxy;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNotEquals;
 +import static org.junit.Assert.assertTrue;
 +import static org.junit.Assert.fail;
 +
 +import java.io.BufferedReader;
 +import java.io.File;
 +import java.io.InputStreamReader;
 +import java.nio.ByteBuffer;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.EnumSet;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Random;
 +import java.util.Set;
 +import java.util.TreeMap;
 +import java.util.UUID;
 +
 +import org.apache.accumulo.core.Constants;
 +import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 +import org.apache.accumulo.core.conf.DefaultConfiguration;
 +import org.apache.accumulo.core.conf.Property;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.file.FileOperations;
 +import org.apache.accumulo.core.file.FileSKVWriter;
 +import org.apache.accumulo.core.iterators.DevNull;
 +import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
 +import org.apache.accumulo.core.iterators.user.SummingCombiner;
 +import org.apache.accumulo.core.iterators.user.VersioningIterator;
 +import org.apache.accumulo.core.util.UtilWaitThread;
 +import org.apache.accumulo.examples.simple.constraints.NumericValueConstraint;
 +import org.apache.accumulo.minicluster.MiniAccumuloCluster;
 +import org.apache.accumulo.minicluster.MiniAccumuloConfig;
 +import org.apache.accumulo.proxy.thrift.AccumuloProxy.Client;
 +import org.apache.accumulo.proxy.thrift.AccumuloSecurityException;
 +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.CompactionReason;
 +import org.apache.accumulo.proxy.thrift.CompactionType;
 +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.MutationsRejectedException;
 +import org.apache.accumulo.proxy.thrift.PartialKey;
 +import org.apache.accumulo.proxy.thrift.Range;
 +import org.apache.accumulo.proxy.thrift.ScanColumn;
 +import org.apache.accumulo.proxy.thrift.ScanOptions;
 +import org.apache.accumulo.proxy.thrift.ScanResult;
 +import org.apache.accumulo.proxy.thrift.ScanState;
 +import org.apache.accumulo.proxy.thrift.ScanType;
 +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.accumulo.server.util.PortUtils;
 +import org.apache.accumulo.test.functional.SlowIterator;
 +import org.apache.commons.io.FileUtils;
 +import org.apache.hadoop.conf.Configuration;
 +import org.apache.hadoop.fs.FSDataInputStream;
 +import org.apache.hadoop.fs.FileSystem;
 +import org.apache.hadoop.fs.Path;
 +import org.apache.hadoop.io.Text;
 +import org.apache.thrift.TException;
 +import org.apache.thrift.protocol.TProtocolFactory;
 +import org.apache.thrift.server.TServer;
 +import org.junit.AfterClass;
 +import org.junit.BeforeClass;
 +import org.junit.Test;
 +import org.junit.rules.TemporaryFolder;
 +
 +/**
 + * Call every method on the proxy and try to verify that it works.
 + */
 +public class SimpleTest {
 +  
 +  public static TemporaryFolder folder = new TemporaryFolder();
 +  
 +  public static final String TABLE_TEST = "test";
 +  
 +  private static MiniAccumuloCluster accumulo;
 +  private static String secret = "superSecret";
 +  private static Random random = new Random();
 +  private static TServer proxyServer;
 +  private static Thread thread;
 +  private static int proxyPort;
 +  private static org.apache.accumulo.proxy.thrift.AccumuloProxy.Client client;
 +  private static String principal = "root";
 +  @SuppressWarnings("serial")
 +  private static Map<String,String> properties = new TreeMap<String,String>() {
 +    {
 +      put("password", secret);
 +    }
 +  };
 +  private static ByteBuffer creds = null;
 +  
 +  private static Class<? extends TProtocolFactory> protocolClass;
 +  
 +  static Class<? extends TProtocolFactory> getRandomProtocol() {
 +    List<Class<? extends TProtocolFactory>> protocolFactories = new ArrayList<Class<? extends TProtocolFactory>>();
 +    protocolFactories.add(org.apache.thrift.protocol.TJSONProtocol.Factory.class);
 +    protocolFactories.add(org.apache.thrift.protocol.TBinaryProtocol.Factory.class);
 +    protocolFactories.add(org.apache.thrift.protocol.TTupleProtocol.Factory.class);
 +    protocolFactories.add(org.apache.thrift.protocol.TCompactProtocol.Factory.class);
 +    
 +    return protocolFactories.get(random.nextInt(protocolFactories.size()));
 +  }
 +  
 +  @BeforeClass
 +  public static void setupMiniCluster() throws Exception {
 +    folder.create();
 +    MiniAccumuloConfig config = new MiniAccumuloConfig(folder.getRoot(), secret)
 +            .setNumTservers (1);
 +    accumulo = new MiniAccumuloCluster(config);
 +    accumulo.start();
 +    
 +    Properties props = new Properties();
 +    props.put("instance", accumulo.getInstanceName());
 +    props.put("zookeepers", accumulo.getZooKeepers());
 +    props.put("tokenClass", PasswordToken.class.getName());
 +    
 +    protocolClass = getRandomProtocol();
 +    System.out.println(protocolClass.getName());
 +    
 +    proxyPort = PortUtils.getRandomFreePort();
 +    proxyServer = Proxy.createProxyServer(org.apache.accumulo.proxy.thrift.AccumuloProxy.class, org.apache.accumulo.proxy.ProxyServer.class, proxyPort,
 +        protocolClass, props);
 +    thread = new Thread() {
 +      @Override
 +      public void run() {
 +        proxyServer.serve();
 +      }
 +    };
 +    thread.start();
 +    while (!proxyServer.isServing())
 +      UtilWaitThread.sleep(100);
 +    client = new TestProxyClient("localhost", proxyPort, protocolClass.newInstance()).proxy();
 +    creds = client.login(principal, properties);
 +  }
 +  
 +  @Test(timeout = 10000)
 +  public void security() throws Exception {
 +    client.createLocalUser(creds, "user", s2bb(secret));
 +    ByteBuffer badLogin = client.login("user", properties);
 +    client.dropLocalUser(creds, "user");
 +    String table = "test1";
 +    client.createTable(creds, table, false, TimeType.MILLIS);
 +    
 +    final IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "200"));
 +    
 +    try {
 +      client.addConstraint(badLogin, table, NumericValueConstraint.class.getName());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.addSplits(badLogin, table, Collections.singleton(s2bb("1")));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.clearLocatorCache(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.compactTable(badLogin, table, null, null, null, true, false);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.cancelCompaction(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.createTable(badLogin, table, false, TimeType.MILLIS);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.deleteTable(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.deleteRows(badLogin, table, null, null);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.tableExists(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.flushTable(badLogin, table, null, null, false);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getLocalityGroups(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getMaxRow(badLogin, table, Collections.<ByteBuffer> emptySet(), null, false, null, false);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getTableProperties(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.listSplits(badLogin, table, 10000);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.listTables(badLogin);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.listConstraints(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.mergeTablets(badLogin, table, null, null);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.offlineTable(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.onlineTable(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.removeConstraint(badLogin, table, 0);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.removeTableProperty(badLogin, table, Property.TABLE_FILE_MAX.getKey());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.renameTable(badLogin, table, "someTableName");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      Map<String,Set<String>> groups = new HashMap<String,Set<String>>();
 +      groups.put("group1", Collections.singleton("cf1"));
 +      groups.put("group2", Collections.singleton("cf2"));
 +      client.setLocalityGroups(badLogin, table, groups);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.setTableProperty(badLogin, table, Property.TABLE_FILE_MAX.getKey(), "0");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.tableIdMap(badLogin);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.getSiteConfiguration(badLogin);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getSystemConfiguration(badLogin);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getTabletServers(badLogin);
 +      fail("exception not thrown");
 +    } catch (TException ex) {}
 +    try {
 +      client.getActiveScans(badLogin, "fake");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getActiveCompactions(badLogin, "fakse");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.removeProperty(badLogin, "table.split.threshold");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.setProperty(badLogin, "table.split.threshold", "500M");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.testClassLoad(badLogin, DevNull.class.getName(), SortedKeyValueIterator.class.getName());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.authenticateUser(badLogin, "root", s2pp(secret));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
 +      client.changeUserAuthorizations(badLogin, "stooge", auths);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.changeLocalUserPassword(badLogin, "stooge", s2bb(""));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.createLocalUser(badLogin, "stooge", s2bb("password"));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.dropLocalUser(badLogin, "stooge");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getUserAuthorizations(badLogin, "stooge");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.grantSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.grantTablePermission(badLogin, "root", table, TablePermission.WRITE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.hasSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.hasTablePermission(badLogin, "root", table, TablePermission.WRITE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.listLocalUsers(badLogin);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.revokeSystemPermission(badLogin, "stooge", SystemPermission.CREATE_TABLE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.revokeTablePermission(badLogin, "root", table, TablePermission.ALTER_TABLE);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.createScanner(badLogin, table, new ScanOptions());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.createBatchScanner(badLogin, table, new BatchScanOptions());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.updateAndFlush(badLogin, table, new HashMap<ByteBuffer,List<ColumnUpdate>>());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.createWriter(badLogin, table, new WriterOptions());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.attachIterator(badLogin, "slow", setting, EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.checkIteratorConflicts(badLogin, table, setting, EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.cloneTable(badLogin, table, TABLE_TEST, false, null, null);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.exportTable(badLogin, table, "/tmp");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.importTable(badLogin, "testify", "/tmp");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.getIteratorSetting(badLogin, table, "foo", IteratorScope.SCAN);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.listIterators(badLogin, table);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.removeIterator(badLogin, table, "name", EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.splitRangeByTablets(badLogin, table, client.getRowRange(ByteBuffer.wrap("row".getBytes())), 10);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      File newFolder = folder.newFolder();
 +      client.importDirectory(badLogin, table, "/tmp", newFolder.getAbsolutePath(), true);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.pingTabletServer(badLogin, "fake");
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.login("badUser", properties);
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +    try {
 +      client.testTableClassLoad(badLogin, table, VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName());
 +      fail("exception not thrown");
 +    } catch (AccumuloSecurityException ex) {}
 +  }
 +  
 +  @Test(timeout = 10000)
 +  public void tableNotFound() throws Exception {
 +    final String doesNotExist = "doesNotExists";
 +    try {
 +      client.addConstraint(creds, doesNotExist, NumericValueConstraint.class.getName());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.addSplits(creds, doesNotExist, Collections.<ByteBuffer> emptySet());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    final IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "200"));
 +    try {
 +      client.attachIterator(creds, doesNotExist, setting, EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.cancelCompaction(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.checkIteratorConflicts(creds, doesNotExist, setting, EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.clearLocatorCache(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.cloneTable(creds, doesNotExist, TABLE_TEST, false, null, null);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.compactTable(creds, doesNotExist, null, null, null, true, false);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.createBatchScanner(creds, doesNotExist, new BatchScanOptions());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.createScanner(creds, doesNotExist, new ScanOptions());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.createWriter(creds, doesNotExist, new WriterOptions());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.deleteRows(creds, doesNotExist, null, null);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.deleteTable(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.exportTable(creds, doesNotExist, "/tmp");
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.flushTable(creds, doesNotExist, null, null, false);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.getIteratorSetting(creds, doesNotExist, "foo", IteratorScope.SCAN);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.getLocalityGroups(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.getMaxRow(creds, doesNotExist, Collections.<ByteBuffer> emptySet(), null, false, null, false);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.getTableProperties(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.grantTablePermission(creds, "root", doesNotExist, TablePermission.WRITE);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.hasTablePermission(creds, "root", doesNotExist, TablePermission.WRITE);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      File newFolder = folder.newFolder();
 +      client.importDirectory(creds, doesNotExist, "/tmp", newFolder.getAbsolutePath(), true);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.listConstraints(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.listSplits(creds, doesNotExist, 10000);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.mergeTablets(creds, doesNotExist, null, null);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.offlineTable(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.onlineTable(creds, doesNotExist);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.removeConstraint(creds, doesNotExist, 0);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.removeIterator(creds, doesNotExist, "name", EnumSet.allOf(IteratorScope.class));
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.removeTableProperty(creds, doesNotExist, Property.TABLE_FILE_MAX.getKey());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.renameTable(creds, doesNotExist, "someTableName");
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.revokeTablePermission(creds, "root", doesNotExist, TablePermission.ALTER_TABLE);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.setTableProperty(creds, doesNotExist, Property.TABLE_FILE_MAX.getKey(), "0");
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.splitRangeByTablets(creds, doesNotExist, client.getRowRange(ByteBuffer.wrap("row".getBytes())), 10);
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.updateAndFlush(creds, doesNotExist, new HashMap<ByteBuffer,List<ColumnUpdate>>());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +    try {
 +      client.testTableClassLoad(creds, doesNotExist, VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName());
 +      fail("exception not thrown");
 +    } catch (TableNotFoundException ex) {}
 +  }
 +  
 +  @Test(timeout = 10000)
 +  public void testExists() throws Exception {
 +    client.createTable(creds, "ett1", false, TimeType.MILLIS);
 +    client.createTable(creds, "ett2", false, TimeType.MILLIS);
 +    try {
 +      client.createTable(creds, "ett1", false, TimeType.MILLIS);
 +      fail("exception not thrown");
 +    } catch (TableExistsException tee) {}
 +    try {
 +      client.renameTable(creds, "ett1", "ett2");
 +      fail("exception not thrown");
 +    } catch (TableExistsException tee) {}
 +    try {
 +      client.cloneTable(creds, "ett1", "ett2", false, new HashMap<String,String>(), new HashSet<String>());
 +      fail("exception not thrown");
 +    } catch (TableExistsException tee) {}
 +  }
 +  
 +  @Test(timeout = 10000)
 +  public void testUnknownScanner() throws Exception {
 +    if (client.tableExists(creds, TABLE_TEST))
 +      client.deleteTable(creds, TABLE_TEST);
 +    
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    
 +    String scanner = client.createScanner(creds, TABLE_TEST, null);
 +    assertFalse(client.hasNext(scanner));
 +    client.closeScanner(scanner);
 +    
 +    try {
 +      client.hasNext(scanner);
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +    
 +    try {
 +      client.closeScanner(scanner);
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +    
 +    try {
 +      client.nextEntry("99999999");
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +    try {
 +      client.nextK("99999999", 6);
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +    try {
 +      client.hasNext("99999999");
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +    try {
 +      client.hasNext(UUID.randomUUID().toString());
 +      fail("exception not thrown");
 +    } catch (UnknownScanner us) {}
 +  }
 +  
 +  @Test(timeout = 10000)
 +  public void testUnknownWriter() throws Exception {
 +    
 +    if (client.tableExists(creds, TABLE_TEST))
 +      client.deleteTable(creds, TABLE_TEST);
 +    
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    
 +    String writer = client.createWriter(creds, TABLE_TEST, null);
 +    client.update(writer, mutation("row0", "cf", "cq", "value"));
 +    client.flush(writer);
 +    client.update(writer, mutation("row2", "cf", "cq", "value2"));
 +    client.closeWriter(writer);
 +    
 +    // this is a oneway call, so it does not throw exceptions
 +    client.update(writer, mutation("row2", "cf", "cq", "value2"));
 +    
 +    try {
 +      client.flush(writer);
 +      fail("exception not thrown");
 +    } catch (UnknownWriter uw) {}
 +    try {
 +      client.flush("99999");
 +      fail("exception not thrown");
 +    } catch (UnknownWriter uw) {}
 +    try {
 +      client.flush(UUID.randomUUID().toString());
 +      fail("exception not thrown");
 +    } catch (UnknownWriter uw) {}
 +    try {
 +      client.closeWriter("99999");
 +      fail("exception not thrown");
 +    } catch (UnknownWriter uw) {}
 +  }
 +  
 +  @Test(timeout = 10000)
++  public void testDelete() throws Exception {
++    if (client.tableExists(creds, TABLE_TEST))
++      client.deleteTable(creds, TABLE_TEST);
++
++    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
++    client.updateAndFlush(creds, TABLE_TEST, mutation("row0", "cf", "cq", "value"));
++    String scanner = client.createScanner(creds, TABLE_TEST, null);
++    ScanResult entries = client.nextK(scanner, 10);
++    client.closeScanner(scanner);
++    assertFalse(entries.more);
++    assertEquals(1, entries.results.size());
++    
++    ColumnUpdate upd = new ColumnUpdate(s2bb("cf"), s2bb("cq"));
++    upd.setDeleteCell(true);
++    Map<ByteBuffer,List<ColumnUpdate>> delete = Collections.singletonMap(s2bb("row0"), Collections.singletonList(upd));
++    
++    client.updateAndFlush(creds, TABLE_TEST, delete);
++    
++    scanner = client.createScanner(creds, TABLE_TEST, null);
++    entries = client.nextK(scanner, 10);
++    client.closeScanner(scanner);
++    assertEquals(0, entries.results.size());
++  }
++
++  @Test(timeout = 10000)
 +  public void testInstanceOperations() throws Exception {
 +    int tservers = 0;
 +    for (String tserver : client.getTabletServers(creds)) {
 +      client.pingTabletServer(creds, tserver);
 +      tservers++;
 +    }
 +    assertTrue(tservers > 0);
 +    
 +    // get something we know is in the site config
 +    Map<String,String> cfg = client.getSiteConfiguration(creds);
 +    assertTrue(cfg.get("instance.dfs.dir").startsWith(folder.getRoot().toString()));
 +    
 +    // set a property in zookeeper
 +    client.setProperty(creds, "table.split.threshold", "500M");
 +    
 +    // check that we can read it
 +    for (int i = 0; i < 5; i++) {
 +      cfg = client.getSystemConfiguration(creds);
 +      if ("500M".equals(cfg.get("table.split.threshold")))
 +        break;
 +      UtilWaitThread.sleep(200);
 +    }
 +    assertEquals("500M", cfg.get("table.split.threshold"));
 +    
 +    // unset the setting, check that it's not what it was
 +    client.removeProperty(creds, "table.split.threshold");
 +    for (int i = 0; i < 5; i++) {
 +      cfg = client.getSystemConfiguration(creds);
 +      if (!"500M".equals(cfg.get("table.split.threshold")))
 +        break;
 +      UtilWaitThread.sleep(200);
 +    }
 +    assertNotEquals("500M", cfg.get("table.split.threshold"));
 +    
 +    // try to load some classes via the proxy
 +    assertTrue(client.testClassLoad(creds, DevNull.class.getName(), SortedKeyValueIterator.class.getName()));
 +    assertFalse(client.testClassLoad(creds, "foo.bar", SortedKeyValueIterator.class.getName()));
 +    
 +    // create a table that's very slow, so we can look for scans/compactions
 +    client.createTable(creds, "slow", true, TimeType.MILLIS);
 +    IteratorSetting setting = new IteratorSetting(100, "slow", SlowIterator.class.getName(), Collections.singletonMap("sleepTime", "200"));
 +    client.attachIterator(creds, "slow", setting, EnumSet.allOf(IteratorScope.class));
 +    client.updateAndFlush(creds, "slow", mutation("row", "cf", "cq", "value"));
 +    client.updateAndFlush(creds, "slow", mutation("row2", "cf", "cq", "value"));
 +    client.updateAndFlush(creds, "slow", mutation("row3", "cf", "cq", "value"));
 +    client.updateAndFlush(creds, "slow", mutation("row4", "cf", "cq", "value"));
 +    
 +    // scan
 +    Thread t = new Thread() {
 +      @Override
 +      public void run() {
 +        String scanner;
 +        try {
 +          Client client2 = new TestProxyClient("localhost", proxyPort, protocolClass.newInstance()).proxy();
 +          scanner = client2.createScanner(creds, "slow", null);
 +          client2.nextK(scanner, 10);
 +          client2.closeScanner(scanner);
 +        } catch (Exception e) {
 +          throw new RuntimeException(e);
 +        }
 +      }
 +    };
 +    t.start();
 +    // look for the scan
 +    List<ActiveScan> scans = Collections.emptyList();
 +    loop: for (int i = 0; i < 100; i++) {
 +      for (String tserver : client.getTabletServers(creds)) {
 +        scans = client.getActiveScans(creds, tserver);
 +        if (!scans.isEmpty())
 +          break loop;
 +        UtilWaitThread.sleep(10);
 +      }
 +    }
 +    t.join();
 +    assertFalse(scans.isEmpty());
 +    ActiveScan scan = scans.get(0);
 +    assertEquals("root", scan.getUser());
 +    assertTrue(ScanState.RUNNING.equals(scan.getState()) || ScanState.QUEUED.equals(scan.getState()));
 +    assertEquals(ScanType.SINGLE, scan.getType());
 +    assertEquals("slow", scan.getTable());
 +    Map<String,String> map = client.tableIdMap(creds);
 +    assertEquals(map.get("slow"), scan.getExtent().tableId);
 +    assertTrue(scan.getExtent().endRow == null);
 +    assertTrue(scan.getExtent().prevEndRow == null);
 +    
 +    // start a compaction
 +    t = new Thread() {
 +      @Override
 +      public void run() {
 +        try {
 +          Client client2 = new TestProxyClient("localhost", proxyPort, protocolClass.newInstance()).proxy();
 +          client2.compactTable(creds, "slow", null, null, null, true, true);
 +        } catch (Exception e) {
 +          throw new RuntimeException(e);
 +        }
 +      }
 +    };
 +    t.start();
 +    
 +    // try to catch it in the act
 +    List<ActiveCompaction> compactions = Collections.emptyList();
 +    loop2: for (int i = 0; i < 100; i++) {
 +      for (String tserver : client.getTabletServers(creds)) {
 +        compactions = client.getActiveCompactions(creds, tserver);
 +        if (!compactions.isEmpty())
 +          break loop2;
 +      }
 +      UtilWaitThread.sleep(10);
 +    }
 +    t.join();
 +    // verify the compaction information
 +    assertFalse(compactions.isEmpty());
 +    ActiveCompaction c = compactions.get(0);
 +    assertEquals(map.get("slow"), c.getExtent().tableId);
 +    assertTrue(c.inputFiles.isEmpty());
 +    assertEquals(CompactionType.MINOR, c.getType());
 +    assertEquals(CompactionReason.USER, c.getReason());
 +    assertEquals("", c.localityGroup);
 +    assertTrue(c.outputFile.contains("default_tablet"));
 +  }
 +  
 +  @Test
 +  public void testSecurityOperations() throws Exception {
 +    // check password
 +    assertTrue(client.authenticateUser(creds, "root", s2pp(secret)));
 +    assertFalse(client.authenticateUser(creds, "root", s2pp("")));
 +    
 +    // create a user
 +    client.createLocalUser(creds, "stooge", s2bb("password"));
 +    // change auths
 +    Set<String> users = client.listLocalUsers(creds);
 +    assertEquals(new HashSet<String>(Arrays.asList("root", "stooge")), users);
 +    HashSet<ByteBuffer> auths = new HashSet<ByteBuffer>(Arrays.asList(s2bb("A"), s2bb("B")));
 +    client.changeUserAuthorizations(creds, "stooge", auths);
 +    List<ByteBuffer> update = client.getUserAuthorizations(creds, "stooge");
 +    assertEquals(auths, new HashSet<ByteBuffer>(update));
 +    
 +    // change password
 +    client.changeLocalUserPassword(creds, "stooge", s2bb(""));
 +    assertTrue(client.authenticateUser(creds, "stooge", s2pp("")));
 +    
 +    // check permission failure
 +    @SuppressWarnings("serial")
 +    ByteBuffer stooge = client.login("stooge", new TreeMap<String,String>() {
 +      {
 +        put("password", "");
 +      }
 +    });
 +    
 +    try {
 +      client.createTable(stooge, "fail", true, TimeType.MILLIS);
 +      fail("should not create the table");
 +    } catch (AccumuloSecurityException ex) {
 +      assertFalse(client.listTables(creds).contains("fail"));
 +    }
 +    // grant permissions and test
 +    assertFalse(client.hasSystemPermission(creds, "stooge", SystemPermission.CREATE_TABLE));
 +    client.grantSystemPermission(creds, "stooge", SystemPermission.CREATE_TABLE);
 +    assertTrue(client.hasSystemPermission(creds, "stooge", SystemPermission.CREATE_TABLE));
 +    client.createTable(stooge, "success", true, TimeType.MILLIS);
 +    client.listTables(creds).contains("succcess");
 +    
 +    // revoke permissions
 +    client.revokeSystemPermission(creds, "stooge", SystemPermission.CREATE_TABLE);
 +    assertFalse(client.hasSystemPermission(creds, "stooge", SystemPermission.CREATE_TABLE));
 +    try {
 +      client.createTable(stooge, "fail", true, TimeType.MILLIS);
 +      fail("should not create the table");
 +    } catch (AccumuloSecurityException ex) {
 +      assertFalse(client.listTables(creds).contains("fail"));
 +    }
 +    // create a table to test table permissions
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    // denied!
 +    try {
 +      String scanner = client.createScanner(stooge, TABLE_TEST, null);
 +      client.nextK(scanner, 100);
 +      fail("stooge should not read table test");
 +    } catch (AccumuloSecurityException ex) {}
 +    // grant
 +    assertFalse(client.hasTablePermission(creds, "stooge", TABLE_TEST, TablePermission.READ));
 +    client.grantTablePermission(creds, "stooge", TABLE_TEST, TablePermission.READ);
 +    assertTrue(client.hasTablePermission(creds, "stooge", TABLE_TEST, TablePermission.READ));
 +    String scanner = client.createScanner(stooge, TABLE_TEST, null);
 +    client.nextK(scanner, 10);
 +    client.closeScanner(scanner);
 +    // revoke
 +    client.revokeTablePermission(creds, "stooge", TABLE_TEST, TablePermission.READ);
 +    assertFalse(client.hasTablePermission(creds, "stooge", TABLE_TEST, TablePermission.READ));
 +    try {
 +      scanner = client.createScanner(stooge, TABLE_TEST, null);
 +      client.nextK(scanner, 100);
 +      fail("stooge should not read table test");
 +    } catch (AccumuloSecurityException ex) {}
 +    
 +    // delete user
 +    client.dropLocalUser(creds, "stooge");
 +    users = client.listLocalUsers(creds);
 +    assertEquals(1, users.size());
 +    
 +  }
 +  
 +  @Test
 +  public void testBatchWriter() throws Exception {
 +    if (client.tableExists(creds, TABLE_TEST))
 +      client.deleteTable(creds, TABLE_TEST);
 +    
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    client.addConstraint(creds, TABLE_TEST, NumericValueConstraint.class.getName());
 +    
 +    WriterOptions writerOptions = new WriterOptions();
 +    writerOptions.setLatencyMs(10000);
 +    writerOptions.setMaxMemory(2);
 +    writerOptions.setThreads(1);
 +    writerOptions.setTimeoutMs(100000);
 +    
 +    String batchWriter = client.createWriter(creds, TABLE_TEST, writerOptions);
 +    client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
 +    client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
 +    try {
 +      client.flush(batchWriter);
 +      fail("constraint did not fire");
 +    } catch (MutationsRejectedException ex) {}
 +    try {
 +      client.closeWriter(batchWriter);
 +      fail("constraint did not fire");
 +    } catch (MutationsRejectedException e) {}
 +    
 +    client.removeConstraint(creds, TABLE_TEST, 1);
 +    
 +    writerOptions = new WriterOptions();
 +    writerOptions.setLatencyMs(10000);
 +    writerOptions.setMaxMemory(3000);
 +    writerOptions.setThreads(1);
 +    writerOptions.setTimeoutMs(100000);
 +    
 +    batchWriter = client.createWriter(creds, TABLE_TEST, writerOptions);
 +    
 +    client.update(batchWriter, mutation("row1", "cf", "cq", "x"));
 +    client.flush(batchWriter);
 +    client.closeWriter(batchWriter);
 +    
 +    String scanner = client.createScanner(creds, TABLE_TEST, null);
 +    ScanResult more = client.nextK(scanner, 2);
 +    assertEquals(1, more.getResults().size());
 +    client.closeScanner(scanner);
 +    
 +    client.deleteTable(creds, TABLE_TEST);
 +  }
 +  
 +  @Test
 +  public void testTableOperations() throws Exception {
 +    if (client.tableExists(creds, TABLE_TEST))
 +      client.deleteTable(creds, TABLE_TEST);
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    // constraints
 +    client.addConstraint(creds, TABLE_TEST, NumericValueConstraint.class.getName());
 +    client.updateAndFlush(creds, TABLE_TEST, mutation("row1", "cf", "cq", "123"));
 +    
 +    try {
 +      client.updateAndFlush(creds, TABLE_TEST, mutation("row1", "cf", "cq", "x"));
 +      fail("constraint did not fire");
 +    } catch (MutationsRejectedException ex) {}
 +    
 +    client.removeConstraint(creds, TABLE_TEST, 1);
 +    assertEquals(0, client.listConstraints(creds, TABLE_TEST).size());
 +    client.updateAndFlush(creds, TABLE_TEST, mutation("row1", "cf", "cq", "x"));
 +    String scanner = client.createScanner(creds, TABLE_TEST, null);
 +    ScanResult more = client.nextK(scanner, 2);
 +    client.closeScanner(scanner);
 +    assertFalse(more.isMore());
 +    assertEquals(1, more.getResults().size());
 +    assertEquals(s2bb("x"), more.getResults().get(0).value);
 +    // splits, merge
 +    client.addSplits(creds, TABLE_TEST, new HashSet<ByteBuffer>(Arrays.asList(s2bb("a"), s2bb("m"), s2bb("z"))));
 +    List<ByteBuffer> splits = client.listSplits(creds, TABLE_TEST, 1);
 +    assertEquals(Arrays.asList(s2bb("m")), splits);
 +    client.mergeTablets(creds, TABLE_TEST, null, s2bb("m"));
 +    splits = client.listSplits(creds, TABLE_TEST, 10);
 +    assertEquals(Arrays.asList(s2bb("m"), s2bb("z")), splits);
 +    client.mergeTablets(creds, TABLE_TEST, null, null);
 +    splits = client.listSplits(creds, TABLE_TEST, 10);
 +    List<ByteBuffer> empty = Collections.emptyList();
 +    assertEquals(empty, splits);
 +    // iterators
 +    client.deleteTable(creds, TABLE_TEST);
 +    client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
 +    HashMap<String,String> options = new HashMap<String,String>();
 +    options.put("type", "STRING");
 +    options.put("columns", "cf");
 +    IteratorSetting setting = new IteratorSetting(10, TABLE_TEST, SummingCombiner.class.getName(), options);
 +    client.attachIterator(creds, TABLE_TEST, setting, EnumSet.allOf(IteratorScope.class));
 +    for (int i = 0; i < 10; i++) {
 +      client.updateAndFlush(creds, TABLE_TEST, mutation("row1", "cf", "cq", "1"));
 +    }
 +    scanner = client.createScanner(creds, TABLE_TEST, null);
 +    more = client.nextK(scanner, 2);
 +    client.closeScanner(scanner);
 +    assertEquals("10", new String(more.getResults().get(0).getValue()));
 +    try {
 +      client.checkIteratorConflicts(creds, TABLE_TEST, setting, EnumSet.allOf(IteratorScope.class));
 +      fail("checkIteratorConflicts did not throw and exception");
 +    } catch (Exception ex) {}
 +    client.deleteRows(creds, TABLE_TEST, null, null);
 +    client.removeIterator(creds, TABLE_TEST, "test", EnumSet.allOf(IteratorScope.class));
 +    for (int i = 0; i < 10; i++) {
 +      client.updateAndFlush(creds, TABLE_TEST, mutation("row" + i, "cf", "cq", "" + i));
 +      client.flushTable(creds, TABLE_TEST, null, null, true);
 +    }
 +    scanner = client.createScanner(creds, TABLE_TEST, null);
 +    more = client.nextK(scanner, 100);
 +    client.closeScanner(scanner);
 +    assertEquals(10, more.getResults().size());
 +    // clone
 +    client.cloneTable(creds, TABLE_TEST, "test2", true, null, null);
 +    scanner = client.createScanner(creds, "test2", null);
 +    more = client.nextK(scanner, 100);
 +    client.closeScanner(scanner);
 +    assertEquals(10, more.getResults().size());
 +    client.deleteTable(creds, "test2");
 +    
 +    // don't know how to test this, call it just for fun
 +    client.clearLocatorCache(creds, TABLE_TEST);
 +    
 +    // compact
 +    client.compactTable(creds, TABLE_TEST, null, null, null, true, true);
 +    assertEquals(1, countFiles(TABLE_TEST));
 +    
 +    // export/import
 +    String dir = folder.getRoot() + "/test";
 +    String destDir = folder.getRoot() + "/test_dest";
 +    client.offlineTable(creds, TABLE_TEST);
 +    client.exportTable(creds, TABLE_TEST, dir);
 +    // copy files to a new location
 +    FileSystem fs = FileSystem.get(new Configuration());
 +    FSDataInputStream is = fs.open(new Path(dir + "/distcp.txt"));
 +    BufferedReader r = new BufferedReader(new InputStreamReader(is));
 +    while (true) {
 +      String line = r.readLine();
 +      if (line == null)
 +        break;
 +      Path srcPath = new Path(line);
 +      FileUtils.copyFile(new File(srcPath.toUri().getPath()), new File(destDir, srcPath.getName()));
 +    }
 +    client.deleteTable(creds, TABLE_TEST);
 +    client.importTable(creds, "testify", destDir);
 +    scanner = client.createScanner(creds, "testify", null);
 +    more = client.nextK(scanner, 100);
 +    client.closeScanner(scanner);
 +    assertEquals(10, more.results.size());
 +    
 +    try {
 +      // ACCUMULO-1558 a second import from the same dir should fail, the first import moved the files
 +      client.importTable(creds, "testify2", destDir);
 +      fail();
 +    } catch (Exception e) {}
 +
 +    assertFalse(client.listTables(creds).contains("testify2"));
 +
 +    // Locality groups
 +    client.createTable(creds, "test", true, TimeType.MILLIS);
 +    Map<String,Set<String>> groups = new HashMap<String,Set<String>>();
 +    groups.put("group1", Collections.singleton("cf1"));
 +    groups.put("group2", Collections.singleton("cf2"));
 +    client.setLocalityGroups(creds, "test", groups);
 +    assertEquals(groups, client.getLocalityGroups(creds, "test"));
 +    // table properties
 +    Map<String,String> orig = client.getTableProperties(creds, "test");
 +    client.setTableProperty(creds, "test", "table.split.threshold", "500M");
 +    Map<String,String> update = client.getTableProperties(creds, "test");
 +    for (int i = 0; i < 5; i++) {
 +      if (update.get("table.split.threshold").equals("500M"))
 +        break;
 +      UtilWaitThread.sleep(200);
 +    }
 +    assertEquals(update.get("table.split.threshold"), "500M");
 +    client.removeTableProperty(creds, "test", "table.split.threshold");
 +    update = client.getTableProperties(creds, "test");
 +    assertEquals(orig, update);
 +    // rename table
 +    Map<String,String> tables = client.tableIdMap(creds);
 +    client.renameTable(creds, "test", "bar");
 +    Map<String,String> tables2 = client.tableIdMap(creds);
 +    assertEquals(tables.get("test"), tables2.get("bar"));
 +    // table exists
 +    assertTrue(client.tableExists(creds, "bar"));
 +    assertFalse(client.tableExists(creds, "test"));
 +    // bulk import
 +    String filename = dir + "/bulk/import/rfile.rf";
 +    FileSKVWriter writer = FileOperations.getInstance().openWriter(filename, fs, fs.getConf(), DefaultConfiguration.getInstance());
 +    writer.startDefaultLocalityGroup();
 +    writer.append(new org.apache.accumulo.core.data.Key(new Text("a"), new Text("b"), new Text("c")), new Value("value".getBytes()));
 +    writer.close();
 +    fs.mkdirs(new Path(dir + "/bulk/fail"));
 +    client.importDirectory(creds, "bar", dir + "/bulk/import", dir + "/bulk/fail", true);
 +    scanner = client.createScanner(creds, "bar", null);
 +    more = client.nextK(scanner, 100);
 +    client.closeScanner(scanner);
 +    assertEquals(1, more.results.size());
 +    ByteBuffer maxRow = client.getMaxRow(creds, "bar", null, null, false, null, false);
 +    assertEquals(s2bb("a"), maxRow);
 +    
 +    assertFalse(client.testTableClassLoad(creds, "bar", "abc123", SortedKeyValueIterator.class.getName()));
 +    assertTrue(client.testTableClassLoad(creds, "bar", VersioningIterator.class.getName(), SortedKeyValueIterator.class.getName()));
 +  }
 +  
 +  // scan !METADATA table for file entries for the given table
 +  private int countFiles(String table) throws Exception {
 +    Map<String,String> tableIdMap = client.tableIdMap(creds);
 +    String tableId = tableIdMap.get(table);
 +    Key start = new Key();
 +    start.row = s2bb(tableId + ";");
 +    Key end = new Key();
 +    end.row = s2bb(tableId + "<");
 +    end = client.getFollowing(end, PartialKey.ROW);
 +    ScanOptions opt = new ScanOptions();
 +    opt.range = new Range(start, true, end, false);
 +    opt.columns = Collections.singletonList(new ScanColumn(s2bb("file")));
 +    String scanner = client.createScanner(creds, Constants.METADATA_TABLE_NAME, opt);
 +    int result = 0;
 +    while (true) {
 +      ScanResult more = client.nextK(scanner, 100);
 +      result += more.getResults().size();
 +      if (!more.more)
 +        break;
 +    }
 +    return result;
 +  }
 +  
 +  private Map<ByteBuffer,List<ColumnUpdate>> mutation(String row, String cf, String cq, String value) {
 +    ColumnUpdate upd = new ColumnUpdate(s2bb(cf), s2bb(cq));
 +    upd.setValue(value.getBytes());
 +    return Collections.singletonMap(s2bb(row), Collections.singletonList(upd));
 +  }
 +  
 +  private ByteBuffer s2bb(String cf) {
 +    return ByteBuffer.wrap(cf.getBytes());
 +  }
 +  
 +  private Map<String,String> s2pp(String cf) {
 +    Map<String,String> toRet = new TreeMap<String,String>();
 +    toRet.put("password", cf);
 +    return toRet;
 +  }
 +  
 +  @AfterClass
 +  public static void tearDownMiniCluster() throws Exception {
 +    accumulo.stop();
 +    folder.delete();
 +  }
 +  
 +}


[3/4] git commit: ACCUMULO-1800 fix deletes, added test

Posted by ec...@apache.org.
ACCUMULO-1800 fix deletes, added test


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/3143b9c5
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/3143b9c5
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/3143b9c5

Branch: refs/heads/master
Commit: 3143b9c5ed639818dd8d8349237815b54f5c1a6a
Parents: 1c8f7f5 ffd16c7
Author: Eric Newton <er...@gmail.com>
Authored: Tue Oct 22 10:25:06 2013 -0400
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Oct 22 10:25:06 2013 -0400

----------------------------------------------------------------------
 .../org/apache/accumulo/proxy/ProxyServer.java  | 12 +++++-----
 .../org/apache/accumulo/proxy/SimpleTest.java   | 25 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/3143b9c5/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
----------------------------------------------------------------------
diff --cc proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
index 3c5c88a,0000000..c6e74f1
mode 100644,000000..100644
--- a/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
@@@ -1,1473 -1,0 +1,1473 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.accumulo.proxy;
 +
 +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.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.Set;
 +import java.util.SortedSet;
 +import java.util.TreeSet;
 +import java.util.UUID;
 +import java.util.concurrent.TimeUnit;
 +
 +import org.apache.accumulo.core.client.AccumuloException;
 +import org.apache.accumulo.core.client.AccumuloSecurityException;
 +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.Connector;
 +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.Scanner;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.client.TableExistsException;
 +import org.apache.accumulo.core.client.TableNotFoundException;
 +import org.apache.accumulo.core.client.ZooKeeperInstance;
 +import org.apache.accumulo.core.client.admin.ActiveCompaction;
 +import org.apache.accumulo.core.client.admin.ActiveScan;
 +import org.apache.accumulo.core.client.admin.TimeType;
 +import org.apache.accumulo.core.client.impl.thrift.TableOperationExceptionType;
 +import org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException;
 +import org.apache.accumulo.core.client.mock.MockInstance;
 +import org.apache.accumulo.core.client.security.SecurityErrorCode;
 +import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
 +import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 +import org.apache.accumulo.core.data.Column;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Mutation;
 +import org.apache.accumulo.core.data.PartialKey;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
 +import org.apache.accumulo.core.security.Authorizations;
 +import org.apache.accumulo.core.security.ColumnVisibility;
 +import org.apache.accumulo.core.security.CredentialHelper;
 +import org.apache.accumulo.core.security.SystemPermission;
 +import org.apache.accumulo.core.security.TablePermission;
 +import org.apache.accumulo.core.security.thrift.TCredentials;
 +import org.apache.accumulo.core.util.ByteBufferUtil;
 +import org.apache.accumulo.core.util.TextUtil;
 +import org.apache.accumulo.proxy.thrift.AccumuloProxy;
 +import org.apache.accumulo.proxy.thrift.BatchScanOptions;
 +import org.apache.accumulo.proxy.thrift.ColumnUpdate;
 +import org.apache.accumulo.proxy.thrift.CompactionReason;
 +import org.apache.accumulo.proxy.thrift.CompactionType;
 +import org.apache.accumulo.proxy.thrift.KeyValue;
 +import org.apache.accumulo.proxy.thrift.KeyValueAndPeek;
 +import org.apache.accumulo.proxy.thrift.NoMoreEntriesException;
 +import org.apache.accumulo.proxy.thrift.ScanColumn;
 +import org.apache.accumulo.proxy.thrift.ScanOptions;
 +import org.apache.accumulo.proxy.thrift.ScanResult;
 +import org.apache.accumulo.proxy.thrift.ScanState;
 +import org.apache.accumulo.proxy.thrift.ScanType;
 +import org.apache.accumulo.proxy.thrift.UnknownScanner;
 +import org.apache.accumulo.proxy.thrift.UnknownWriter;
 +import org.apache.accumulo.proxy.thrift.WriterOptions;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +import org.apache.thrift.TException;
 +
 +import com.google.common.cache.Cache;
 +import com.google.common.cache.CacheBuilder;
 +import com.google.common.cache.RemovalListener;
 +import com.google.common.cache.RemovalNotification;
 +
 +/**
 + * Proxy Server exposing the Accumulo API via Thrift..
 + * 
 + * @since 1.5
 + */
 +public class ProxyServer implements AccumuloProxy.Iface {
 +  
 +  public static final Logger logger = Logger.getLogger(ProxyServer.class);
 +  protected Instance instance;
 +  
 +  protected Class<? extends AuthenticationToken> tokenClass;
 +  
 +  static protected class ScannerPlusIterator {
 +    public ScannerBase scanner;
 +    public Iterator<Map.Entry<Key,Value>> iterator;
 +  }
 +  
 +  static protected class BatchWriterPlusException {
 +    public BatchWriter writer;
 +    public MutationsRejectedException exception = null;
 +  }
 +  
 +  static class CloseWriter implements RemovalListener<UUID,BatchWriterPlusException> {
 +    @Override
 +    public void onRemoval(RemovalNotification<UUID,BatchWriterPlusException> notification) {
 +      try {
 +        BatchWriterPlusException value = notification.getValue();
 +        if (value.exception != null)
 +          throw value.exception;
 +        notification.getValue().writer.close();
 +      } catch (MutationsRejectedException e) {
 +        logger.warn(e, e);
 +      }
 +    }
 +    
 +    public CloseWriter() {}
 +  }
 +  
 +  static class CloseScanner implements RemovalListener<UUID,ScannerPlusIterator> {
 +    @Override
 +    public void onRemoval(RemovalNotification<UUID,ScannerPlusIterator> notification) {
 +      final ScannerBase base = notification.getValue().scanner;
 +      if (base instanceof BatchScanner) {
 +        final BatchScanner scanner = (BatchScanner) base;
 +        scanner.close();
 +      }
 +    }
 +    
 +    public CloseScanner() {}
 +  }
 +  
 +  protected Cache<UUID,ScannerPlusIterator> scannerCache;
 +  protected Cache<UUID,BatchWriterPlusException> writerCache;
 +  
 +  public ProxyServer(Properties props) {
 +    
 +    String useMock = props.getProperty("useMockInstance");
 +    if (useMock != null && Boolean.parseBoolean(useMock))
 +      instance = new MockInstance();
 +    else
 +      instance = new ZooKeeperInstance(props.getProperty("instance"), props.getProperty("zookeepers"));
 +    
 +    try {
 +      String tokenProp = props.getProperty("tokenClass", PasswordToken.class.getName());
 +      tokenClass = Class.forName(tokenProp).asSubclass(AuthenticationToken.class);
 +    } catch (ClassNotFoundException e) {
 +      throw new RuntimeException(e);
 +    }
 +    
 +    scannerCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).maximumSize(1000).removalListener(new CloseScanner()).build();
 +    
 +    writerCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).maximumSize(1000).removalListener(new CloseWriter()).build();
 +  }
 +  
 +  protected Connector getConnector(ByteBuffer login) throws Exception {
 +    TCredentials user = CredentialHelper.fromByteArray(ByteBufferUtil.toBytes(login));
 +    if (user == null)
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException("unknown user");
 +    Connector connector = instance.getConnector(user.getPrincipal(), CredentialHelper.extractToken(user));
 +    return connector;
 +  }
 +  
 +  private void handleAccumuloException(AccumuloException e) throws org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.AccumuloException {
 +    if (e.getCause() instanceof ThriftTableOperationException) {
 +      ThriftTableOperationException ttoe = (ThriftTableOperationException) e.getCause();
 +      if (ttoe.type == TableOperationExceptionType.NOTFOUND) {
 +        throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(e.toString());
 +      }
 +    }
 +    throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +  }
 +  
 +  private void handleAccumuloSecurityException(AccumuloSecurityException e) throws org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException {
 +    if (e.getSecurityErrorCode().equals(SecurityErrorCode.TABLE_DOESNT_EXIST))
 +      throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(e.toString());
 +    throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException(e.toString());
 +  }
 +
 +  private void handleExceptionTNF(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      throw ex;
 +    } catch (AccumuloException e) {
 +      handleAccumuloException(e);
 +    } catch (AccumuloSecurityException e) {
 +      handleAccumuloSecurityException(e);
 +    } catch (TableNotFoundException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(ex.toString());
 +    } catch (Exception e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +    }
 +  }
 +
 +  private void handleExceptionTEE(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.TableExistsException, TException {
 +    try {
 +      throw ex;
 +    } catch (AccumuloException e) {
 +      handleAccumuloException(e);
 +    } catch (AccumuloSecurityException e) {
 +      handleAccumuloSecurityException(e);
 +    } catch (TableNotFoundException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(ex.toString());
 +    } catch (TableExistsException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableExistsException(e.toString());
 +    } catch (Exception e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +    }
 +  }
 +  
 +  private void handleExceptionMRE(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
 +    try {
 +      throw ex;
 +    } catch (MutationsRejectedException e) {
 +      throw new org.apache.accumulo.proxy.thrift.MutationsRejectedException(ex.toString());
 +    } catch (AccumuloException e) {
 +      handleAccumuloException(e);
 +    } catch (AccumuloSecurityException e) {
 +      handleAccumuloSecurityException(e);
 +    } catch (TableNotFoundException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(ex.toString());
 +    } catch (Exception e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +    }
 +  }
 +  
 +  private void handleException(Exception ex) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      throw ex;
 +    } catch (AccumuloException e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +    } catch (AccumuloSecurityException e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException(e.toString());
 +    } catch (Exception e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloException(e.toString());
 +    }
 +  }
 +
 +  @Override
 +  public int addConstraint(ByteBuffer login, String tableName, String constraintClassName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    
 +    try {
 +      return getConnector(login).tableOperations().addConstraint(tableName, constraintClassName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return -1;
 +    }
 +  }
 +  
 +  @Override
 +  public void addSplits(ByteBuffer login, String tableName, Set<ByteBuffer> splits) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    
 +    try {
 +      SortedSet<Text> sorted = new TreeSet<Text>();
 +      for (ByteBuffer split : splits) {
 +        sorted.add(ByteBufferUtil.toText(split));
 +      }
 +      getConnector(login).tableOperations().addSplits(tableName, sorted);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void clearLocatorCache(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().clearLocatorCache(tableName);
 +    } catch (TableNotFoundException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableNotFoundException(e.toString());
 +    } catch (Exception e) {
 +      throw new TException(e.toString());
 +    }
 +  }
 +  
 +  @Override
 +  public void compactTable(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow,
 +      List<org.apache.accumulo.proxy.thrift.IteratorSetting> iterators, boolean flush, boolean wait)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.AccumuloException, TException {
 +    try {
 +      getConnector(login).tableOperations().compact(tableName, ByteBufferUtil.toText(startRow), ByteBufferUtil.toText(endRow), getIteratorSettings(iterators),
 +          flush, wait);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void cancelCompaction(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, org.apache.accumulo.proxy.thrift.AccumuloException, TException {
 +    
 +    try {
 +      getConnector(login).tableOperations().cancelCompaction(tableName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  private List<IteratorSetting> getIteratorSettings(List<org.apache.accumulo.proxy.thrift.IteratorSetting> iterators) {
 +    List<IteratorSetting> result = new ArrayList<IteratorSetting>();
 +    if (iterators != null) {
 +      for (org.apache.accumulo.proxy.thrift.IteratorSetting is : iterators) {
 +        result.add(getIteratorSetting(is));
 +      }
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public void createTable(ByteBuffer login, String tableName, boolean versioningIter, org.apache.accumulo.proxy.thrift.TimeType type)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableExistsException, TException {
 +    try {
 +      if (type == null)
 +        type = org.apache.accumulo.proxy.thrift.TimeType.MILLIS;
 +      
 +      getConnector(login).tableOperations().create(tableName, versioningIter, TimeType.valueOf(type.toString()));
 +    } catch (TableExistsException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableExistsException(e.toString());
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void deleteTable(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().delete(tableName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void deleteRows(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().deleteRows(tableName, ByteBufferUtil.toText(startRow), ByteBufferUtil.toText(endRow));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public boolean tableExists(ByteBuffer login, String tableName) throws TException {
 +    try {
 +      return getConnector(login).tableOperations().exists(tableName);
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public 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,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().flush(tableName, ByteBufferUtil.toText(startRow), ByteBufferUtil.toText(endRow), wait);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,Set<String>> getLocalityGroups(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Map<String,Set<Text>> groups = getConnector(login).tableOperations().getLocalityGroups(tableName);
 +      Map<String,Set<String>> ret = new HashMap<String,Set<String>>();
 +      for (String key : groups.keySet()) {
 +        ret.put(key, new HashSet<String>());
 +        for (Text val : groups.get(key)) {
 +          ret.get(key).add(val.toString());
 +        }
 +      }
 +      return ret;
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public 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,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Connector connector = getConnector(login);
 +      Text startText = ByteBufferUtil.toText(startRow);
 +      Text endText = ByteBufferUtil.toText(endRow);
 +      Authorizations auth;
 +      if (auths != null) {
 +        auth = getAuthorizations(auths);
 +      } else {
 +        auth = connector.securityOperations().getUserAuthorizations(connector.whoami());
 +      }
 +      Text max = connector.tableOperations().getMaxRow(tableName, auth, startText, startInclusive, endText, endInclusive);
 +      return TextUtil.getByteBuffer(max);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,String> getTableProperties(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Map<String,String> ret = new HashMap<String,String>();
 +      
 +      for (Map.Entry<String,String> entry : getConnector(login).tableOperations().getProperties(tableName)) {
 +        ret.put(entry.getKey(), entry.getValue());
 +      }
 +      return ret;
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public List<ByteBuffer> listSplits(ByteBuffer login, String tableName, int maxSplits) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Collection<Text> splits = getConnector(login).tableOperations().listSplits(tableName, maxSplits);
 +      List<ByteBuffer> ret = new ArrayList<ByteBuffer>();
 +      for (Text split : splits) {
 +        ret.add(TextUtil.getByteBuffer(split));
 +      }
 +      return ret;
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public Set<String> listTables(ByteBuffer login) throws TException {
 +    try {
 +      return getConnector(login).tableOperations().list();
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,Integer> listConstraints(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    
 +    try {
 +      return getConnector(login).tableOperations().listConstraints(tableName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void mergeTablets(ByteBuffer login, String tableName, ByteBuffer startRow, ByteBuffer endRow)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().merge(tableName, ByteBufferUtil.toText(startRow), ByteBufferUtil.toText(endRow));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void offlineTable(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().offline(tableName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void onlineTable(ByteBuffer login, String tableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().online(tableName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void removeConstraint(ByteBuffer login, String tableName, int constraint) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    
 +    try {
 +      getConnector(login).tableOperations().removeConstraint(tableName, constraint);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void removeTableProperty(ByteBuffer login, String tableName, String property) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().removeProperty(tableName, property);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void renameTable(ByteBuffer login, String oldTableName, String newTableName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException,
 +      org.apache.accumulo.proxy.thrift.TableExistsException, TException {
 +    try {
 +      getConnector(login).tableOperations().rename(oldTableName, newTableName);
 +    } catch (Exception e) {
 +      handleExceptionTEE(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void setLocalityGroups(ByteBuffer login, String tableName, Map<String,Set<String>> groupStrings)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Map<String,Set<Text>> groups = new HashMap<String,Set<Text>>();
 +      for (String key : groupStrings.keySet()) {
 +        groups.put(key, new HashSet<Text>());
 +        for (String val : groupStrings.get(key)) {
 +          groups.get(key).add(new Text(val));
 +        }
 +      }
 +      getConnector(login).tableOperations().setLocalityGroups(tableName, groups);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void setTableProperty(ByteBuffer login, String tableName, String property, String value) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().setProperty(tableName, property, value);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,String> tableIdMap(ByteBuffer login) throws TException {
 +    try {
 +      return getConnector(login).tableOperations().tableIdMap();
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,String> getSiteConfiguration(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).instanceOperations().getSiteConfiguration();
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,String> getSystemConfiguration(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).instanceOperations().getSystemConfiguration();
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public List<String> getTabletServers(ByteBuffer login) throws TException {
 +    try {
 +      return getConnector(login).instanceOperations().getTabletServers();
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public List<org.apache.accumulo.proxy.thrift.ActiveScan> getActiveScans(ByteBuffer login, String tserver)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    List<org.apache.accumulo.proxy.thrift.ActiveScan> result = new ArrayList<org.apache.accumulo.proxy.thrift.ActiveScan>();
 +    try {
 +      List<ActiveScan> activeScans = getConnector(login).instanceOperations().getActiveScans(tserver);
 +      for (ActiveScan scan : activeScans) {
 +        org.apache.accumulo.proxy.thrift.ActiveScan pscan = new org.apache.accumulo.proxy.thrift.ActiveScan();
 +        pscan.client = scan.getClient();
 +        pscan.user = scan.getUser();
 +        pscan.table = scan.getTable();
 +        pscan.age = scan.getAge();
 +        pscan.idleTime = scan.getIdleTime();
 +        pscan.type = ScanType.valueOf(scan.getType().toString());
 +        pscan.state = ScanState.valueOf(scan.getState().toString());
 +        KeyExtent e = scan.getExtent();
 +        pscan.extent = new org.apache.accumulo.proxy.thrift.KeyExtent(e.getTableId().toString(), TextUtil.getByteBuffer(e.getEndRow()),
 +            TextUtil.getByteBuffer(e.getPrevEndRow()));
 +        pscan.columns = new ArrayList<org.apache.accumulo.proxy.thrift.Column>();
 +        if (scan.getColumns() != null) {
 +          for (Column c : scan.getColumns()) {
 +            org.apache.accumulo.proxy.thrift.Column column = new org.apache.accumulo.proxy.thrift.Column();
 +            column.setColFamily(c.getColumnFamily());
 +            column.setColQualifier(c.getColumnQualifier());
 +            column.setColVisibility(c.getColumnVisibility());
 +            pscan.columns.add(column);
 +          }
 +        }
 +        pscan.iterators = new ArrayList<org.apache.accumulo.proxy.thrift.IteratorSetting>();
 +        for (String iteratorString : scan.getSsiList()) {
 +          String[] parts = iteratorString.split("[=,]");
 +          if (parts.length == 3) {
 +            String name = parts[0];
 +            int priority = Integer.parseInt(parts[1]);
 +            String classname = parts[2];
 +            org.apache.accumulo.proxy.thrift.IteratorSetting settings = new org.apache.accumulo.proxy.thrift.IteratorSetting(priority, name, classname, scan
 +                .getSsio().get(name));
 +            pscan.iterators.add(settings);
 +          }
 +        }
 +        pscan.authorizations = new ArrayList<ByteBuffer>();
 +        if (scan.getAuthorizations() != null) {
 +          for (byte[] a : scan.getAuthorizations()) {
 +            pscan.authorizations.add(ByteBuffer.wrap(a));
 +          }
 +        }
 +        result.add(pscan);
 +      }
 +      return result;
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public List<org.apache.accumulo.proxy.thrift.ActiveCompaction> getActiveCompactions(ByteBuffer login, String tserver)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    
 +    try {
 +      List<org.apache.accumulo.proxy.thrift.ActiveCompaction> result = new ArrayList<org.apache.accumulo.proxy.thrift.ActiveCompaction>();
 +      List<ActiveCompaction> active = getConnector(login).instanceOperations().getActiveCompactions(tserver);
 +      for (ActiveCompaction comp : active) {
 +        org.apache.accumulo.proxy.thrift.ActiveCompaction pcomp = new org.apache.accumulo.proxy.thrift.ActiveCompaction();
 +        pcomp.age = comp.getAge();
 +        pcomp.entriesRead = comp.getEntriesRead();
 +        pcomp.entriesWritten = comp.getEntriesWritten();
 +        KeyExtent e = comp.getExtent();
 +        pcomp.extent = new org.apache.accumulo.proxy.thrift.KeyExtent(e.getTableId().toString(), TextUtil.getByteBuffer(e.getEndRow()),
 +            TextUtil.getByteBuffer(e.getPrevEndRow()));
 +        pcomp.inputFiles = new ArrayList<String>();
 +        if (comp.getInputFiles() != null) {
 +          pcomp.inputFiles.addAll(comp.getInputFiles());
 +        }
 +        pcomp.localityGroup = comp.getLocalityGroup();
 +        pcomp.outputFile = comp.getOutputFile();
 +        pcomp.reason = CompactionReason.valueOf(comp.getReason().toString());
 +        pcomp.type = CompactionType.valueOf(comp.getType().toString());
 +        
 +        pcomp.iterators = new ArrayList<org.apache.accumulo.proxy.thrift.IteratorSetting>();
 +        if (comp.getIterators() != null) {
 +          for (IteratorSetting setting : comp.getIterators()) {
 +            org.apache.accumulo.proxy.thrift.IteratorSetting psetting = new org.apache.accumulo.proxy.thrift.IteratorSetting(setting.getPriority(),
 +                setting.getName(), setting.getIteratorClass(), setting.getOptions());
 +            pcomp.iterators.add(psetting);
 +          }
 +        }
 +        result.add(pcomp);
 +      }
 +      return result;
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void removeProperty(ByteBuffer login, String property) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).instanceOperations().removeProperty(property);
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void setProperty(ByteBuffer login, String property, String value) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).instanceOperations().setProperty(property, value);
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public boolean testClassLoad(ByteBuffer login, String className, String asTypeName) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).instanceOperations().testClassLoad(className, asTypeName);
 +    } catch (Exception e) {
 +      handleException(e);
 +      return false;
 +    }
 +  }
 +  
 +  @Override
 +  public boolean authenticateUser(ByteBuffer login, String user, Map<String,String> properties) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).securityOperations().authenticateUser(user, getToken(user, properties));
 +    } catch (Exception e) {
 +      handleException(e);
 +      return false;
 +    }
 +  }
 +  
 +  @Override
 +  public void changeUserAuthorizations(ByteBuffer login, String user, Set<ByteBuffer> authorizations)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      Set<String> auths = new HashSet<String>();
 +      for (ByteBuffer auth : authorizations) {
 +        auths.add(ByteBufferUtil.toString(auth));
 +      }
 +      getConnector(login).securityOperations().changeUserAuthorizations(user, new Authorizations(auths.toArray(new String[0])));
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void changeLocalUserPassword(ByteBuffer login, String user, ByteBuffer password) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).securityOperations().changeLocalUserPassword(user, new PasswordToken(password));
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void createLocalUser(ByteBuffer login, String user, ByteBuffer password) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).securityOperations().createLocalUser(user, new PasswordToken(password));
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void dropLocalUser(ByteBuffer login, String user) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).securityOperations().dropLocalUser(user);
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public List<ByteBuffer> getUserAuthorizations(ByteBuffer login, String user) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).securityOperations().getUserAuthorizations(user).getAuthorizationsBB();
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void grantSystemPermission(ByteBuffer login, String user, org.apache.accumulo.proxy.thrift.SystemPermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).securityOperations().grantSystemPermission(user, SystemPermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void grantTablePermission(ByteBuffer login, String user, String table, org.apache.accumulo.proxy.thrift.TablePermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).securityOperations().grantTablePermission(user, table, TablePermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public boolean hasSystemPermission(ByteBuffer login, String user, org.apache.accumulo.proxy.thrift.SystemPermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).securityOperations().hasSystemPermission(user, SystemPermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleException(e);
 +      return false;
 +    }
 +  }
 +  
 +  @Override
 +  public boolean hasTablePermission(ByteBuffer login, String user, String table, org.apache.accumulo.proxy.thrift.TablePermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      return getConnector(login).securityOperations().hasTablePermission(user, table, TablePermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return false;
 +    }
 +  }
 +  
 +  @Override
 +  public Set<String> listLocalUsers(ByteBuffer login) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      return getConnector(login).securityOperations().listLocalUsers();
 +    } catch (Exception e) {
 +      handleException(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void revokeSystemPermission(ByteBuffer login, String user, org.apache.accumulo.proxy.thrift.SystemPermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).securityOperations().revokeSystemPermission(user, SystemPermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void revokeTablePermission(ByteBuffer login, String user, String table, org.apache.accumulo.proxy.thrift.TablePermission perm)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).securityOperations().revokeTablePermission(user, table, TablePermission.getPermissionById((byte) perm.getValue()));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  private Authorizations getAuthorizations(Set<ByteBuffer> authorizations) {
 +    List<String> auths = new ArrayList<String>();
 +    for (ByteBuffer bbauth : authorizations) {
 +      auths.add(ByteBufferUtil.toString(bbauth));
 +    }
 +    return new Authorizations(auths.toArray(new String[0]));
 +  }
 +  
 +  @Override
 +  public String createScanner(ByteBuffer login, String tableName, ScanOptions opts) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Connector connector = getConnector(login);
 +      
 +      Authorizations auth;
 +      if (opts != null && opts.isSetAuthorizations()) {
 +        auth = getAuthorizations(opts.authorizations);
 +      } else {
 +        auth = connector.securityOperations().getUserAuthorizations(connector.whoami());
 +      }
 +      Scanner scanner = connector.createScanner(tableName, auth);
 +      
 +      if (opts != null) {
 +        if (opts.iterators != null) {
 +          for (org.apache.accumulo.proxy.thrift.IteratorSetting iter : opts.iterators) {
 +            IteratorSetting is = new IteratorSetting(iter.getPriority(), iter.getName(), iter.getIteratorClass(), iter.getProperties());
 +            scanner.addScanIterator(is);
 +          }
 +        }
 +        org.apache.accumulo.proxy.thrift.Range prange = opts.range;
 +        if (prange != null) {
 +          Range range = new Range(Util.fromThrift(prange.getStart()), prange.startInclusive, Util.fromThrift(prange.getStop()), prange.stopInclusive);
 +          scanner.setRange(range);
 +        }
 +        if (opts.columns != null) {
 +          for (ScanColumn col : opts.columns) {
 +            if (col.isSetColQualifier())
 +              scanner.fetchColumn(ByteBufferUtil.toText(col.colFamily), ByteBufferUtil.toText(col.colQualifier));
 +            else
 +              scanner.fetchColumnFamily(ByteBufferUtil.toText(col.colFamily));
 +          }
 +        }
 +      }
 +      
 +      UUID uuid = UUID.randomUUID();
 +      
 +      ScannerPlusIterator spi = new ScannerPlusIterator();
 +      spi.scanner = scanner;
 +      spi.iterator = scanner.iterator();
 +      scannerCache.put(uuid, spi);
 +      return uuid.toString();
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public String createBatchScanner(ByteBuffer login, String tableName, BatchScanOptions opts) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Connector connector = getConnector(login);
 +      
 +      int threads = 10;
 +      Authorizations auth;
 +      if (opts != null && opts.isSetAuthorizations()) {
 +        auth = getAuthorizations(opts.authorizations);
 +      } else {
 +        auth = connector.securityOperations().getUserAuthorizations(connector.whoami());
 +      }
 +      if (opts != null && opts.threads > 0)
 +        threads = opts.threads;
 +      
 +      BatchScanner scanner = connector.createBatchScanner(tableName, auth, threads);
 +      
 +      if (opts != null) {
 +        if (opts.iterators != null) {
 +          for (org.apache.accumulo.proxy.thrift.IteratorSetting iter : opts.iterators) {
 +            IteratorSetting is = new IteratorSetting(iter.getPriority(), iter.getName(), iter.getIteratorClass(), iter.getProperties());
 +            scanner.addScanIterator(is);
 +          }
 +        }
 +        
 +        ArrayList<Range> ranges = new ArrayList<Range>();
 +        
 +        if (opts.ranges == null) {
 +          ranges.add(new Range());
 +        } else {
 +          for (org.apache.accumulo.proxy.thrift.Range range : opts.ranges) {
 +            Range aRange = new Range(range.getStart() == null ? null : Util.fromThrift(range.getStart()), true, range.getStop() == null ? null
 +                : Util.fromThrift(range.getStop()), false);
 +            ranges.add(aRange);
 +          }
 +        }
 +        scanner.setRanges(ranges);
 +        
 +        if (opts.columns != null) {
 +          for (ScanColumn col : opts.columns) {
 +            if (col.isSetColQualifier())
 +              scanner.fetchColumn(ByteBufferUtil.toText(col.colFamily), ByteBufferUtil.toText(col.colQualifier));
 +            else
 +              scanner.fetchColumnFamily(ByteBufferUtil.toText(col.colFamily));
 +          }
 +        }
 +      }
 +      
 +      UUID uuid = UUID.randomUUID();
 +      
 +      ScannerPlusIterator spi = new ScannerPlusIterator();
 +      spi.scanner = scanner;
 +      spi.iterator = scanner.iterator();
 +      scannerCache.put(uuid, spi);
 +      return uuid.toString();
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  private ScannerPlusIterator getScanner(String scanner) throws UnknownScanner {
 +    
 +    UUID uuid = null;
 +    try {
 +      uuid = UUID.fromString(scanner);
 +    } catch (IllegalArgumentException e) {
 +      throw new UnknownScanner(e.getMessage());
 +    }
 +    
 +    ScannerPlusIterator spi = scannerCache.getIfPresent(uuid);
 +    if (spi == null) {
 +      throw new UnknownScanner("Scanner never existed or no longer exists");
 +    }
 +    return spi;
 +  }
 +  
 +  @Override
 +  public boolean hasNext(String scanner) throws UnknownScanner, TException {
 +    ScannerPlusIterator spi = getScanner(scanner);
 +    
 +    return (spi.iterator.hasNext());
 +  }
 +  
 +  @Override
 +  public KeyValueAndPeek nextEntry(String scanner) throws NoMoreEntriesException, UnknownScanner, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      TException {
 +    
 +    ScanResult scanResult = nextK(scanner, 1);
 +    if (scanResult.results.size() > 0) {
 +      return new KeyValueAndPeek(scanResult.results.get(0), scanResult.isMore());
 +    } else {
 +      throw new NoMoreEntriesException();
 +    }
 +  }
 +  
 +  @Override
 +  public ScanResult nextK(String scanner, int k) throws NoMoreEntriesException, UnknownScanner, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      TException {
 +    
 +    // fetch the scanner
 +    ScannerPlusIterator spi = getScanner(scanner);
 +    Iterator<Map.Entry<Key,Value>> batchScanner = spi.iterator;
 +    // synchronized to prevent race conditions
 +    synchronized (batchScanner) {
 +      ScanResult ret = new ScanResult();
 +      ret.setResults(new ArrayList<KeyValue>());
 +      int numRead = 0;
 +      try {
 +        while (batchScanner.hasNext() && numRead < k) {
 +          Map.Entry<Key,Value> next = batchScanner.next();
 +          ret.addToResults(new KeyValue(Util.toThrift(next.getKey()), ByteBuffer.wrap(next.getValue().get())));
 +          numRead++;
 +        }
 +        ret.setMore(numRead == k);
 +      } catch (Exception ex) {
 +        closeScanner(scanner);
 +        throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException(ex.toString());
 +      }
 +      return ret;
 +    }
 +  }
 +
 +  @Override
 +  public void closeScanner(String scanner) throws UnknownScanner, TException {
 +    UUID uuid = null;
 +    try {
 +      uuid = UUID.fromString(scanner);
 +    } catch (IllegalArgumentException e) {
 +      throw new UnknownScanner(e.getMessage());
 +    }
 +
 +    try {
 +      if (scannerCache.asMap().remove(uuid) == null) {
 +        throw new UnknownScanner("Scanner never existed or no longer exists");
 +      }
 +    } catch (UnknownScanner e) {
 +      throw e;
 +    } catch (Exception e) {
 +      throw new TException(e.toString());
 +    }
 +  }
 +  
 +  @Override
 +  public void updateAndFlush(ByteBuffer login, String tableName, Map<ByteBuffer,List<ColumnUpdate>> cells)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
 +    try {
 +      BatchWriterPlusException bwpe = getWriter(login, tableName, null);
 +      addCellsToWriter(cells, bwpe);
 +      if (bwpe.exception != null)
 +        throw bwpe.exception;
 +      bwpe.writer.flush();
 +      bwpe.writer.close();
 +    } catch (Exception e) {
 +      handleExceptionMRE(e);
 +    }
 +  }
 +  
 +  private static final ColumnVisibility EMPTY_VIS = new ColumnVisibility();
 +  
 +  private void addCellsToWriter(Map<ByteBuffer,List<ColumnUpdate>> cells, BatchWriterPlusException bwpe) {
 +    if (bwpe.exception != null)
 +      return;
 +    
 +    HashMap<Text,ColumnVisibility> vizMap = new HashMap<Text,ColumnVisibility>();
 +    
 +    for (Map.Entry<ByteBuffer,List<ColumnUpdate>> entry : cells.entrySet()) {
 +      Mutation m = new Mutation(ByteBufferUtil.toBytes(entry.getKey()));
 +      
 +      for (ColumnUpdate update : entry.getValue()) {
 +        ColumnVisibility viz = EMPTY_VIS;
 +        if (update.isSetColVisibility()) {
 +          Text vizText = new Text(update.getColVisibility());
 +          viz = vizMap.get(vizText);
 +          if (viz == null) {
 +            vizMap.put(vizText, viz = new ColumnVisibility(vizText));
 +          }
 +        }
 +        byte[] value = new byte[0];
 +        if (update.isSetValue())
 +          value = update.getValue();
 +        if (update.isSetTimestamp()) {
 +          if (update.isSetDeleteCell()) {
 +            m.putDelete(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp());
 +          } else {
-             if (update.isSetDeleteCell()) {
-               m.putDelete(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp());
-             } else {
-               m.put(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp(), value);
++            m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, update.getTimestamp(), new Value(value));
 +            }
-           }
 +        } else {
-           m.put(update.getColFamily(), update.getColQualifier(), viz, value);
++          if (update.isSetDeleteCell()) {
++            m.putDelete(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz);
++          } else {
++            m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, new Value(value));
++          }
 +        }
 +      }
 +      try {
 +        bwpe.writer.addMutation(m);
 +      } catch (MutationsRejectedException mre) {
 +        bwpe.exception = mre;
 +      }
 +    }
 +  }
 +  
 +  @Override
 +  public String createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      BatchWriterPlusException writer = getWriter(login, tableName, opts);
 +      UUID uuid = UUID.randomUUID();
 +      writerCache.put(uuid, writer);
 +      return uuid.toString();
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void update(String writer, Map<ByteBuffer,List<ColumnUpdate>> cells) throws TException {
 +    try {
 +      BatchWriterPlusException bwpe = getWriter(writer);
 +      addCellsToWriter(cells, bwpe);
 +    } catch (UnknownWriter e) {
 +      // just drop it, this is a oneway thrift call and throwing a TException seems to make all subsequent thrift calls fail
 +    }
 +  }
 +  
 +  @Override
 +  public void flush(String writer) throws UnknownWriter, org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
 +    try {
 +      BatchWriterPlusException bwpe = getWriter(writer);
 +      if (bwpe.exception != null)
 +        throw bwpe.exception;
 +      bwpe.writer.flush();
 +    } catch (MutationsRejectedException e) {
 +      throw new org.apache.accumulo.proxy.thrift.MutationsRejectedException(e.toString());
 +    } catch (UnknownWriter uw) {
 +      throw uw;
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void closeWriter(String writer) throws UnknownWriter, org.apache.accumulo.proxy.thrift.MutationsRejectedException, TException {
 +    try {
 +      BatchWriterPlusException bwpe = getWriter(writer);
 +      if (bwpe.exception != null)
 +        throw bwpe.exception;
 +      bwpe.writer.close();
 +      writerCache.invalidate(UUID.fromString(writer));
 +    } catch (UnknownWriter uw) {
 +      throw uw;
 +    } catch (MutationsRejectedException e) {
 +      throw new org.apache.accumulo.proxy.thrift.MutationsRejectedException(e.toString());
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +
 +  private BatchWriterPlusException getWriter(String writer) throws UnknownWriter {
 +    UUID uuid = null;
 +    try {
 +      uuid = UUID.fromString(writer);
 +    } catch (IllegalArgumentException iae) {
 +      throw new UnknownWriter(iae.getMessage());
 +    }
 +    
 +    BatchWriterPlusException bwpe = writerCache.getIfPresent(uuid);
 +    if (bwpe == null) {
 +      throw new UnknownWriter("Writer never existed or no longer exists");
 +    }
 +    return bwpe;
 +  }
 +  
 +  private BatchWriterPlusException getWriter(ByteBuffer login, String tableName, WriterOptions opts) throws Exception {
 +    BatchWriterConfig cfg = new BatchWriterConfig();
 +    if (opts != null) {
 +      if (opts.maxMemory != 0)
 +        cfg.setMaxMemory(opts.maxMemory);
 +      if (opts.threads != 0)
 +        cfg.setMaxWriteThreads(opts.threads);
 +      if (opts.timeoutMs != 0)
 +        cfg.setTimeout(opts.timeoutMs, TimeUnit.MILLISECONDS);
 +      if (opts.latencyMs != 0)
 +        cfg.setMaxLatency(opts.latencyMs, TimeUnit.MILLISECONDS);
 +    }
 +    BatchWriterPlusException result = new BatchWriterPlusException();
 +    result.writer = getConnector(login).createBatchWriter(tableName, cfg);
 +    return result;
 +  }
 +  
 +  private IteratorSetting getIteratorSetting(org.apache.accumulo.proxy.thrift.IteratorSetting setting) {
 +    return new IteratorSetting(setting.priority, setting.name, setting.iteratorClass, setting.getProperties());
 +  }
 +  
 +  private IteratorScope getIteratorScope(org.apache.accumulo.proxy.thrift.IteratorScope scope) {
 +    return IteratorScope.valueOf(scope.toString().toLowerCase());
 +  }
 +  
 +  private EnumSet<IteratorScope> getIteratorScopes(Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes) {
 +    EnumSet<IteratorScope> scopes_ = EnumSet.noneOf(IteratorScope.class);
 +    for (org.apache.accumulo.proxy.thrift.IteratorScope scope : scopes) {
 +      scopes_.add(getIteratorScope(scope));
 +    }
 +    return scopes_;
 +  }
 +  
 +  private EnumSet<org.apache.accumulo.proxy.thrift.IteratorScope> getProxyIteratorScopes(Set<IteratorScope> scopes) {
 +    EnumSet<org.apache.accumulo.proxy.thrift.IteratorScope> scopes_ = EnumSet.noneOf(org.apache.accumulo.proxy.thrift.IteratorScope.class);
 +    for (IteratorScope scope : scopes) {
 +      scopes_.add(org.apache.accumulo.proxy.thrift.IteratorScope.valueOf(scope.toString().toUpperCase()));
 +    }
 +    return scopes_;
 +  }
 +  
 +  @Override
 +  public void attachIterator(ByteBuffer login, String tableName, org.apache.accumulo.proxy.thrift.IteratorSetting setting,
 +      Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes) throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().attachIterator(tableName, getIteratorSetting(setting), getIteratorScopes(scopes));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void checkIteratorConflicts(ByteBuffer login, String tableName, org.apache.accumulo.proxy.thrift.IteratorSetting setting,
 +      Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().checkIteratorConflicts(tableName, getIteratorSetting(setting), getIteratorScopes(scopes));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public 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,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, org.apache.accumulo.proxy.thrift.TableExistsException, TException {
 +    try {
 +      propertiesToExclude = propertiesToExclude == null ? new HashSet<String>() : propertiesToExclude;
 +      propertiesToSet = propertiesToSet == null ? new HashMap<String,String>() : propertiesToSet;
 +      
 +      getConnector(login).tableOperations().clone(tableName, newTableName, flush, propertiesToSet, propertiesToExclude);
 +    } catch (Exception e) {
 +      handleExceptionTEE(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void exportTable(ByteBuffer login, String tableName, String exportDir) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    
 +    try {
 +      getConnector(login).tableOperations().exportTable(tableName, exportDir);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public void importTable(ByteBuffer login, String tableName, String importDir) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableExistsException, TException {
 +    
 +    try {
 +      getConnector(login).tableOperations().importTable(tableName, importDir);
 +    } catch (TableExistsException e) {
 +      throw new org.apache.accumulo.proxy.thrift.TableExistsException(e.toString());
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public org.apache.accumulo.proxy.thrift.IteratorSetting getIteratorSetting(ByteBuffer login, String tableName, String iteratorName,
 +      org.apache.accumulo.proxy.thrift.IteratorScope scope) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      IteratorSetting is = getConnector(login).tableOperations().getIteratorSetting(tableName, iteratorName, getIteratorScope(scope));
 +      return new org.apache.accumulo.proxy.thrift.IteratorSetting(is.getPriority(), is.getName(), is.getIteratorClass(), is.getOptions());
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public Map<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> listIterators(ByteBuffer login, String tableName)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Map<String,EnumSet<IteratorScope>> iterMap = getConnector(login).tableOperations().listIterators(tableName);
 +      Map<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>> result = new HashMap<String,Set<org.apache.accumulo.proxy.thrift.IteratorScope>>();
 +      for (Map.Entry<String,EnumSet<IteratorScope>> entry : iterMap.entrySet()) {
 +        result.put(entry.getKey(), getProxyIteratorScopes(entry.getValue()));
 +      }
 +      return result;
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  @Override
 +  public void removeIterator(ByteBuffer login, String tableName, String iterName, Set<org.apache.accumulo.proxy.thrift.IteratorScope> scopes)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      getConnector(login).tableOperations().removeIterator(tableName, iterName, getIteratorScopes(scopes));
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  @Override
 +  public Set<org.apache.accumulo.proxy.thrift.Range> splitRangeByTablets(ByteBuffer login, String tableName, org.apache.accumulo.proxy.thrift.Range range,
 +      int maxSplits) throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      Set<Range> ranges = getConnector(login).tableOperations().splitRangeByTablets(tableName, getRange(range), maxSplits);
 +      Set<org.apache.accumulo.proxy.thrift.Range> result = new HashSet<org.apache.accumulo.proxy.thrift.Range>();
 +      for (Range r : ranges) {
 +        result.add(getRange(r));
 +      }
 +      return result;
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return null;
 +    }
 +  }
 +  
 +  private org.apache.accumulo.proxy.thrift.Range getRange(Range r) {
 +    return new org.apache.accumulo.proxy.thrift.Range(getProxyKey(r.getStartKey()), r.isStartKeyInclusive(), getProxyKey(r.getEndKey()), r.isEndKeyInclusive());
 +  }
 +  
 +  private org.apache.accumulo.proxy.thrift.Key getProxyKey(Key k) {
 +    if (k == null)
 +      return null;
 +    org.apache.accumulo.proxy.thrift.Key result = new org.apache.accumulo.proxy.thrift.Key(TextUtil.getByteBuffer(k.getRow()), TextUtil.getByteBuffer(k
 +        .getColumnFamily()), TextUtil.getByteBuffer(k.getColumnQualifier()), TextUtil.getByteBuffer(k.getColumnVisibility()));
 +    return result;
 +  }
 +  
 +  private Range getRange(org.apache.accumulo.proxy.thrift.Range range) {
 +    return new Range(Util.fromThrift(range.start), Util.fromThrift(range.stop));
 +  }
 +  
 +  @Override
 +  public void importDirectory(ByteBuffer login, String tableName, String importDir, String failureDir, boolean setTime)
 +      throws org.apache.accumulo.proxy.thrift.TableNotFoundException, org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).tableOperations().importDirectory(tableName, importDir, failureDir, setTime);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +    }
 +  }
 +  
 +  static private final ByteBuffer EMPTY = ByteBuffer.wrap(new byte[] {});
 +  
 +  @Override
 +  public org.apache.accumulo.proxy.thrift.Range getRowRange(ByteBuffer row) throws TException {
 +    return new org.apache.accumulo.proxy.thrift.Range(new org.apache.accumulo.proxy.thrift.Key(row, EMPTY, EMPTY, EMPTY), true,
 +        new org.apache.accumulo.proxy.thrift.Key(row, EMPTY, EMPTY, EMPTY), true);
 +  }
 +  
 +  @Override
 +  public org.apache.accumulo.proxy.thrift.Key getFollowing(org.apache.accumulo.proxy.thrift.Key key, org.apache.accumulo.proxy.thrift.PartialKey part)
 +      throws TException {
 +    Key key_ = Util.fromThrift(key);
 +    PartialKey part_ = PartialKey.valueOf(part.toString());
 +    Key followingKey = key_.followingKey(part_);
 +    return getProxyKey(followingKey);
 +  }
 +  
 +  @Override
 +  public void pingTabletServer(ByteBuffer login, String tserver) throws org.apache.accumulo.proxy.thrift.AccumuloException,
 +      org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      getConnector(login).instanceOperations().ping(tserver);
 +    } catch (Exception e) {
 +      handleException(e);
 +    }
 +  }
 +  
 +  @Override
 +  public ByteBuffer login(String principal, Map<String,String> loginProperties) throws org.apache.accumulo.proxy.thrift.AccumuloSecurityException, TException {
 +    try {
 +      AuthenticationToken token = getToken(principal, loginProperties);
 +      TCredentials credential = CredentialHelper.create(principal, token, instance.getInstanceID());
 +      ByteBuffer login = ByteBuffer.wrap(CredentialHelper.asByteArray(credential));
 +      getConnector(login); // check to make sure user exists
 +      return login;
 +    } catch (AccumuloSecurityException e) {
 +      throw new org.apache.accumulo.proxy.thrift.AccumuloSecurityException(e.toString());
 +    } catch (Exception e) {
 +      throw new TException(e);
 +    }
 +  }
 +  
 +  private AuthenticationToken getToken(String principal, Map<String,String> properties) throws AccumuloSecurityException, AccumuloException {
 +    AuthenticationToken.Properties props = new AuthenticationToken.Properties();
 +    props.putAllStrings(properties);
 +    AuthenticationToken token;
 +    try {
 +      token = tokenClass.newInstance();
 +    } catch (InstantiationException e) {
 +      throw new AccumuloException(e);
 +    } catch (IllegalAccessException e) {
 +      throw new AccumuloException(e);
 +    }
 +    token.init(props);
 +    return token;
 +  }
 +  
 +  @Override
 +  public boolean testTableClassLoad(ByteBuffer login, String tableName, String className, String asTypeName)
 +      throws org.apache.accumulo.proxy.thrift.AccumuloException, org.apache.accumulo.proxy.thrift.AccumuloSecurityException,
 +      org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {
 +    try {
 +      return getConnector(login).tableOperations().testClassLoad(tableName, className, asTypeName);
 +    } catch (Exception e) {
 +      handleExceptionTNF(e);
 +      return false;
 +    }
 +  }
 +}


[4/4] git commit: ACCUMULO-1800 fix deletes, added test

Posted by ec...@apache.org.
ACCUMULO-1800 fix deletes, added test


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/8ec4cb84
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/8ec4cb84
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/8ec4cb84

Branch: refs/heads/master
Commit: 8ec4cb840aff77bba3f3dc2e1b98a1c4de7c89ab
Parents: fb82945 3143b9c
Author: Eric Newton <er...@gmail.com>
Authored: Tue Oct 22 10:30:07 2013 -0400
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Oct 22 10:30:07 2013 -0400

----------------------------------------------------------------------
 .../org/apache/accumulo/proxy/ProxyServer.java  | 12 +++++-----
 .../org/apache/accumulo/proxy/SimpleTest.java   | 24 ++++++++++++++++++++
 2 files changed, 30 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/8ec4cb84/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
----------------------------------------------------------------------
diff --cc proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
index cec8cfc,c6e74f1..ee993b9
--- a/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
+++ b/proxy/src/main/java/org/apache/accumulo/proxy/ProxyServer.java
@@@ -1161,41 -1144,6 +1161,41 @@@ public class ProxyServer implements Acc
      }
    }
    
 +  private void addUpdatesToMutation(HashMap<Text,ColumnVisibility> vizMap, Mutation m, List<ColumnUpdate> cu) {
 +    for (ColumnUpdate update : cu) {
 +      ColumnVisibility viz = EMPTY_VIS;
 +      if (update.isSetColVisibility()) {
 +        viz = getCahcedCV(vizMap, update.getColVisibility());
 +      }
 +      byte[] value = new byte[0];
 +      if (update.isSetValue())
 +        value = update.getValue();
 +      if (update.isSetTimestamp()) {
 +        if (update.isSetDeleteCell()) {
 +          m.putDelete(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp());
 +        } else {
-           if (update.isSetDeleteCell()) {
-             m.putDelete(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp());
-           } else {
-             m.put(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp(), value);
-           }
++          m.put(update.getColFamily(), update.getColQualifier(), viz, update.getTimestamp(), value);
 +        }
 +      } else {
-         m.put(update.getColFamily(), update.getColQualifier(), viz, value);
++        if (update.isSetDeleteCell()) {
++          m.putDelete(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz);
++        } else {
++          m.put(new Text(update.getColFamily()), new Text(update.getColQualifier()), viz, new Value(value));
++        }
 +      }
 +    }
 +  }
 +  
 +  private static ColumnVisibility getCahcedCV(HashMap<Text,ColumnVisibility> vizMap, byte[] cv) {
 +    ColumnVisibility viz;
 +    Text vizText = new Text(cv);
 +    viz = vizMap.get(vizText);
 +    if (viz == null) {
 +      vizMap.put(vizText, viz = new ColumnVisibility(vizText));
 +    }
 +    return viz;
 +  }
 +  
    @Override
    public String createWriter(ByteBuffer login, String tableName, WriterOptions opts) throws org.apache.accumulo.proxy.thrift.AccumuloException,
        org.apache.accumulo.proxy.thrift.AccumuloSecurityException, org.apache.accumulo.proxy.thrift.TableNotFoundException, TException {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/8ec4cb84/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
----------------------------------------------------------------------
diff --cc proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
index 242ef08,3bd552d..8b1ab8b
--- a/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
+++ b/proxy/src/test/java/org/apache/accumulo/proxy/SimpleTest.java
@@@ -699,8 -678,33 +699,32 @@@ public class SimpleTest 
        fail("exception not thrown");
      } catch (UnknownWriter uw) {}
    }
 -  
 +
    @Test(timeout = 10000)
+   public void testDelete() throws Exception {
 -    if (client.tableExists(creds, TABLE_TEST))
 -      client.deleteTable(creds, TABLE_TEST);
++    final String TABLE_TEST = makeTableName();
+ 
+     client.createTable(creds, TABLE_TEST, true, TimeType.MILLIS);
+     client.updateAndFlush(creds, TABLE_TEST, mutation("row0", "cf", "cq", "value"));
+     String scanner = client.createScanner(creds, TABLE_TEST, null);
+     ScanResult entries = client.nextK(scanner, 10);
+     client.closeScanner(scanner);
+     assertFalse(entries.more);
+     assertEquals(1, entries.results.size());
+     
+     ColumnUpdate upd = new ColumnUpdate(s2bb("cf"), s2bb("cq"));
+     upd.setDeleteCell(true);
+     Map<ByteBuffer,List<ColumnUpdate>> delete = Collections.singletonMap(s2bb("row0"), Collections.singletonList(upd));
+     
+     client.updateAndFlush(creds, TABLE_TEST, delete);
+     
+     scanner = client.createScanner(creds, TABLE_TEST, null);
+     entries = client.nextK(scanner, 10);
+     client.closeScanner(scanner);
+     assertEquals(0, entries.results.size());
+   }
+ 
+   @Test(timeout = 10000)
    public void testInstanceOperations() throws Exception {
      int tservers = 0;
      for (String tserver : client.getTabletServers(creds)) {