
# 通过ThriftServer实例操作HBase表
#### 操作场景
传入ThriftServer实例所在host和提供服务的port，根据认证凭据及配置文件新建Thrift客户端，访问ThriftServer，进行根据指定namespace获取tablename以及创建表、删除表的操作。
#### 操作步骤
1. 登录FusionInsight Manager，选择"集群 \> 服务 \> HBase \> 配置 \> 全部配置"，搜索并修改ThriftServer实例的配置参数"hbase.thrift.security.qop"。该参数值需与"hbase.rpc.protection"的值一一对应。保存配置，重启配置过期节点服务使更改的配置生效。
   
   ![](https://support.huaweicloud.com/devg-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
   "hbase.rpc.protection"与"hbase.thrift.security.qop"参数值的对应关系为：
   - **"privacy" - "auth-conf**"
   
   - **"authentication" - "auth**"
   
   - **"integrity" - "auth-int"**
    
   
   
2. 获取集群中安装ThriftServer对应实例的配置文件。 
   - 方法一：选择"集群 \> 服务 \> HBase \> 实例"，单击待操作的实例ThriftServer进入详情界面，获取配置文件"hdfs-site.xml"、"core-site.xml"、"hbase-site.xml"。
   
   - 方法二：通过[准备HBase应用开发和运行环境](https://support.huaweicloud.com/devg-lts-mrs/mrs_07_290006.html)中解压客户端文件的方法获取配置文件，需要在获取的"hbase-site.xml"中手动添加以下配置，其中"hbase.thrift.security.qop"的参数值与[1]保持一致。
     ```
     <property>
     <name>hbase.thrift.security.qop</name>
     <value>auth</value>
     </property>
     <property>
     <name>hbase.thrift.kerberos.principal</name>
     <value>thrift/hadoop.hadoop.com@HADOOP.COM</value>
     </property>
     <property>
     <name>hbase.thrift.keytab.file</name>
     <value>/opt/huawei/Bigdata/FusionInsight_HD_8.1.2.2/install/FusionInsight-HBase-2.2.3/keytabs/HBase/thrift.keytab</value>
     </property>
     ```
     
   
   
   
   
 
#### 样例代码
- 初始化配置
  以下代码在"hbase-thrift-example"样例工程的"com.huawei.bigdata.hbase.examples"包的"TestMain"类中。
  ```
  private static void init() throws IOException {
          // Default load from conf directory
          conf = HBaseConfiguration.create();
          String userdir = TestMain.class.getClassLoader().getResource("conf").getPath() + File.separator;[1]
          //In Linux environment
          //String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator;
          conf.addResource(new Path(userdir + "core-site.xml"), false);
          conf.addResource(new Path(userdir + "hdfs-site.xml"), false);
          conf.addResource(new Path(userdir + "hbase-site.xml"), false);
  }
  ```
  \[1\]**userdir**获取的是编译后资源路径下conf目录的路径。初始化配置用到的core-site.xml、hdfs-site.xml、hbase-site.xml文件，需要放置到"src/main/resources/conf"的目录下。
  

- 连接ThriftServer实例
  以下代码在"hbase-thrift-example"样例工程的"com.huawei.bigdata.hbase.examples"包的"TestMain"类中。
  ```
  try {    
          test = new ThriftSample();    
          test.test("100.120.16.170", THRIFT_PORT, conf);[2]
      } catch (TException | IOException e) {
          LOG.error("Test thrift error", e);
      }
  ```
  MRS 3.6.0-LTS及之后版本：
  ```
  try {    
          test = new ThriftSample();    
          // Specify the Thrift server hostnames, separated by comma if multiple are there.
          String thriftServerHostNames = "xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx";
          test.test(thriftServerHostNames, THRIFT_PORT, conf);[2]
      } catch (TException | IOException e) {
          LOG.error("Test thrift error", e);
      }
  ```
  \[2\]test.test()传入参数为待访问的ThriftServer实例所在节点IP地址，需根据实际运行集群情况进行修改，建议部署多个ThriftServer增加业务可靠性，需根据实际运行集群情况进行修改，且该节点ip需要配置到运行样例代码的本机hosts文件中。
  "THRIFT_PORT"为ThriftServer实例的配置参数"hbase.regionserver.thrift.port"对应的值。
  
- 方法调用
  ```
  // Get table of specified namespace. 
  getTableNamesByNamespace(client, "default");
  // Create table. 
  createTable(client, TABLE_NAME);
  // Delete specified table.
   deleteTable(client, TABLE_NAME);
  ```
  
- 根据指定namespace获取tablename 以下代码片段在"hbase-thrift-example\\src\\main\\java\\com\\huawei\\hadoop\\hbase\\examples"包的"ThriftSample"类的getTableNamesByNamespace方法中。
  ```
  private void getTableNamesByNamespace(THBaseService.Iface client, String namespace) throws TException {
       client.getTableNamesByNamespace(namespace)
           .forEach(
               tTableName -> LOGGER.info("{}", TableName.valueOf(tTableName.getNs(), tTableName.getQualifier())));
   }
  ```
  

- 创建表 以下代码片段在"hbase-thrift-example\\src\\main\\java\\com\\huawei\\hadoop\\hbase\\examples"包的"ThriftSample"类的createTable方法中。
  ```
  private void createTable(THBaseService.Iface client, String tableName) throws TException, IOException {
       TTableName table = getTableName(tableName);
       TTableDescriptor descriptor = new TTableDescriptor(table);
       descriptor.setColumns(
           Collections.singletonList(new TColumnFamilyDescriptor().setName(COLUMN_FAMILY.getBytes())));
       if (client.tableExists(table)) {
           LOGGER.warn("Table {} is exists, delete it.", tableName);
           client.disableTable(table);
           client.deleteTable(table);
       }
       client.createTable(descriptor, null);
       if (client.tableExists(table)) {
           LOGGER.info("Created {}.", tableName);
       } else {
           LOGGER.error("Create {} failed.", tableName);
       }
   }
  ```
  
- 删除表 以下代码片段在"hbase-thrift-example\\src\\main\\java\\com\\huawei\\hadoop\\hbase\\examples"包的"ThriftSample"类的deleteTable方法中。
  ```
  private void deleteTable(THBaseService.Iface client, String tableName) throws TException, IOException {
       TTableName table = getTableName(tableName);
       if (client.tableExists(table)) {
           client.disableTable(table);
           client.deleteTable(table);
           LOGGER.info("Deleted {}.", tableName);
       } else {
           LOGGER.warn("{} not exist.", tableName);
       }
   }
  ```
  
 
