Search code examples
javahbasegoogle-cloud-bigtablebigtable

Using hbase-orm in BigTable


I am trying to use hbase-orm in Bigtable (I am running the code on Bigtable Emulator). I keep getting this exception:

 org.apache.hadoop.hbase.DoNotRetryIOException: Failed to perform operation. Operation='put', projectId='projectId', tableName='citizens', rowKey='IND|1'
 at com.google.cloud.bigtable.hbase.AbstractBigtableTable.logAndCreateIOException(AbstractBigtableTable.java:541)
 at com.google.cloud.bigtable.hbase.AbstractBigtableTable.mutateRow(AbstractBigtableTable.java:478)
 at com.google.cloud.bigtable.hbase.AbstractBigtableTable.put(AbstractBigtableTable.java:342)
 at com.flipkart.hbaseobjectmapper.AbstractHBDAO.persist(AbstractHBDAO.java:627)
 at Main.main(Main.java:10)
Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: When parsing 'projects/projectId/instances/instanceId/tables/citizens' : Table name expected in the form 'projects/<project_id>/instances/<instance_id>/tables/<table_id>'.
 at io.grpc.Status.asRuntimeException(Status.java:524)
 at com.google.cloud.bigtable.grpc.async.AbstractRetryingOperation.getBlockingResult(AbstractRetryingOperation.java:449)
 at com.google.cloud.bigtable.grpc.BigtableDataGrpcClient.mutateRow(BigtableDataGrpcClient.java:242)
 at com.google.cloud.bigtable.grpc.BigtableDataClientWrapper.mutateRow(BigtableDataClientWrapper.java:70)
 at com.google.cloud.bigtable.hbase.AbstractBigtableTable.mutateRow(AbstractBigtableTable.java:475)
 ... 3 more

Here is the record class:

import com.flipkart.hbaseobjectmapper.*;
import com.flipkart.hbaseobjectmapper.codec.BestSuitCodec;

import java.util.Map;
import java.util.NavigableMap;

@HBTable(name = "citizens",
       families = {
               @Family(name = "main"),
               @Family(name = "optional", versions = 3),
               @Family(name = "tracked", versions = 10)
       }
)
public class Citizen implements HBRecord<String> {

   public Citizen() {
   }


   public Citizen(String countryCode, Integer uid, String name, Short age, Integer sal, Long counter) {
       this.countryCode = countryCode;
       this.uid = uid;
       this.name = name;
       this.age = age;
       this.sal = sal;
       this.counter = counter;
   }

   @HBRowKey
   private String countryCode;

   @HBRowKey
   private Integer uid;

   @HBColumn(family = "main", column = "name")
   private String name;

   @HBColumn(family = "optional", column = "age")
   private Short age;

   @HBColumn(family = "optional", column = "salary")
   private Integer sal;

   @HBColumn(family = "optional", column = "counter")
   private Long counter;

   @HBColumn(family = "optional", column = "custom_details")
   private Map<String, Integer> customDetails;

   @HBColumnMultiVersion(family = "tracked", column = "phone_number")
   private NavigableMap<Long, Integer> phoneNumber;

   @HBColumn(family = "optional", column = "pincode", codecFlags = {
           @Flag(name = BestSuitCodec.SERIALIZE_AS_STRING, value = "true")
   })
   private Integer pincode;

   @Override
   public String composeRowKey() {
       return String.format("%s|%d", countryCode, uid);
   }

   @Override
   public void parseRowKey(String rowKey) {
       String[] pieces = rowKey.split("|");
       this.countryCode = pieces[0];
       this.uid = Integer.parseInt(pieces[1]);
   }

   public String getCountryCode() {
       return countryCode;
   }

   public void setCountryCode(String countryCode) {
       this.countryCode = countryCode;
   }

   public Integer getUid() {
       return uid;
   }

   public void setUid(Integer uid) {
       this.uid = uid;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public Short getAge() {
       return age;
   }

   public void setAge(Short age) {
       this.age = age;
   }

   public Integer getSal() {
       return sal;
   }

   public void setSal(Integer sal) {
       this.sal = sal;
   }

   public Long getCounter() {
       return counter;
   }

   public void setCounter(Long counter) {
       this.counter = counter;
   }

   public Map<String, Integer> getCustomDetails() {
       return customDetails;
   }

   public void setCustomDetails(Map<String, Integer> customDetails) {
       this.customDetails = customDetails;
   }

   public NavigableMap<Long, Integer> getPhoneNumber() {
       return phoneNumber;
   }

   public void setPhoneNumber(NavigableMap<Long, Integer> phoneNumber) {
       this.phoneNumber = phoneNumber;
   }

   public Integer getPincode() {
       return pincode;
   }

   public void setPincode(Integer pincode) {
       this.pincode = pincode;
   }
}

here the DAO class:

import com.flipkart.hbaseobjectmapper.AbstractHBDAO;
import org.apache.hadoop.hbase.client.Connection;
import java.io.IOException;

public class CitizenDAO extends AbstractHBDAO<String, Citizen> {

    public CitizenDAO(Connection connection) throws IOException {
        super(connection); 
    }
}

Here is the main class:

import com.google.cloud.bigtable.hbase.BigtableConfiguration;
import org.apache.hadoop.hbase.client.Connection;

import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try (Connection connection = BigtableConfiguration.connect("projectId", "instanceId")) {
            CitizenDAO citizenDao = new CitizenDAO(connection);
            String rowKey = citizenDao.persist(new Citizen("IND", 1, "Suhaib", (short) 5, 15, 155L));
            System.out.println(rowKey);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Any advice to solve the issue? I don't know If I can use hbase-orm in Bigtable or not, since I am a beginner in Bigtable and HBase. Thanks.


Solution

  • I found the solution by myself, The issue was with connecting to Bigtable Emulator it was the wrong way here is the correct way :

    Configuration conf = BigtableConfiguration.configure("projectId", "instanceId");
    conf.set(BigtableOptionsFactory.BIGTABLE_EMULATOR_HOST_KEY, "localhost:8086");
    Connection connection = BigtableConfiguration.connect(conf);
    Admin admin = connection.getAdmin();
    CitizenDAO citizenDao = new CitizenDAO(connection);
    String rowKey = citizenDao.persist(new Citizen("IND", 1, "Suhaib", (short) 5, 15, 155L));
    Citizen citizen = citizenDao.get("IND|1");
    System.out.println(citizen.getName());