Updated on 2022-06-01 GMT+08:00

REST

MRS1.6 and later versions allow you to perform service operations on HBase using REST APIs, which support the curl command and Java client. The use method of the curl commands is the same as that of Apache HBase. Visit https://hbase.apache.org/book.html#_rest for more information.

Currently, the default SSL protocols are TLSv1.1 and TLSv1.2. Therefore, you need to check whether the current environment supports the SSL protocols when you run the curl command to invoke a REST API.

Running the curl Command

  • For clusters with Kerberos authentication disabled

    Before running the curl command in a cluster with Kerberos authentication disabled, add the parameters as follows:

    curl -vi -k POST -H "Accept: text/xml" -H "Content-Type: text/xml" -d '<?xml version="1.0" encoding="UTF-8"?> <TableSchema name="users"><ColumnSchema name="cf" /> </TableSchema>' "https://<IP address of the HBase node where the RESTServer service is installed>:21309/users/schema"
  • For clusters with Kerberos authentication enabled

    When you run the curl command in a cluster with Kerberos authentication enabled, you need to perform the following steps:

    1. Perform Kerberos authentication as follows:

      Human-machine user: kinit MRS cluster user

      For example, kinit hbaseuser.

      Machine-machine user: kinit -kt Authentication credential path MRS cluster user

      For example: kinit -kt /opt/user.keytab hbaseuser.

    2. In the curl command, add the --negotiate -u parameter before the request type as follows:
      curl -vi -k --negotiate -u: POST -H "Accept: text/xml"   -H "Content-Type: text/xml" -d '<?xml version="1.0" encoding="UTF-8"?> <TableSchema name="users"><ColumnSchema name="cf" /> </TableSchema>' "https://<IP address of the HBase node where the RESTServer service is installed>:21309/users/schema"

Using the Java Client

Perform the following operations to use Java to call REST APIs. (You can refer to some code of RestExample in the sample code.)

  1. Perform Kerberos authentication. You can skip this step for a cluster with Kerberos authentication disabled.
  2. Create a cluster object of the org.apache.hadoop.hbase.rest.client.Cluster class, and add a cluster by invoking the add method of the cluster class and the cluster IP address and port of the REST server.
    Cluster cluster = new Cluster();
    cluster.add("10.10.10.10:21309");
  3. Use the client object of the cluster initialization class org.apache.hadoop.hbase.rest.client.Client added in step 2 to invoke doAs to operate HBase.
    Client client = new Client(cluster, true);
    UserGroupInformation.getLoginUser().doAs(new PrivilegedAction() {
      public Object run() {
        
        // Rest client code
        
        /* Sample code to list all the tables
           client.get("/")
        */
    
        return null;
      }
    });
  4. You can use the following methods to call different REST APIs.
  • Using plain text to obtain a namesapce
  1. Taking a path including namespace as a parameter, use the client to invoke the Get method to obtain a namespace. The response will be captured by an object of the org.apache.hadoop.hbase.rest.client.Response class. The following is an example.
    Response response;
    String namespacePath = "/namespaces/" + "nameSpaceName";
    response = client.get(namespacePath);
    System.out.println(Bytes.toString(response.getBody()));
  • Creating or modifying a namespace
  1. When creating or modifying a namespace, you need to use NamespacesInstanceModel to create a model and use the buildTestModel() method to build the mode. The model you create must contain the properties of the namespace to be created.
    Map<String, String> NAMESPACE1_PROPS = new HashMap<String, String>();
    NAMESPACE1_PROPS.put("key1", "value1");
    
    NamespacesInstanceModel model = buildTestModel(NAMESPACE1,NAMESPACE1_PROPS);
    
    private static NamespacesInstanceModel buildTestModel(String namespace, Map<String, String> properties) {
    NamespacesInstanceModel model = new NamespacesInstanceModel();
    for (String key : properties.keySet()) {
    model.addProperty(key, properties.get(key));
    }
    return model;
    }

    When you send a POST or PUT request to create or modify a table, TableSchemaModel is used to create a model class.

  2. You can use the following methods to create and modify namespaces.
  • Creating a namespace using XML
  1. After you use NamespacesInstanceModel to create a model, use the client to invoke the Post method to create a namespace. The parameters include the namespace path, content type, and content. For the content type, the invoked class is org.apache.hadoop.hbase.rest.Constants, and the invoked parameter here is Constants.MIMETYPE_XML. For the content, the following example uses the toXML() method to convert the content to the XML format. The response will be captured by an object of the org.apache.hadoop.hbase.rest.client.Response class. The following is an example.
    Response response;
    String namespacePath = "/namespaces/" + "nameSpaceName";
    response = client.post(namespacePath, Constants.MIMETYPE_XML, toXML(model));
    
    private static byte[] toXML(NamespacesInstanceModel model) throws JAXBException {
    StringWriter writer = new StringWriter();
    context.createMarshaller().marshal(model, writer);
    return Bytes.toBytes(writer.toString());
    }
  2. When sending a Get request using XML, you can use the fromXML() method to obtain the model from the response and find the name of the created namespace from the model.
    private static <T> T fromXML(byte[] content) throws JAXBException {
    return (T) context.createUnmarshaller().unmarshal(new ByteArrayInputStream(content));
    }
  • Modifying a namespace using JSON
  1. After you use NamespacesInstanceModel to create a model, invoke the Put method of the client class to create a namespace. The parameters include the namespace path, content type, and content. For the content type, the invoked class is org.apache.hadoop.hbase.rest.Constants, and the invoked parameter here is Constants.MIMETYPE_JSON. For the content, the following example converts the content to the JSON format and uses jsonMapper as a parameter. The response will be captured by an object of the org.apache.hadoop.hbase.rest.client.Response class. The following is an example.
    ObjectMapper jsonMapper = new JacksonProvider().locateMapper(NamespacesInstanceModel.class, MediaType.APPLICATION_JSON_TYPE);
    
    Response response;
    String namespacePath = "/namespaces/" + "nameSpaceName";
    String jsonString = jsonMapper.writeValueAsString(model);
    
    response = client.put(namespacePath, Constants.MIMETYPE_JSON, Bytes.toBytes(jsonString));
  2. When sending a Get request using JSON, you can use the readValue() method of jsonMapper to obtain the model from the response and find the name of the created namespace from the model.
    jsonMapper.readValue(response.getBody(), NamespacesInstanceModel.class);
    
    /*Here second argument should be according to API, if its     **related to table it should be TableSchemaModel.class*/
  • Modifying a namespace using Protobuf
  1. After you use NamespacesInstanceModel to create a model, invoke the Put method of the client class to create a namespace. The parameters include the namespace path, content type, and content. For the content type, the invoked class is org.apache.hadoop.hbase.rest.Constants, and the invoked parameter here is Constants.MIMETYPE_PROTOBUF. For the content, the following example converts the content as follows and uses createProtobufOutput to create Protobuf. The response will be captured by an object of the org.apache.hadoop.hbase.rest.client.Response class. The following is an example.
    Response response;
    String namespacePath = "/namespaces/" + "nameSpaceName";
    
    response = client.put(namespacePath, Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
    model.getObjectFromMessage(response.getBody());
  2. When sending a Get request using Protobuf, you can use the getObjectFromMessage method to obtain the model from the response and find the name of the created namespace from the model.
    model.getObjectFromMessage(response.getBody());