http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
new file mode 100644
index 0000000..f6eb993
--- /dev/null
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java
@@ -0,0 +1,1389 @@
+/**
+ *
+ * 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.hadoop.hbase.thrift2.client;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.CacheEvictionStats;
+import org.apache.hadoop.hbase.ClusterMetrics;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.NamespaceNotFoundException;
+import org.apache.hadoop.hbase.RegionMetrics;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.TableNotFoundException;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
+import org.apache.hadoop.hbase.client.CompactType;
+import org.apache.hadoop.hbase.client.CompactionState;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.client.SnapshotDescription;
+import org.apache.hadoop.hbase.client.SnapshotType;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.replication.TableCFs;
+import org.apache.hadoop.hbase.client.security.SecurityCapability;
+import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
+import org.apache.hadoop.hbase.quotas.QuotaFilter;
+import org.apache.hadoop.hbase.quotas.QuotaRetriever;
+import org.apache.hadoop.hbase.quotas.QuotaSettings;
+import org.apache.hadoop.hbase.replication.ReplicationException;
+import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
+import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
+import org.apache.hadoop.hbase.thrift2.ThriftUtilities;
+import org.apache.hadoop.hbase.thrift2.generated.TColumnFamilyDescriptor;
+import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
+import org.apache.hadoop.hbase.thrift2.generated.TNamespaceDescriptor;
+import org.apache.hadoop.hbase.thrift2.generated.TTableDescriptor;
+import org.apache.hadoop.hbase.thrift2.generated.TTableName;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.thrift.TException;
+import org.apache.thrift.transport.TTransport;
+import org.apache.yetus.audience.InterfaceAudience;
+
+@InterfaceAudience.Private
+public class ThriftAdmin implements Admin {
+
+  private THBaseService.Client client;
+  private TTransport transport;
+  private int operationTimeout;
+  private Configuration conf;
+
+
+  public ThriftAdmin(THBaseService.Client client, TTransport tTransport, 
Configuration conf) {
+    this.client = client;
+    this.transport = tTransport;
+    this.operationTimeout = 
conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
+        HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
+    this.conf = conf;
+  }
+
+  @Override
+  public int getOperationTimeout() {
+    return operationTimeout;
+  }
+
+  @Override
+  public void abort(String why, Throwable e) {
+
+  }
+
+  @Override
+  public boolean isAborted() {
+    return false;
+  }
+
+  @Override
+  public void close() throws IOException {
+    transport.close();
+  }
+
+  @Override
+  public Configuration getConfiguration() {
+    return conf;
+  }
+
+  @Override
+  public boolean tableExists(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      return client.tableExists(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public Connection getConnection() {
+    throw new NotImplementedException("getConnection not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] listTables() throws IOException {
+    return listTables((String)null);
+  }
+
+  @Override
+  public List<TableDescriptor> listTableDescriptors() throws IOException {
+    return listTableDescriptors((Pattern) null);
+  }
+
+  @Override
+  public HTableDescriptor[] listTables(Pattern pattern) throws IOException {
+    String regex = (pattern == null ? null : pattern.toString());
+    return listTables(regex);
+  }
+
+  @Override
+  public List<TableDescriptor> listTableDescriptors(Pattern pattern) throws 
IOException {
+    return listTableDescriptors(pattern, false);
+  }
+
+  @Override
+  public HTableDescriptor[] listTables(String regex) throws IOException {
+    return listTables(regex, false);
+  }
+
+  @Override
+  public HTableDescriptor[] listTables(Pattern pattern, boolean 
includeSysTables)
+      throws IOException {
+    String regex = (pattern == null ? null : pattern.toString());
+    return listTables(regex, includeSysTables);
+
+  }
+
+  @Override
+  public List<TableDescriptor> listTableDescriptors(Pattern pattern, boolean 
includeSysTables)
+      throws IOException {
+    try {
+      String regex = (pattern == null ? null : pattern.toString());
+      List<TTableDescriptor> tTableDescriptors = client
+          .getTableDescriptorsByPattern(regex, includeSysTables);
+      return ThriftUtilities.tableDescriptorsFromThrift(tTableDescriptors);
+
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public HTableDescriptor[] listTables(String regex, boolean includeSysTables) 
throws IOException {
+    try {
+      List<TTableDescriptor> tTableDescriptors = client
+          .getTableDescriptorsByPattern(regex, includeSysTables);
+      return ThriftUtilities.hTableDescriptorsFromThrift(tTableDescriptors);
+
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public TableName[] listTableNames() throws IOException {
+    return listTableNames((String)null);
+  }
+
+  @Override
+  public TableName[] listTableNames(Pattern pattern) throws IOException {
+    return listTableNames(pattern, false);
+  }
+
+  @Override
+  public TableName[] listTableNames(String regex) throws IOException {
+    return listTableNames(regex, false);
+  }
+
+  @Override
+  public TableName[] listTableNames(Pattern pattern, boolean includeSysTables) 
throws IOException {
+    String regex = (pattern == null ? null : pattern.toString());
+    return listTableNames(regex, includeSysTables);
+  }
+
+  @Override
+  public TableName[] listTableNames(String regex, boolean includeSysTables) 
throws IOException {
+    try {
+      List<TTableName> tTableNames = client.getTableNamesByPattern(regex, 
includeSysTables);
+      return ThriftUtilities.tableNamesArrayFromThrift(tTableNames);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public HTableDescriptor getTableDescriptor(TableName tableName)
+      throws TableNotFoundException, IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      TTableDescriptor tTableDescriptor = 
client.getTableDescriptor(tTableName);
+      return ThriftUtilities.hTableDescriptorFromThrift(tTableDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public TableDescriptor getDescriptor(TableName tableName)
+      throws TableNotFoundException, IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      TTableDescriptor tTableDescriptor = 
client.getTableDescriptor(tTableName);
+      return ThriftUtilities.tableDescriptorFromThrift(tTableDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public HTableDescriptor[] listTableDescriptorsByNamespace(String name) 
throws IOException {
+    try {
+      List<TTableDescriptor> tTableDescriptors = 
client.getTableDescriptorsByNamespace(name);
+      return ThriftUtilities.hTableDescriptorsFromThrift(tTableDescriptors);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public List<TableDescriptor> listTableDescriptorsByNamespace(byte[] name) 
throws IOException {
+    try {
+      List<TTableDescriptor> tTableDescriptors = client
+          .getTableDescriptorsByNamespace(Bytes.toString(name));
+      return ThriftUtilities.tableDescriptorsFromThrift(tTableDescriptors);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public TableName[] listTableNamesByNamespace(String name) throws IOException 
{
+    try {
+      List<TTableName> tTableNames = client.getTableNamesByNamespace(name);
+      return ThriftUtilities.tableNamesArrayFromThrift(tTableNames);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void createTable(TableDescriptor desc) throws IOException {
+    createTable(desc, null);
+  }
+
+  @Override
+  public void createTable(TableDescriptor desc, byte[] startKey, byte[] 
endKey, int numRegions)
+      throws IOException {
+    if(numRegions < 3) {
+      throw new IllegalArgumentException("Must create at least three regions");
+    } else if(Bytes.compareTo(startKey, endKey) >= 0) {
+      throw new IllegalArgumentException("Start key must be smaller than end 
key");
+    }
+    if (numRegions == 3) {
+      createTable(desc, new byte[][]{startKey, endKey});
+      return;
+    }
+    byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3);
+    if(splitKeys == null || splitKeys.length != numRegions - 1) {
+      throw new IllegalArgumentException("Unable to split key range into 
enough regions");
+    }
+    createTable(desc, splitKeys);
+  }
+
+  @Override
+  public void createTable(TableDescriptor desc, byte[][] splitKeys) throws 
IOException {
+    TTableDescriptor tTableDescriptor = 
ThriftUtilities.tableDescriptorFromHBase(desc);
+    List<ByteBuffer> splitKeyInBuffer = 
ThriftUtilities.splitKeyFromHBase(splitKeys);
+    try {
+      client.createTable(tTableDescriptor, splitKeyInBuffer);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void deleteTable(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      client.deleteTable(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void truncateTable(TableName tableName, boolean preserveSplits) 
throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      client.truncateTable(tTableName, preserveSplits);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void enableTable(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      client.enableTable(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void disableTable(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      client.disableTable(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean isTableEnabled(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      return client.isTableEnabled(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean isTableDisabled(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      return client.isTableDisabled(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean isTableAvailable(TableName tableName) throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      return client.isTableAvailable(tTableName);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean isTableAvailable(TableName tableName, byte[][] splitKeys) 
throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    List<ByteBuffer> splitKeyInBuffer = 
ThriftUtilities.splitKeyFromHBase(splitKeys);
+    try {
+      return client.isTableAvailableWithSplit(tTableName, splitKeyInBuffer);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void addColumnFamily(TableName tableName, ColumnFamilyDescriptor 
columnFamily)
+      throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    TColumnFamilyDescriptor tColumnFamilyDescriptor = ThriftUtilities
+        .columnFamilyDescriptorFromHBase(columnFamily);
+    try {
+      client.addColumnFamily(tTableName, tColumnFamilyDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void deleteColumn(TableName tableName, byte[] columnFamily) throws 
IOException {
+    deleteColumnFamily(tableName, columnFamily);
+  }
+
+  @Override
+  public void deleteColumnFamily(TableName tableName, byte[] columnFamily) 
throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    try {
+      client.deleteColumnFamily(tTableName, ByteBuffer.wrap(columnFamily));
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void modifyColumnFamily(TableName tableName, ColumnFamilyDescriptor 
columnFamily)
+      throws IOException {
+    TTableName tTableName = ThriftUtilities.tableNameFromHBase(tableName);
+    TColumnFamilyDescriptor tColumnFamilyDescriptor = ThriftUtilities
+        .columnFamilyDescriptorFromHBase(columnFamily);
+    try {
+      client.modifyColumnFamily(tTableName, tColumnFamilyDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void modifyTable(TableName tableName, TableDescriptor td) throws 
IOException {
+    modifyTable(td);
+  }
+
+  @Override
+  public void modifyTable(TableDescriptor td) throws IOException {
+    TTableDescriptor tTableDescriptor = ThriftUtilities
+        .tableDescriptorFromHBase(td);
+    try {
+      client.modifyTable(tTableDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void modifyNamespace(NamespaceDescriptor descriptor) throws 
IOException {
+    TNamespaceDescriptor tNamespaceDescriptor = ThriftUtilities
+        .namespaceDescriptorFromHBase(descriptor);
+    try {
+      client.modifyNamespace(tNamespaceDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void deleteNamespace(String name) throws IOException {
+    try {
+      client.deleteNamespace(name);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public NamespaceDescriptor getNamespaceDescriptor(String name)
+      throws NamespaceNotFoundException, IOException {
+    try {
+      TNamespaceDescriptor tNamespaceDescriptor = 
client.getNamespaceDescriptor(name);
+      return 
ThriftUtilities.namespaceDescriptorFromThrift(tNamespaceDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public NamespaceDescriptor[] listNamespaceDescriptors() throws IOException {
+    try {
+      List<TNamespaceDescriptor> tNamespaceDescriptors = 
client.listNamespaceDescriptors();
+      return 
ThriftUtilities.namespaceDescriptorsFromThrift(tNamespaceDescriptors);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void createNamespace(NamespaceDescriptor descriptor) throws 
IOException {
+    TNamespaceDescriptor tNamespaceDescriptor = ThriftUtilities
+        .namespaceDescriptorFromHBase(descriptor);
+    try {
+      client.createNamespace(tNamespaceDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean switchRpcThrottle(boolean enable) throws IOException {
+    throw new NotImplementedException("switchRpcThrottle by pattern not 
supported in ThriftAdmin");
+  }
+
+  @Override
+  public boolean isRpcThrottleEnabled() throws IOException {
+    throw new NotImplementedException(
+        "isRpcThrottleEnabled by pattern not supported in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] disableTables(String regex) throws IOException {
+    throw new NotImplementedException("disableTables by pattern not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] disableTables(Pattern pattern) throws IOException {
+    throw new NotImplementedException("disableTables by pattern not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] enableTables(String regex) throws IOException {
+    throw new NotImplementedException("enableTables by pattern not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] enableTables(Pattern pattern) throws IOException {
+    throw new NotImplementedException("enableTables by pattern not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] deleteTables(String regex) throws IOException {
+    throw new NotImplementedException("deleteTables by pattern not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public HTableDescriptor[] deleteTables(Pattern pattern) throws IOException {
+    throw new NotImplementedException("deleteTables by pattern not supported 
in ThriftAdmin");
+
+  }
+
+  @Override
+  public HTableDescriptor[] getTableDescriptorsByTableName(List<TableName> 
tableNames)
+      throws IOException {
+    throw new NotImplementedException("getTableDescriptorsByTableName not 
supported in ThriftAdmin"
+        + ", use getDescriptor to get descriptors one by one");
+  }
+
+  @Override
+  public List<TableDescriptor> listTableDescriptors(List<TableName> 
tableNames) throws IOException {
+    throw new NotImplementedException("listTableDescriptors not supported in 
ThriftAdmin"
+        + ", use getDescriptor to get descriptors one by one");
+  }
+
+  @Override
+  public HTableDescriptor[] getTableDescriptors(List<String> names) throws 
IOException {
+    throw new NotImplementedException("getTableDescriptors not supported in 
ThriftAdmin"
+        + ", use getDescriptor to get descriptors one by one");
+  }
+
+  @Override
+  public void closeRegion(String regionname, String serverName) {
+    throw new NotImplementedException("closeRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void closeRegion(byte[] regionname, String serverName) {
+    throw new NotImplementedException("closeRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public boolean closeRegionWithEncodedRegionName(String encodedRegionName, 
String serverName) {
+    throw new NotImplementedException(
+        "closeRegionWithEncodedRegionName not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void closeRegion(ServerName sn, HRegionInfo hri) {
+    throw new NotImplementedException("closeRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public List<HRegionInfo> getOnlineRegions(ServerName sn) {
+    throw new NotImplementedException("getOnlineRegions not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<RegionInfo> getRegions(ServerName serverName) {
+    throw new NotImplementedException("getRegions not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void flush(TableName tableName) {
+    throw new NotImplementedException("flush not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void flushRegion(byte[] regionName) {
+    throw new NotImplementedException("flushRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void flushRegionServer(ServerName serverName) {
+    throw new NotImplementedException("flushRegionServer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void compact(TableName tableName) {
+    throw new NotImplementedException("compact not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void compactRegion(byte[] regionName) {
+    throw new NotImplementedException("compactRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void compact(TableName tableName, byte[] columnFamily) {
+    throw new NotImplementedException("compact not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void compactRegion(byte[] regionName, byte[] columnFamily) {
+    throw new NotImplementedException("compactRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void compact(TableName tableName, CompactType compactType) {
+    throw new NotImplementedException("compact not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void compact(TableName tableName, byte[] columnFamily, CompactType 
compactType) {
+    throw new NotImplementedException("compact not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompact(TableName tableName) {
+    throw new NotImplementedException("majorCompact not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompactRegion(byte[] regionName) {
+    throw new NotImplementedException("majorCompactRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompact(TableName tableName, byte[] columnFamily) {
+    throw new NotImplementedException("majorCompact not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompactRegion(byte[] regionName, byte[] columnFamily) {
+    throw new NotImplementedException("majorCompactRegion not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompact(TableName tableName, CompactType compactType) {
+    throw new NotImplementedException("majorCompact not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompact(TableName tableName, byte[] columnFamily, 
CompactType compactType) {
+    throw new NotImplementedException("majorCompact not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Map<ServerName, Boolean> compactionSwitch(boolean switchState,
+      List<String> serverNamesList) {
+    throw new NotImplementedException("compactionSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void compactRegionServer(ServerName serverName) {
+    throw new NotImplementedException("compactRegionServer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void majorCompactRegionServer(ServerName serverName) {
+    throw new NotImplementedException("majorCompactRegionServer not supported 
in ThriftAdmin");
+
+  }
+
+  @Override
+  public void move(byte[] encodedRegionName, byte[] destServerName) {
+    throw new NotImplementedException("move not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void assign(byte[] regionName) {
+    throw new NotImplementedException("assign not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void unassign(byte[] regionName, boolean force) {
+    throw new NotImplementedException("unassign not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void offline(byte[] regionName) {
+    throw new NotImplementedException("offline not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public boolean balancerSwitch(boolean onOrOff, boolean synchronous) {
+    throw new NotImplementedException("balancerSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean balance() {
+    throw new NotImplementedException("balance not supported in ThriftAdmin");
+  }
+
+  @Override
+  public boolean balance(boolean force) {
+    throw new NotImplementedException("balance not supported in ThriftAdmin");
+  }
+
+  @Override
+  public boolean isBalancerEnabled() {
+    throw new NotImplementedException("isBalancerEnabled not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public CacheEvictionStats clearBlockCache(TableName tableName) {
+    throw new NotImplementedException("clearBlockCache not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean normalize() {
+    throw new NotImplementedException("normalize not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean isNormalizerEnabled() {
+    throw new NotImplementedException("isNormalizerEnabled not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean normalizerSwitch(boolean on) {
+    throw new NotImplementedException("normalizerSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean catalogJanitorSwitch(boolean onOrOff) {
+    throw new NotImplementedException("catalogJanitorSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public int runCatalogJanitor() {
+    throw new NotImplementedException("runCatalogJanitor not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean isCatalogJanitorEnabled() {
+    throw new NotImplementedException("isCatalogJanitorEnabled not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public boolean cleanerChoreSwitch(boolean onOrOff) {
+    throw new NotImplementedException("cleanerChoreSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean runCleanerChore() {
+    throw new NotImplementedException("runCleanerChore not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean isCleanerChoreEnabled() {
+    throw new NotImplementedException("isCleanerChoreEnabled not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void mergeRegions(byte[] nameOfRegionA, byte[] nameOfRegionB, boolean 
forcible) {
+    throw new NotImplementedException("mergeRegions not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> mergeRegionsAsync(byte[] nameOfRegionA, byte[] 
nameOfRegionB,
+      boolean forcible) {
+    throw new NotImplementedException("mergeRegionsAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> mergeRegionsAsync(byte[][] nameofRegionsToMerge, boolean 
forcible) {
+    throw new NotImplementedException("mergeRegionsAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void split(TableName tableName) {
+    throw new NotImplementedException("split not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void splitRegion(byte[] regionName) {
+    throw new NotImplementedException("splitRegion not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void split(TableName tableName, byte[] splitPoint) {
+    throw new NotImplementedException("split not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void splitRegion(byte[] regionName, byte[] splitPoint) {
+    throw new NotImplementedException("splitRegion not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> splitRegionAsync(byte[] regionName, byte[] splitPoint) {
+    throw new NotImplementedException("splitRegionAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> modifyTableAsync(TableName tableName, TableDescriptor 
td) {
+    throw new NotImplementedException("modifyTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> modifyTableAsync(TableDescriptor td) {
+    throw new NotImplementedException("modifyTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void shutdown() {
+    throw new NotImplementedException("shutdown not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void stopMaster() {
+    throw new NotImplementedException("stopMaster not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public boolean isMasterInMaintenanceMode() {
+    throw new NotImplementedException("isMasterInMaintenanceMode not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public void stopRegionServer(String hostnamePort) {
+    throw new NotImplementedException("stopRegionServer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public ClusterMetrics getClusterMetrics(EnumSet<ClusterMetrics.Option> 
options) {
+    throw new NotImplementedException("getClusterMetrics not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<RegionMetrics> getRegionMetrics(ServerName serverName, TableName 
tableName) {
+    throw new NotImplementedException("getRegionMetrics not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> createNamespaceAsync(NamespaceDescriptor descriptor) {
+    throw new NotImplementedException("createNamespaceAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> modifyNamespaceAsync(NamespaceDescriptor descriptor) {
+    throw new NotImplementedException("modifyNamespaceAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<HRegionInfo> getTableRegions(TableName tableName) {
+    throw new NotImplementedException("getTableRegions not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<RegionInfo> getRegions(TableName tableName) {
+    throw new NotImplementedException("getRegions not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean abortProcedure(long procId, boolean mayInterruptIfRunning) {
+    throw new NotImplementedException("abortProcedure not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Boolean> abortProcedureAsync(long procId, boolean 
mayInterruptIfRunning) {
+    throw new NotImplementedException("abortProcedureAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public String getProcedures() {
+    throw new NotImplementedException("getProcedures not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public String getLocks() {
+    throw new NotImplementedException("getLocks not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void rollWALWriter(ServerName serverName) {
+    throw new NotImplementedException("rollWALWriter not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public CompactionState getCompactionState(TableName tableName) {
+    throw new NotImplementedException("getCompactionState not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public CompactionState getCompactionState(TableName tableName, CompactType 
compactType) {
+    throw new NotImplementedException("getCompactionState not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public CompactionState getCompactionStateForRegion(byte[] regionName) {
+    throw new NotImplementedException("getCompactionStateForRegion not 
supported in ThriftAdmin");
+  }
+
+  @Override
+  public long getLastMajorCompactionTimestamp(TableName tableName) {
+    throw new NotImplementedException(
+        "getLastMajorCompactionTimestamp not supported in ThriftAdmin");
+  }
+
+  @Override
+  public long getLastMajorCompactionTimestampForRegion(byte[] regionName) {
+    throw new NotImplementedException(
+        "getLastMajorCompactionTimestampForRegion not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void snapshot(String snapshotName, TableName tableName) {
+    throw new NotImplementedException("snapshot not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void snapshot(byte[] snapshotName, TableName tableName) {
+    throw new NotImplementedException("snapshot not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void snapshot(String snapshotName, TableName tableName, SnapshotType 
type) {
+    throw new NotImplementedException("snapshot not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void snapshot(SnapshotDescription snapshot) {
+    throw new NotImplementedException("snapshot not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void snapshotAsync(SnapshotDescription snapshot) {
+    throw new NotImplementedException("snapshotAsync not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public boolean isSnapshotFinished(SnapshotDescription snapshot) {
+    throw new NotImplementedException("isSnapshotFinished not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void restoreSnapshot(byte[] snapshotName) {
+    throw new NotImplementedException("restoreSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void restoreSnapshot(String snapshotName) {
+    throw new NotImplementedException("restoreSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> restoreSnapshotAsync(String snapshotName) {
+    throw new NotImplementedException("restoreSnapshotAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void restoreSnapshot(byte[] snapshotName, boolean 
takeFailSafeSnapshot) {
+    throw new NotImplementedException("restoreSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void restoreSnapshot(String snapshotName, boolean 
takeFailSafeSnapshot) {
+    throw new NotImplementedException("restoreSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void restoreSnapshot(String snapshotName, boolean 
takeFailSafeSnapshot,
+      boolean restoreAcl) {
+    throw new NotImplementedException("restoreSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void cloneSnapshot(byte[] snapshotName, TableName tableName) {
+    throw new NotImplementedException("cloneSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void cloneSnapshot(String snapshotName, TableName tableName, boolean 
restoreAcl) {
+    throw new NotImplementedException("cloneSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void cloneSnapshot(String snapshotName, TableName tableName) {
+    throw new NotImplementedException("cloneSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> cloneSnapshotAsync(String snapshotName, TableName 
tableName) {
+    throw new NotImplementedException("cloneSnapshotAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void execProcedure(String signature, String instance, Map<String, 
String> props) {
+    throw new NotImplementedException("execProcedure not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public byte[] execProcedureWithReturn(String signature, String instance,
+      Map<String, String> props) {
+    throw new NotImplementedException("execProcedureWithReturn not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public boolean isProcedureFinished(String signature, String instance, 
Map<String, String> props) {
+    throw new NotImplementedException("isProcedureFinished not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<SnapshotDescription> listSnapshots() {
+    throw new NotImplementedException("listSnapshots not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<SnapshotDescription> listSnapshots(String regex) {
+    throw new NotImplementedException("listSnapshots not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<SnapshotDescription> listSnapshots(Pattern pattern) {
+    throw new NotImplementedException("listSnapshots not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<SnapshotDescription> listTableSnapshots(String tableNameRegex,
+      String snapshotNameRegex) {
+    throw new NotImplementedException("listTableSnapshots not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<SnapshotDescription> listTableSnapshots(Pattern tableNamePattern,
+      Pattern snapshotNamePattern) {
+    throw new NotImplementedException("listTableSnapshots not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void deleteSnapshot(byte[] snapshotName) {
+    throw new NotImplementedException("deleteSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void deleteSnapshot(String snapshotName) {
+    throw new NotImplementedException("deleteSnapshot not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void deleteSnapshots(String regex) {
+    throw new NotImplementedException("deleteSnapshots not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void deleteSnapshots(Pattern pattern) {
+    throw new NotImplementedException("deleteSnapshots not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void deleteTableSnapshots(String tableNameRegex, String 
snapshotNameRegex) {
+    throw new NotImplementedException("deleteTableSnapshots not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void deleteTableSnapshots(Pattern tableNamePattern, Pattern 
snapshotNamePattern) {
+    throw new NotImplementedException("deleteTableSnapshots not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void setQuota(QuotaSettings quota) {
+    throw new NotImplementedException("setQuota not supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public QuotaRetriever getQuotaRetriever(QuotaFilter filter) {
+    throw new NotImplementedException("getQuotaRetriever not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<QuotaSettings> getQuota(QuotaFilter filter) {
+    throw new NotImplementedException("getQuota not supported in ThriftAdmin");
+  }
+
+  @Override
+  public CoprocessorRpcChannel coprocessorService() {
+    throw new NotImplementedException("coprocessorService not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public CoprocessorRpcChannel coprocessorService(ServerName serverName) {
+    throw new NotImplementedException("coprocessorService not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void updateConfiguration(ServerName server) {
+    throw new NotImplementedException("updateConfiguration not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void updateConfiguration() {
+    throw new NotImplementedException("updateConfiguration not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public List<SecurityCapability> getSecurityCapabilities() {
+    throw new NotImplementedException("getSecurityCapabilities not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public boolean splitSwitch(boolean enabled, boolean synchronous) {
+    throw new NotImplementedException("splitSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean mergeSwitch(boolean enabled, boolean synchronous) {
+    throw new NotImplementedException("mergeSwitch not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean isSplitEnabled() {
+    throw new NotImplementedException("isSplitEnabled not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public boolean isMergeEnabled() {
+    throw new NotImplementedException("isMergeEnabled not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void addReplicationPeer(String peerId, ReplicationPeerConfig 
peerConfig, boolean enabled) {
+    throw new NotImplementedException("addReplicationPeer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> addReplicationPeerAsync(String peerId, 
ReplicationPeerConfig peerConfig,
+      boolean enabled) {
+    throw new NotImplementedException("addReplicationPeerAsync not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public void removeReplicationPeer(String peerId) {
+    throw new NotImplementedException("removeReplicationPeer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> removeReplicationPeerAsync(String peerId) {
+    throw new NotImplementedException("removeReplicationPeerAsync not 
supported in ThriftAdmin");
+  }
+
+  @Override
+  public void enableReplicationPeer(String peerId) {
+    throw new NotImplementedException("enableReplicationPeer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> enableReplicationPeerAsync(String peerId) {
+    throw new NotImplementedException("enableReplicationPeerAsync not 
supported in ThriftAdmin");
+  }
+
+  @Override
+  public void disableReplicationPeer(String peerId) {
+    throw new NotImplementedException("disableReplicationPeer not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> disableReplicationPeerAsync(String peerId) {
+    throw new NotImplementedException("disableReplicationPeerAsync not 
supported in ThriftAdmin");
+  }
+
+  @Override
+  public ReplicationPeerConfig getReplicationPeerConfig(String peerId) {
+    throw new NotImplementedException("getReplicationPeerConfig not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public void updateReplicationPeerConfig(String peerId, ReplicationPeerConfig 
peerConfig) {
+    throw new NotImplementedException("updateReplicationPeerConfig not 
supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> updateReplicationPeerConfigAsync(String peerId,
+      ReplicationPeerConfig peerConfig) {
+    throw new NotImplementedException(
+        "updateReplicationPeerConfigAsync not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void appendReplicationPeerTableCFs(String id, Map<TableName, 
List<String>> tableCfs)
+      throws ReplicationException, IOException {
+    throw new NotImplementedException("appendReplicationPeerTableCFs not 
supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public void removeReplicationPeerTableCFs(String id, Map<TableName, 
List<String>> tableCfs)
+      throws ReplicationException, IOException {
+    throw new NotImplementedException("removeReplicationPeerTableCFs not 
supported in ThriftAdmin");
+
+  }
+
+  @Override
+  public List<ReplicationPeerDescription> listReplicationPeers() {
+    throw new NotImplementedException("listReplicationPeers not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public List<ReplicationPeerDescription> listReplicationPeers(Pattern 
pattern) {
+    throw new NotImplementedException("listReplicationPeers not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void decommissionRegionServers(List<ServerName> servers, boolean 
offload) {
+    throw new NotImplementedException("decommissionRegionServers not supported 
in ThriftAdmin");
+
+  }
+
+  @Override
+  public List<ServerName> listDecommissionedRegionServers() {
+    throw new NotImplementedException(
+        "listDecommissionedRegionServers not supported in ThriftAdmin");
+  }
+
+  @Override
+  public void recommissionRegionServer(ServerName server, List<byte[]> 
encodedRegionNames) {
+    throw new NotImplementedException("recommissionRegionServer not supported 
in ThriftAdmin");
+
+  }
+
+  @Override
+  public List<TableCFs> listReplicatedTableCFs() {
+    throw new NotImplementedException("listReplicatedTableCFs not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void enableTableReplication(TableName tableName) {
+    throw new NotImplementedException("enableTableReplication not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public void disableTableReplication(TableName tableName) {
+    throw new NotImplementedException("disableTableReplication not supported 
in ThriftAdmin");
+
+  }
+
+  @Override
+  public void clearCompactionQueues(ServerName serverName, Set<String> queues) 
{
+    throw new NotImplementedException("clearCompactionQueues not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public List<ServerName> clearDeadServers(List<ServerName> servers) {
+    throw new NotImplementedException("clearDeadServers not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public void cloneTableSchema(TableName tableName, TableName newTableName,
+      boolean preserveSplits) {
+    throw new NotImplementedException("cloneTableSchema not supported in 
ThriftAdmin");
+
+  }
+
+  @Override
+  public Future<Void> createTableAsync(TableDescriptor desc, byte[][] 
splitKeys) {
+    throw new NotImplementedException("createTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> deleteTableAsync(TableName tableName) {
+    throw new NotImplementedException("deleteTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> truncateTableAsync(TableName tableName, boolean 
preserveSplits) {
+    throw new NotImplementedException("truncateTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> enableTableAsync(TableName tableName) {
+    throw new NotImplementedException("enableTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> disableTableAsync(TableName tableName) {
+    throw new NotImplementedException("disableTableAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Pair<Integer, Integer> getAlterStatus(TableName tableName) {
+    throw new NotImplementedException("getAlterStatus not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Pair<Integer, Integer> getAlterStatus(byte[] tableName) {
+    throw new NotImplementedException("getAlterStatus not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> deleteColumnFamilyAsync(TableName tableName, byte[] 
columnFamily) {
+    throw new NotImplementedException("deleteColumnFamilyAsync not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> addColumnFamilyAsync(TableName tableName,
+      ColumnFamilyDescriptor columnFamily) {
+    throw new NotImplementedException("addColumnFamilyAsync not supported in 
ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> modifyColumnFamilyAsync(TableName tableName,
+      ColumnFamilyDescriptor columnFamily) {
+    throw new NotImplementedException("modifyColumnFamilyAsync not supported 
in ThriftAdmin");
+  }
+
+  @Override
+  public Future<Void> deleteNamespaceAsync(String name) {
+    throw new NotImplementedException("deleteNamespaceAsync not supported in 
ThriftAdmin");
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftClientBuilder.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftClientBuilder.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftClientBuilder.java
new file mode 100644
index 0000000..3c11c98
--- /dev/null
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftClientBuilder.java
@@ -0,0 +1,37 @@
+/**
+ *
+ * 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.hadoop.hbase.thrift2.client;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.thrift.transport.TTransport;
+import org.apache.yetus.audience.InterfaceAudience;
+
+@InterfaceAudience.Private
+public abstract class ThriftClientBuilder {
+  protected ThriftConnection connection;
+
+  public ThriftClientBuilder(ThriftConnection connection) {
+    this.connection = connection;
+  }
+
+  public abstract Pair<THBaseService.Client, TTransport> getClient() throws 
IOException;
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftConnection.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftConnection.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftConnection.java
new file mode 100644
index 0000000..a0f902a
--- /dev/null
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftConnection.java
@@ -0,0 +1,322 @@
+/**
+ *
+ * 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.hadoop.hbase.thrift2.client;
+
+import static 
org.apache.hadoop.hbase.ipc.RpcClient.DEFAULT_SOCKET_TIMEOUT_CONNECT;
+import static org.apache.hadoop.hbase.ipc.RpcClient.SOCKET_TIMEOUT_CONNECT;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.BufferedMutator;
+import org.apache.hadoop.hbase.client.BufferedMutatorParams;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.RegionLocator;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.client.TableBuilder;
+import org.apache.hadoop.hbase.security.User;
+import org.apache.hadoop.hbase.thrift.Constants;
+import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.utils.HttpClientUtils;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TCompactProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.THttpClient;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.apache.yetus.audience.InterfaceAudience;
+
+import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
+
+@InterfaceAudience.Private
+public class ThriftConnection implements Connection {
+  private Configuration conf;
+  private User user;
+  // For HTTP protocol
+  private HttpClient httpClient;
+  private boolean httpClientCreated = false;
+  private boolean isClosed = false;
+
+  private String host;
+  private int port;
+  private boolean isFramed = false;
+  private boolean isCompact = false;
+
+  private ThriftClientBuilder clientBuilder;
+
+  private int operationTimeout;
+  private int connectTimeout;
+
+  public ThriftConnection(Configuration conf, ExecutorService pool, final User 
user)
+      throws IOException {
+    this.conf = conf;
+    this.user = user;
+    this.host = conf.get(Constants.HBASE_THRIFT_SERVER_NAME);
+    this.port = conf.getInt(Constants.HBASE_THRIFT_SERVER_PORT, -1);
+    Preconditions.checkArgument(port > 0);
+    Preconditions.checkArgument(host != null);
+    this.isFramed = conf.getBoolean(Constants.FRAMED_CONF_KEY, 
Constants.FRAMED_CONF_DEFAULT);
+    this.isCompact = conf.getBoolean(Constants.COMPACT_CONF_KEY, 
Constants.COMPACT_CONF_DEFAULT);
+    this.operationTimeout = 
conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
+        HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
+    this.connectTimeout = conf.getInt(SOCKET_TIMEOUT_CONNECT, 
DEFAULT_SOCKET_TIMEOUT_CONNECT);
+
+    String className = conf.get(Constants.HBASE_THRIFT_CLIENT_BUIDLER_CLASS,
+        DefaultThriftClientBuilder.class.getName());
+    try {
+      Class<?> clazz = Class.forName(className);
+      Constructor<?> constructor = clazz
+          .getDeclaredConstructor(ThriftConnection.class);
+      constructor.setAccessible(true);
+      clientBuilder = (ThriftClientBuilder) constructor.newInstance(this);
+    }catch (Exception e) {
+      throw new IOException(e);
+    }
+  }
+
+  public synchronized void setHttpClient(HttpClient httpClient) {
+    this.httpClient = httpClient;
+  }
+
+  @Override
+  public Configuration getConfiguration() {
+    return conf;
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public int getPort() {
+    return port;
+  }
+
+  public boolean isFramed() {
+    return isFramed;
+  }
+
+  public boolean isCompact() {
+    return isCompact;
+  }
+
+  public int getOperationTimeout() {
+    return operationTimeout;
+  }
+
+  public int getConnectTimeout() {
+    return connectTimeout;
+  }
+
+  public ThriftClientBuilder getClientBuilder() {
+    return clientBuilder;
+  }
+
+  /**
+   * the default thrift client builder.
+   * One can extend the ThriftClientBuilder to builder custom client, implement
+   * features like authentication(hbase-examples/thrift/DemoClient)
+   *
+   */
+  public static class DefaultThriftClientBuilder extends ThriftClientBuilder  {
+
+    @Override
+    public Pair<THBaseService.Client, TTransport> getClient() throws 
IOException {
+      TSocket sock = new TSocket(connection.getHost(), connection.getPort());
+      sock.setSocketTimeout(connection.getOperationTimeout());
+      sock.setConnectTimeout(connection.getConnectTimeout());
+      TTransport tTransport = sock;
+      if (connection.isFramed()) {
+        tTransport = new TFramedTransport(tTransport);
+      }
+      try {
+        sock.open();
+      } catch (TTransportException e) {
+        throw new IOException(e);
+      }
+      TProtocol prot;
+      if (connection.isCompact()) {
+        prot = new TCompactProtocol(tTransport);
+      } else {
+        prot = new TBinaryProtocol(tTransport);
+      }
+      THBaseService.Client client = new THBaseService.Client(prot);
+      return new Pair<>(client, tTransport);
+    }
+
+    public DefaultThriftClientBuilder(ThriftConnection connection) {
+      super(connection);
+    }
+  }
+
+  /**
+   * the default thrift http client builder.
+   * One can extend the ThriftClientBuilder to builder custom http client, 
implement
+   * features like authentication or 
'DoAs'(hbase-examples/thrift/HttpDoAsClient)
+   *
+   */
+  public static class HTTPThriftClientBuilder extends ThriftClientBuilder {
+    Map<String,String> customHeader = new HashMap<>();
+
+    public HTTPThriftClientBuilder(ThriftConnection connection) {
+      super(connection);
+    }
+
+    public void addCostumHeader(String key, String value) {
+      customHeader.put(key, value);
+    }
+
+    @Override
+    public Pair<THBaseService.Client, TTransport> getClient() throws 
IOException {
+      Preconditions.checkArgument(connection.getHost().startsWith("http"),
+          "http client host must start with http or https");
+      String url = connection.getHost() + ":" + connection.getPort();
+      try {
+        THttpClient httpClient = new THttpClient(url, 
connection.getHttpClient());
+        for (Map.Entry<String, String> header : customHeader.entrySet()) {
+          httpClient.setCustomHeader(header.getKey(), header.getValue());
+        }
+        httpClient.open();
+        TProtocol prot = new TBinaryProtocol(httpClient);
+        THBaseService.Client client = new THBaseService.Client(prot);
+        return new Pair<>(client, httpClient);
+      } catch (TTransportException e) {
+        throw new IOException(e);
+      }
+
+    }
+  }
+
+  /**
+   * Get a ThriftAdmin, ThriftAdmin is NOT thread safe
+   * @return a ThriftAdmin
+   * @throws IOException IOException
+   */
+  @Override
+  public Admin getAdmin() throws IOException {
+    Pair<THBaseService.Client, TTransport> client = clientBuilder.getClient();
+    return new ThriftAdmin(client.getFirst(), client.getSecond(), conf);
+  }
+
+  public synchronized HttpClient getHttpClient() {
+    if (httpClient != null) {
+      return httpClient;
+    }
+    HttpClientBuilder builder = HttpClientBuilder.create();
+    RequestConfig.Builder requestBuilder = RequestConfig.custom();
+    requestBuilder = requestBuilder.setConnectTimeout(getConnectTimeout());
+    requestBuilder = 
requestBuilder.setConnectionRequestTimeout(getOperationTimeout());
+    builder.setDefaultRequestConfig(requestBuilder.build());
+    httpClient = builder.build();
+    httpClientCreated = true;
+    return httpClient;
+  }
+
+  @Override
+  public synchronized void close() throws IOException {
+    if (httpClient != null && httpClientCreated) {
+      HttpClientUtils.closeQuietly(httpClient);
+    }
+    isClosed = true;
+  }
+
+  @Override
+  public boolean isClosed() {
+    return isClosed;
+  }
+
+  /**
+   * Get a TableBuider to build ThriftTable, ThriftTable is NOT thread safe
+   * @return a TableBuilder
+   * @throws IOException IOException
+   */
+  @Override
+  public TableBuilder getTableBuilder(TableName tableName, ExecutorService 
pool) {
+    return new TableBuilder() {
+      @Override
+      public TableBuilder setOperationTimeout(int timeout) {
+        return this;
+      }
+
+      @Override
+      public TableBuilder setRpcTimeout(int timeout) {
+        return this;
+      }
+
+      @Override
+      public TableBuilder setReadRpcTimeout(int timeout) {
+        return this;
+      }
+
+      @Override
+      public TableBuilder setWriteRpcTimeout(int timeout) {
+        return this;
+      }
+
+      @Override
+      public Table build() {
+        try {
+          Pair<THBaseService.Client, TTransport> client = 
clientBuilder.getClient();
+          return new ThriftTable(tableName, client.getFirst(), 
client.getSecond(), conf);
+        } catch (IOException ioE) {
+          throw new RuntimeException(ioE);
+        }
+
+      }
+    };
+  }
+
+  @Override
+  public void abort(String why, Throwable e) {
+
+  }
+
+  @Override
+  public boolean isAborted() {
+    return false;
+  }
+
+  @Override
+  public BufferedMutator getBufferedMutator(TableName tableName) throws 
IOException {
+    throw new NotImplementedException("batchCoprocessorService not supported 
in ThriftTable");
+  }
+
+  @Override
+  public BufferedMutator getBufferedMutator(BufferedMutatorParams params) 
throws IOException {
+    throw new NotImplementedException("batchCoprocessorService not supported 
in ThriftTable");
+  }
+
+  @Override
+  public RegionLocator getRegionLocator(TableName tableName) throws 
IOException {
+    throw new NotImplementedException("batchCoprocessorService not supported 
in ThriftTable");
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftTable.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftTable.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftTable.java
new file mode 100644
index 0000000..5c826b9
--- /dev/null
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftTable.java
@@ -0,0 +1,492 @@
+/**
+ *
+ * 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.hadoop.hbase.thrift2.client;
+
+import static 
org.apache.hadoop.hbase.thrift.Constants.HBASE_THRIFT_CLIENT_SCANNER_CACHING;
+import static 
org.apache.hadoop.hbase.thrift.Constants.HBASE_THRIFT_CLIENT_SCANNER_CACHING_DEFAULT;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.CompareOperator;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Append;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Increment;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Row;
+import org.apache.hadoop.hbase.client.RowMutations;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.client.Table;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.coprocessor.Batch;
+import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
+import org.apache.hadoop.hbase.io.TimeRange;
+import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
+import org.apache.hadoop.hbase.thrift2.ThriftUtilities;
+import org.apache.hadoop.hbase.thrift2.generated.TAppend;
+import org.apache.hadoop.hbase.thrift2.generated.TDelete;
+import org.apache.hadoop.hbase.thrift2.generated.TGet;
+import org.apache.hadoop.hbase.thrift2.generated.THBaseService;
+import org.apache.hadoop.hbase.thrift2.generated.TIncrement;
+import org.apache.hadoop.hbase.thrift2.generated.TPut;
+import org.apache.hadoop.hbase.thrift2.generated.TResult;
+import org.apache.hadoop.hbase.thrift2.generated.TRowMutations;
+import org.apache.hadoop.hbase.thrift2.generated.TScan;
+import org.apache.hadoop.hbase.thrift2.generated.TTableDescriptor;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.thrift.TException;
+import org.apache.thrift.transport.TTransport;
+import org.apache.yetus.audience.InterfaceAudience;
+
+import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
+import org.apache.hbase.thirdparty.com.google.common.primitives.Booleans;
+
+@InterfaceAudience.Private
+public class ThriftTable implements Table {
+
+  private TableName tableName;
+  private Configuration conf;
+  private TTransport tTransport;
+  private THBaseService.Client client;
+  private ByteBuffer tableNameInBytes;
+  private int operationTimeout;
+
+  private final int scannerCaching;
+
+  public ThriftTable(TableName tableName, THBaseService.Client client, 
TTransport tTransport,
+      Configuration conf) {
+    this.tableName = tableName;
+    this.tableNameInBytes = ByteBuffer.wrap(tableName.toBytes());
+    this.conf = conf;
+    this.tTransport = tTransport;
+    this.client = client;
+    this.scannerCaching = conf.getInt(HBASE_THRIFT_CLIENT_SCANNER_CACHING,
+        HBASE_THRIFT_CLIENT_SCANNER_CACHING_DEFAULT);
+    this.operationTimeout = 
conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
+        HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
+
+
+  }
+
+  @Override
+  public TableName getName() {
+    return tableName;
+  }
+
+  @Override
+  public Configuration getConfiguration() {
+    return conf;
+  }
+
+  @Override
+  public TableDescriptor getDescriptor() throws IOException {
+    try {
+      TTableDescriptor tableDescriptor = client
+          .getTableDescriptor(ThriftUtilities.tableNameFromHBase(tableName));
+      return ThriftUtilities.tableDescriptorFromThrift(tableDescriptor);
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean exists(Get get) throws IOException {
+    TGet tGet = ThriftUtilities.getFromHBase(get);
+    try {
+      return client.exists(tableNameInBytes, tGet);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public boolean[] exists(List<Get> gets) throws IOException {
+    List<TGet> tGets = new ArrayList<>();
+    for (Get get: gets) {
+      tGets.add(ThriftUtilities.getFromHBase(get));
+    }
+    try {
+      List<Boolean> results = client.existsAll(tableNameInBytes, tGets);
+      return Booleans.toArray(results);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void batch(List<? extends Row> actions, Object[] results)
+      throws IOException {
+    throw new IOException("Batch not supported in ThriftTable, use 
put(List<Put> puts), "
+        + "get(List<Get> gets) or delete(List<Delete> deletes) respectively");
+
+
+  }
+
+  @Override
+  public <R> void batchCallback(List<? extends Row> actions, Object[] results,
+      Batch.Callback<R> callback) throws IOException {
+    throw new IOException("BatchCallback not supported in ThriftTable, use 
put(List<Put> puts), "
+        + "get(List<Get> gets) or delete(List<Delete> deletes) respectively");
+  }
+
+  @Override
+  public Result get(Get get) throws IOException {
+    TGet tGet = ThriftUtilities.getFromHBase(get);
+    try {
+      TResult tResult = client.get(tableNameInBytes, tGet);
+      return ThriftUtilities.resultFromThrift(tResult);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public Result[] get(List<Get> gets) throws IOException {
+    List<TGet> tGets = ThriftUtilities.getsFromHBase(gets);
+    try {
+      List<TResult> results = client.getMultiple(tableNameInBytes, tGets);
+      return ThriftUtilities.resultsFromThrift(results);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  /**
+   * A scanner to perform scan from thrift server
+   * getScannerResults is used in this scanner
+   */
+  private class Scanner implements ResultScanner {
+    protected TScan scan;
+    protected Result lastResult = null;
+    protected final Queue<Result> cache = new ArrayDeque<>();;
+
+
+    public Scanner(Scan scan) throws IOException {
+      if (scan.getBatch() > 0) {
+        throw new IOException("Batch is not supported in Scanner");
+      }
+      if (scan.getCaching() <= 0) {
+        scan.setCaching(scannerCaching);
+      } else if (scan.getCaching() == 1 && scan.isReversed()){
+        // for reverse scan, we need to pass the last row to the next scanner
+        // we need caching number bigger than 1
+        scan.setCaching(scan.getCaching() + 1);
+      }
+      this.scan = ThriftUtilities.scanFromHBase(scan);
+    }
+
+
+    @Override
+    public Result next() throws IOException {
+      if (cache.size() == 0) {
+        setupNextScanner();
+        try {
+          List<TResult> tResults = client
+              .getScannerResults(tableNameInBytes, scan, scan.getCaching());
+          Result[] results = ThriftUtilities.resultsFromThrift(tResults);
+          boolean firstKey = true;
+          for (Result result : results) {
+            // If it is a reverse scan, we use the last result's key as the 
startkey, since there is
+            // no way to construct a closet rowkey smaller than the last result
+            // So when the results return, we must rule out the first result, 
since it has already
+            // returned to user.
+            if (firstKey) {
+              firstKey = false;
+              if (scan.isReversed() && lastResult != null) {
+                if (Bytes.equals(lastResult.getRow(), result.getRow())) {
+                  continue;
+                }
+              }
+            }
+            cache.add(result);
+            lastResult = result;
+          }
+        } catch (TException e) {
+          throw new IOException(e);
+        }
+      }
+
+      if (cache.size() > 0) {
+        return cache.poll();
+      } else {
+        //scan finished
+        return null;
+      }
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public boolean renewLease() {
+      throw new RuntimeException("renewLease() not supported");
+    }
+
+    @Override
+    public ScanMetrics getScanMetrics() {
+      throw new RuntimeException("getScanMetrics() not supported");
+    }
+
+    private void setupNextScanner() {
+      //if lastResult is null null, it means it is not the fist scan
+      if (lastResult!= null) {
+        byte[] lastRow = lastResult.getRow();
+        if (scan.isReversed()) {
+          //for reverse scan, we can't find the closet row before this row
+          scan.setStartRow(lastRow);
+        } else {
+          scan.setStartRow(createClosestRowAfter(lastRow));
+        }
+      }
+    }
+
+
+    /**
+     * Create the closest row after the specified row
+     */
+    protected byte[] createClosestRowAfter(byte[] row) {
+      if (row == null) {
+        throw new RuntimeException("The passed row is null");
+      }
+      return Arrays.copyOf(row, row.length + 1);
+    }
+  }
+
+  @Override
+  public ResultScanner getScanner(Scan scan) throws IOException {
+    return new Scanner(scan);
+  }
+
+  @Override
+  public ResultScanner getScanner(byte[] family) throws IOException {
+    Scan scan = new Scan();
+    scan.addFamily(family);
+    return getScanner(scan);
+  }
+
+  @Override
+  public ResultScanner getScanner(byte[] family, byte[] qualifier) throws 
IOException {
+    Scan scan = new Scan();
+    scan.addColumn(family, qualifier);
+    return getScanner(scan);
+  }
+
+  @Override
+  public void put(Put put) throws IOException {
+    TPut tPut = ThriftUtilities.putFromHBase(put);
+    try {
+      client.put(tableNameInBytes, tPut);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void put(List<Put> puts) throws IOException {
+    List<TPut> tPuts = ThriftUtilities.putsFromHBase(puts);
+    try {
+      client.putMultiple(tableNameInBytes, tPuts);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void delete(Delete delete) throws IOException {
+    TDelete tDelete = ThriftUtilities.deleteFromHBase(delete);
+    try {
+      client.deleteSingle(tableNameInBytes, tDelete);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void delete(List<Delete> deletes) throws IOException {
+    List<TDelete> tDeletes = ThriftUtilities.deletesFromHBase(deletes);
+    try {
+      client.deleteMultiple(tableNameInBytes, tDeletes);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  private class CheckAndMutateBuilderImpl implements CheckAndMutateBuilder {
+
+    private final byte[] row;
+    private final byte[] family;
+    private byte[] qualifier;
+    private CompareOperator op;
+    private byte[] value;
+
+    CheckAndMutateBuilderImpl(byte[] row, byte[] family) {
+      this.row = Preconditions.checkNotNull(row, "row is null");
+      this.family = Preconditions.checkNotNull(family, "family is null");
+    }
+
+    @Override
+    public CheckAndMutateBuilder qualifier(byte[] qualifier) {
+      this.qualifier = Preconditions.checkNotNull(qualifier, "qualifier is 
null. Consider using" +
+          " an empty byte array, or just do not call this method if you want a 
null qualifier");
+      return this;
+    }
+
+    @Override
+    public CheckAndMutateBuilder timeRange(TimeRange timeRange) {
+      throw new NotImplementedException("timeRange not supported in 
ThriftTable");
+    }
+
+    @Override
+    public CheckAndMutateBuilder ifNotExists() {
+      this.op = CompareOperator.EQUAL;
+      this.value = null;
+      return this;
+    }
+
+    @Override
+    public CheckAndMutateBuilder ifMatches(CompareOperator compareOp, byte[] 
value) {
+      this.op = Preconditions.checkNotNull(compareOp, "compareOp is null");
+      this.value = Preconditions.checkNotNull(value, "value is null");
+      return this;
+    }
+
+    private void preCheck() {
+      Preconditions.checkNotNull(op, "condition is null. You need to specify 
the condition by" +
+          " calling ifNotExists/ifEquals/ifMatches before executing the 
request");
+    }
+
+    @Override
+    public boolean thenPut(Put put) throws IOException {
+      preCheck();
+      RowMutations rowMutations = new RowMutations(put.getRow());
+      rowMutations.add(put);
+      return checkAndMutate(row, family, qualifier, op, value, rowMutations);
+    }
+
+    @Override
+    public boolean thenDelete(Delete delete) throws IOException {
+      preCheck();
+      RowMutations rowMutations = new RowMutations(delete.getRow());
+      rowMutations.add(delete);
+      return checkAndMutate(row, family, qualifier, op, value, rowMutations);
+    }
+
+    @Override
+    public boolean thenMutate(RowMutations mutation) throws IOException {
+      preCheck();
+      return checkAndMutate(row, family, qualifier, op, value, mutation);
+    }
+  }
+
+
+  @Override
+  public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, 
CompareOperator op,
+      byte[] value, RowMutations mutation) throws IOException {
+    try {
+      ByteBuffer valueBuffer = value == null? null : ByteBuffer.wrap(value);
+      return client.checkAndMutate(tableNameInBytes, ByteBuffer.wrap(row), 
ByteBuffer.wrap(family),
+          ByteBuffer.wrap(qualifier), ThriftUtilities.compareOpFromHBase(op), 
valueBuffer,
+          ThriftUtilities.rowMutationsFromHBase(mutation));
+    } catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public CheckAndMutateBuilder checkAndMutate(byte[] row, byte[] family) {
+    return new CheckAndMutateBuilderImpl(row, family);
+  }
+
+  @Override
+  public void mutateRow(RowMutations rm) throws IOException {
+    TRowMutations tRowMutations = ThriftUtilities.rowMutationsFromHBase(rm);
+    try {
+      client.mutateRow(tableNameInBytes, tRowMutations);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public Result append(Append append) throws IOException {
+    TAppend tAppend = ThriftUtilities.appendFromHBase(append);
+    try {
+      TResult tResult = client.append(tableNameInBytes, tAppend);
+      return ThriftUtilities.resultFromThrift(tResult);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public Result increment(Increment increment) throws IOException {
+    TIncrement tIncrement = ThriftUtilities.incrementFromHBase(increment);
+    try {
+      TResult tResult = client.increment(tableNameInBytes, tIncrement);
+      return ThriftUtilities.resultFromThrift(tResult);
+    }  catch (TException e) {
+      throw new IOException(e);
+    }
+  }
+
+  @Override
+  public void close() throws IOException {
+    tTransport.close();
+  }
+
+  @Override
+  public long getRpcTimeout(TimeUnit unit) {
+    return unit.convert(operationTimeout, TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public long getReadRpcTimeout(TimeUnit unit) {
+    return unit.convert(operationTimeout, TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public long getWriteRpcTimeout(TimeUnit unit) {
+    return unit.convert(operationTimeout, TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public long getOperationTimeout(TimeUnit unit) {
+    return unit.convert(operationTimeout, TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public CoprocessorRpcChannel coprocessorService(byte[] row) {
+    throw new NotImplementedException("coprocessorService not supported in 
ThriftTable");
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAppend.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAppend.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAppend.java
index 1b9d6fc..d2aa0d3 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAppend.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAppend.java
@@ -34,7 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TAppend implements org.apache.thrift.TBase<TAppend, 
TAppend._Fields>, java.io.Serializable, Cloneable, Comparable<TAppend> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TAppend");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAuthorization.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAuthorization.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAuthorization.java
index 916dc0c..db5c916 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAuthorization.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TAuthorization.java
@@ -34,7 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TAuthorization implements org.apache.thrift.TBase<TAuthorization, 
TAuthorization._Fields>, java.io.Serializable, Cloneable, 
Comparable<TAuthorization> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TAuthorization");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TCellVisibility.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TCellVisibility.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TCellVisibility.java
index e9af9fe..bc0d513 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TCellVisibility.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TCellVisibility.java
@@ -34,7 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TCellVisibility implements 
org.apache.thrift.TBase<TCellVisibility, TCellVisibility._Fields>, 
java.io.Serializable, Cloneable, Comparable<TCellVisibility> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TCellVisibility");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumn.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumn.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumn.java
index 11e3ace..8734539 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumn.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumn.java
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
  * in a HBase table by column family and optionally
  * a column qualifier and timestamp
  */
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TColumn implements org.apache.thrift.TBase<TColumn, 
TColumn._Fields>, java.io.Serializable, Cloneable, Comparable<TColumn> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TColumn");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnFamilyDescriptor.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnFamilyDescriptor.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnFamilyDescriptor.java
index df4656f..2335333 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnFamilyDescriptor.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnFamilyDescriptor.java
@@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
  * Thrift wrapper around
  * org.apache.hadoop.hbase.client.ColumnFamilyDescriptor
  */
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TColumnFamilyDescriptor implements 
org.apache.thrift.TBase<TColumnFamilyDescriptor, 
TColumnFamilyDescriptor._Fields>, java.io.Serializable, Cloneable, 
Comparable<TColumnFamilyDescriptor> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TColumnFamilyDescriptor");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnIncrement.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnIncrement.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnIncrement.java
index 18c5ff2..08574c3 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnIncrement.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnIncrement.java
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Represents a single cell and the amount to increment it by
  */
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TColumnIncrement implements 
org.apache.thrift.TBase<TColumnIncrement, TColumnIncrement._Fields>, 
java.io.Serializable, Cloneable, Comparable<TColumnIncrement> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TColumnIncrement");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnValue.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnValue.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnValue.java
index 1355141..e2105bc 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnValue.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TColumnValue.java
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Represents a single cell and its value.
  */
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TColumnValue implements org.apache.thrift.TBase<TColumnValue, 
TColumnValue._Fields>, java.io.Serializable, Cloneable, 
Comparable<TColumnValue> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TColumnValue");
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/891c620c/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TDelete.java
----------------------------------------------------------------------
diff --git 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TDelete.java
 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TDelete.java
index cdce4fb..c3e1543 100644
--- 
a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TDelete.java
+++ 
b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/generated/TDelete.java
@@ -60,7 +60,7 @@ import org.slf4j.LoggerFactory;
  * by changing the durability. If you don't provide durability, it defaults to
  * column family's default setting for durability.
  */
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2018-12-28")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)", date = 
"2019-01-03")
 public class TDelete implements org.apache.thrift.TBase<TDelete, 
TDelete._Fields>, java.io.Serializable, Cloneable, Comparable<TDelete> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TDelete");
 

Reply via email to