diff --git a/hbase-native-client/core/BUCK b/hbase-native-client/core/BUCK index d8d15a9..4a06a45 100644 --- a/hbase-native-client/core/BUCK +++ b/hbase-native-client/core/BUCK @@ -64,12 +64,26 @@ cxx_library( ], compiler_flags=['-Weffc++'], visibility=['PUBLIC',],) +cxx_library( + name="mini-cluster", + exported_headers=["mini-cluster.h",], + srcs=["mini-cluster.cc",], + preprocessor_flags= ['-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/', '-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/linux'], + exported_preprocessor_flags= ['-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/', '-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/linux'], + compiler_flags = ['-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/', '-I', '/usr/lib/jvm/java-8-openjdk-amd64/include/linux'], + linker_flags = ['-ljvm', '-L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server'], + exported_linker_flags = ['-ljvm', '-L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server', '-Wl,-rpath=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server'], + deps=[ + ":core", + ], + visibility=['PUBLIC',],) cxx_test( name="location-cache-test", srcs=["location-cache-test.cc",], deps=[ ":core", "//test-util:test-util", + "//core:mini-cluster" ], run_test_separately=True,) cxx_test( diff --git a/hbase-native-client/core/client-test.cc b/hbase-native-client/core/client-test.cc index 0a45fff..24912cb 100644 --- a/hbase-native-client/core/client-test.cc +++ b/hbase-native-client/core/client-test.cc @@ -57,7 +57,7 @@ class ClientTest { static void CreateHBaseConfWithEnv() { // Creating Empty Config Files so that we dont get a Configuration exception @Client CreateHBaseConf(kDefHBaseConfPath, kHBaseDefaultXml, kHBaseXmlData); - CreateHBaseConf(kDefHBaseConfPath, kHBaseSiteXml, kHBaseXmlData); + //CreateHBaseConf(kDefHBaseConfPath, kHBaseSiteXml, kHBaseXmlData); setenv("HBASE_CONF", kDefHBaseConfPath.c_str(), 1); } }; @@ -116,9 +116,12 @@ TEST(Client, Get) { // Using TestUtil to populate test data hbase::TestUtil *test_util = new hbase::TestUtil(); - test_util->RunShellCmd( - "create 't', 'd'; put 't', 'test2', 'd:2', 'value2'; put 't', 'test2', 'd:extra', 'value for " - "extra'"); + test_util->create_table("t", "d"); + test_util->tablePut("t", "test2", "d", "2", "value2"); + test_util->tablePut("t", "test2", "d", "extra", "value for extra"); +// test_util->RunShellCmd( +// "create 't', 'd'; put 't', 'test2', 'd:2', 'value2'; put 't', 'test2', 'd:extra', 'value for " +// "extra'"); // Create TableName and Row to be fetched from HBase auto tn = folly::to("t"); @@ -203,7 +206,8 @@ TEST(Client, GetForNonExistentRow) { // Using TestUtil to populate test data hbase::TestUtil *test_util = new hbase::TestUtil(); - test_util->RunShellCmd("create 't_exists', 'd'"); + test_util->create_table("t_exists", "d"); + //test_util->RunShellCmd("create 't_exists', 'd'"); // Create TableName and Row to be fetched from HBase auto tn = folly::to("t_exists"); diff --git a/hbase-native-client/core/location-cache-test.cc b/hbase-native-client/core/location-cache-test.cc index 9a778c6..8f62864 100644 --- a/hbase-native-client/core/location-cache-test.cc +++ b/hbase-native-client/core/location-cache-test.cc @@ -59,7 +59,7 @@ TEST(LocationCacheTest, TestGetRegionLocation) { auto tn = folly::to("t"); auto row = "test"; ASSERT_ANY_THROW(cache.LocateFromMeta(tn, row).get(milliseconds(1000))); - test_util.RunShellCmd("create 't', 'd'"); + test_util.create_table("t", "d"); auto loc = cache.LocateFromMeta(tn, row).get(milliseconds(1000)); ASSERT_TRUE(loc != nullptr); cpu->stop(); @@ -83,8 +83,9 @@ TEST(LocationCacheTest, TestCaching) { // test location pulled from meta gets cached ASSERT_ANY_THROW(cache.LocateRegion(tn_1, row_a).get(milliseconds(1000))); ASSERT_ANY_THROW(cache.LocateFromMeta(tn_1, row_a).get(milliseconds(1000))); + test_util.create_table("t1", "d"); - test_util.RunShellCmd("create 't1', 'd'"); +// test_util.RunShellCmd("create 't1', 'd'"); ASSERT_FALSE(cache.IsLocationCached(tn_1, row_a)); auto loc = cache.LocateRegion(tn_1, row_a).get(milliseconds(1000)); @@ -92,7 +93,8 @@ TEST(LocationCacheTest, TestCaching) { ASSERT_EQ(loc, cache.GetCachedLocation(tn_1, row_a)); // test with two regions - test_util.RunShellCmd("create 't2', 'd', SPLITS => ['b']"); + test_util.create_table("t2", "d", "b", NULL); +// test_util.RunShellCmd("create 't2', 'd', SPLITS => ['b']"); ASSERT_FALSE(cache.IsLocationCached(tn_2, "a")); loc = cache.LocateRegion(tn_2, "a").get(milliseconds(1000)); @@ -107,7 +109,9 @@ TEST(LocationCacheTest, TestCaching) { ASSERT_EQ(loc, cache.GetCachedLocation(tn_2, "ba")); // test with three regions - test_util.RunShellCmd("create 't3', 'd', SPLITS => ['b', 'c']"); + test_util.create_table("t3", "d", "b", "c"); + +// test_util.RunShellCmd("create 't3', 'd', SPLITS => ['b', 'c']"); ASSERT_FALSE(cache.IsLocationCached(tn_3, "c")); ASSERT_FALSE(cache.IsLocationCached(tn_3, "ca")); diff --git a/hbase-native-client/core/location-cache.cc b/hbase-native-client/core/location-cache.cc index da9f64a..a32a91b 100644 --- a/hbase-native-client/core/location-cache.cc +++ b/hbase-native-client/core/location-cache.cc @@ -106,7 +106,7 @@ ServerName LocationCache::ReadMetaLocation() { reinterpret_cast(buf->writableData()), &len, nullptr); if (zk_result != ZOK || len < 9) { LOG(ERROR) << "Error getting meta location."; - throw runtime_error("Error getting meta location"); + throw runtime_error("Error getting meta location"+conf_->Get(kHBaseZookeeperQuorum_,"ted")); } buf->append(len); diff --git a/hbase-native-client/test-util/BUCK b/hbase-native-client/test-util/BUCK index c6e41f1..ee9390f 100644 --- a/hbase-native-client/test-util/BUCK +++ b/hbase-native-client/test-util/BUCK @@ -22,9 +22,19 @@ cxx_library(name="test-util", srcs=["test-util.cc"], deps=[ "//third-party:folly", - "//core:core" + "//core:core", + "//core:mini-cluster" ], visibility=[ 'PUBLIC', ], ) +cxx_test( + name="test-util-test", + srcs=["test-util-test.cc",], + deps=[ + "//core:core", + "//test-util:test-util", + "//core:mini-cluster" + ], + run_test_separately=True,) diff --git a/hbase-native-client/test-util/test-util.cc b/hbase-native-client/test-util/test-util.cc index e355bdf..c029061 100644 --- a/hbase-native-client/test-util/test-util.cc +++ b/hbase-native-client/test-util/test-util.cc @@ -18,6 +18,7 @@ */ #include "test-util/test-util.h" +#include #include @@ -43,14 +44,19 @@ std::string TestUtil::RandString(int len) { TestUtil::TestUtil() : temp_dir_(TestUtil::RandString()) { auto p = temp_dir_.path().string(); - auto cmd = std::string{"bin/start-local-hbase.sh " + p}; - auto res_code = std::system(cmd.c_str()); - CHECK_EQ(res_code, 0); + jobject cluster = StartMiniCluster(2); + std::string quorum("localhost:"); + const char* port = mini->getConf(cluster, "hbase.zookeeper.property.clientPort"); + conf()->Set("hbase.zookeeper.quorum", quorum + port); + //auto cmd = std::string{"bin/start-local-hbase.sh " + p}; + //auto res_code = std::system(cmd.c_str()); + //CHECK_EQ(res_code, 0); } TestUtil::~TestUtil() { - auto res_code = std::system("bin/stop-local-hbase.sh"); - CHECK_EQ(res_code, 0); + //auto res_code = std::system("bin/stop-local-hbase.sh"); + //CHECK_EQ(res_code, 0); + StopMiniCluster(); } void TestUtil::RunShellCmd(const std::string &command) { @@ -58,3 +64,20 @@ void TestUtil::RunShellCmd(const std::string &command) { auto res_code = std::system(cmd_string.c_str()); CHECK_EQ(res_code, 0); } + +jobject TestUtil::StartMiniCluster(int num_region_servers) { + mini = new MiniCluster(); + return mini->start_cluster(num_region_servers); +} +void TestUtil::StopMiniCluster() { + mini->stop_cluster(); +} +jobject TestUtil::create_table(char *tblNam, char *familyName) { + return mini->create_table(tblNam, familyName); +} +jobject TestUtil::create_table(char *tblNam, char *familyName, char* key1, char*k2) { + return mini->create_table(tblNam, familyName, key1, k2); +} +jobject TestUtil::tablePut(char *table, char *row, char *fam, char *col, char *value) { + return mini->tablePut(table, row, fam, col, value); +} \ No newline at end of file diff --git a/hbase-native-client/test-util/test-util.h b/hbase-native-client/test-util/test-util.h index cc35511..f917a17 100644 --- a/hbase-native-client/test-util/test-util.h +++ b/hbase-native-client/test-util/test-util.h @@ -23,7 +23,7 @@ #include #include - +#include "core/mini-cluster.h" #include "core/configuration.h" namespace hbase { @@ -62,7 +62,18 @@ class TestUtil { */ std::shared_ptr conf() const { return conf_; } + /** + * Starts mini hbase cluster with specified number of region servers + */ + jobject StartMiniCluster(int num_region_servers); + + void StopMiniCluster(); + jobject create_table(char *tblNam, char *familyName); + jobject create_table(char *tblNam, char *familyName, char* key1, char*k2); + jobject tablePut(char *table, char *row, char *fam, char *col, char *value); + private: + MiniCluster* mini; folly::test::TemporaryDirectory temp_dir_; std::shared_ptr conf_ = std::make_shared(); }; diff --git a/hbase-native-client/core/mini-cluster.cc b/hbase-native-client/core/mini-cluster.cc new file mode 100644 index 0000000..bef5eef --- /dev/null +++ b/hbase-native-client/core/mini-cluster.cc @@ -0,0 +1,399 @@ +/* + * 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. + * + */ + +#include "core/mini-cluster.h" +#include "core/client.h" +#include +#include +#include "core/configuration.h" +#include "core/get.h" +#include "core/hbase_configuration_loader.h" +#include "core/result.h" +#include "core/table.h" +#include "serde/table-name.h" +//#include "/usr/lib/jvm/java-8-openjdk-amd64/include/jni.h" + +#define TABLE_NAME_CLASS "org/apache/hadoop/hbase/TableName" +#define TABLE_CLASS "org/apache/hadoop/hbase/client/Table" +#define ADMIN_CLASS "org/apache/hadoop/hbase/client/Admin" +#define CONN_FACTORY_CLASS "org/apache/hadoop/hbase/client/ConnectionFactory" +#define CONN_CLASS "org/apache/hadoop/hbase/client/Connection" +#define PUT_CLASS "org/apache/hadoop/hbase/client/Put" +#define HTU_CLASS "org/apache/hadoop/hbase/HBaseTestingUtility" +#define MINI_CLUSTER_CLASS "org/apache/hadoop/hbase/MiniHBaseCluster" +#define HADOOP_CONF "org/apache/hadoop/conf/Configuration" + +using hbase::MiniCluster; +JNIEnv* env; +jclass testingUtilClass; +jclass tableNameClass; +jclass tableClass; +jclass connFactoryClass; +jclass connClass; +jclass adminClass; +jclass hbaseMiniClusterClass; +jclass putClass; +jclass confClass; +jclass strClass; +jmethodID stopRSMid; +jmethodID getConfMid; +jmethodID setConfMid; +jmethodID tblNameValueOfMid; +jmethodID createTableMid; +jmethodID createTableWithSplitMid; +jmethodID putMid; +jmethodID putCtor; +jmethodID addColMid; +jmethodID createConnMid; +jmethodID getConnMid; +jmethodID getTableMid; +jmethodID confGetMid; +jmethodID getAdminMid; +jmethodID moveMid; +jmethodID strCtorMid; +pthread_mutex_t count_mutex; +jobject htu; +jobject cluster; +jobject encoding; + char buf[14000]; + + JNIEnv* create_vm(JavaVM **jvm) + { + JavaVMInitArgs args; + JavaVMOption jvm_options; + args.version = JNI_VERSION_1_6; + args.nOptions = 1; + char *classpath = getenv("CLASSPATH"); + if (classpath == NULL || strstr(classpath, "-tests.jar")==NULL) { + FILE *fd = fopen("/tmp/clspath", "r"); + size_t nread; + if (fd) { + int len=strlen(classpath); + // prefix bootstrapper.jar + strcpy(buf, classpath); + strcpy(buf+len, ":"); + nread = fread(buf+len+1, 1, sizeof buf, fd); + if (nread > 0) { + classpath = buf; + *(classpath+nread) = '\0'; + int ret = setenv("CLASSPATH", classpath, 1); + printf("set clspath %d\n", ret); + } + } + fclose(fd); + } + char *options = (char*)malloc(strlen(classpath) + strlen("-Djava.class.path=")) + 2; + strcpy(options, "-Djava.class.path="); + strcpy(options+strlen(options), classpath); + printf("CLASSPATH = %s", classpath); + jvm_options.optionString = options; + args.options = &jvm_options; + args.ignoreUnrecognized = 0; + int rv; + rv = JNI_CreateJavaVM(jvm, (void**)&env, &args); + if (rv < 0 || !env) { + printf("Unable to Launch JVM %d\n",rv); + } else { + printf("Launched JVM! %s\n", options); + } + return env; + } + +void writeConf(jobject conf, const char *filepath) +{ + jclass class_fdesc = (*env).FindClass("java/io/FileDescriptor"); + // construct a new FileDescriptor + jmethodID const_fdesc = (*env).GetMethodID(class_fdesc, "", "()V"); + + jobject file = (*env).NewObject(class_fdesc, const_fdesc); + jfieldID field_fd = (*env).GetFieldID(class_fdesc, "fd", "I"); + + int fd = open(filepath, O_RDWR | O_NONBLOCK | O_CREAT, S_IRWXU); + if (fd < 0) { + printf("Couldn't open file %s\n", filepath); + exit(-1); + } + (*env).SetIntField(file, field_fd, fd); + + jclass cls_outstream = (*env).FindClass("java/io/FileOutputStream"); + jmethodID ctor_stream = (*env).GetMethodID(cls_outstream, "", + "(Ljava/io/FileDescriptor;)V"); + if (ctor_stream == NULL) { + printf("Couldn't get ctor for FileOutputStream\n"); + exit(-1); + } + jobject file_outstream = (*env).NewObject(cls_outstream, ctor_stream, file); + if (file_outstream == NULL) { + printf("Couldn't create FileOutputStream\n"); + exit(-1); + } + jclass class_conf = (*env).FindClass(HADOOP_CONF); + jmethodID writeXmlMid = (*env).GetMethodID(class_conf, "writeXml", + "(Ljava/io/OutputStream;)V"); + (*env).CallObjectMethod(conf, writeXmlMid, file_outstream); +} +void setup() +{ + JavaVM *jvm; + jmethodID constructor; + pthread_mutex_lock(&count_mutex); + if (env == NULL) { + env = create_vm(&jvm); + if (env == NULL) { + exit(-1); + } + testingUtilClass = (*env).FindClass(HTU_CLASS); + //this should be converted to a globalref I think to avoid the underlying java obj getting GC'ed + if (testingUtilClass == NULL) { + printf("Couldn't find class %s", HTU_CLASS); + exit(-1); + } + jmethodID mid = (*env).GetStaticMethodID(testingUtilClass, "createLocalHTU", + "()Lorg/apache/hadoop/hbase/HBaseTestingUtility;"); + htu = (*env).CallStaticObjectMethod(testingUtilClass, mid); + //this should be converted to a globalref I think to avoid the underlying java obj getting GC'ed + if (htu == NULL) { + printf("Couldn't invoke method createLocalHTU in %s", HTU_CLASS); + exit(-1); + } + getConnMid = (*env).GetMethodID(testingUtilClass, "getConnection", + "()Lorg/apache/hadoop/hbase/client/Connection;"); + connClass = (*env).FindClass(CONN_CLASS); + getAdminMid = (*env).GetMethodID(connClass, "getAdmin", + "()Lorg/apache/hadoop/hbase/client/Admin;"); + getTableMid = (*env).GetMethodID(connClass, "getTable", + "(Lorg/apache/hadoop/hbase/TableName;)Lorg/apache/hadoop/hbase/client/Table;"); + if (getTableMid == NULL) { + printf("Couldn't find getConnection\n"); + exit(-1); + } + adminClass = (*env).FindClass(ADMIN_CLASS); + moveMid = (*env).GetMethodID(adminClass, "move", + "([B[B)V"); + if (moveMid == NULL) { + printf("Couldn't find move\n"); + exit(-1); + } + createTableMid = (*env).GetMethodID(testingUtilClass, "createTable", + "(Lorg/apache/hadoop/hbase/TableName;Ljava/lang/String;)Lorg/apache/hadoop/hbase/client/Table;"); + createTableWithSplitMid = (*env).GetMethodID(testingUtilClass, "createTable", + "(Lorg/apache/hadoop/hbase/TableName;[[B[[B)Lorg/apache/hadoop/hbase/client/Table;"); + if (createTableWithSplitMid == NULL) { + printf("Couldn't find method createTable with split\n"); + exit(-1); + } + + tableNameClass = (*env).FindClass(TABLE_NAME_CLASS); + tblNameValueOfMid = (*env).GetStaticMethodID(tableNameClass, "valueOf", + "(Ljava/lang/String;)Lorg/apache/hadoop/hbase/TableName;"); + if (tblNameValueOfMid == NULL) { + printf("Couldn't find method valueOf in %s\n", TABLE_NAME_CLASS); + exit(-1); + } + hbaseMiniClusterClass = (*env).FindClass(MINI_CLUSTER_CLASS); + stopRSMid = (*env).GetMethodID(hbaseMiniClusterClass, "stopRegionServer", + "(I)Lorg/apache/hadoop/hbase/util/JVMClusterUtil$RegionServerThread;"); + getConfMid = (*env).GetMethodID(hbaseMiniClusterClass, "getConfiguration", + "()Lorg/apache/hadoop/conf/Configuration;"); + + confClass = (*env).FindClass(HADOOP_CONF); + setConfMid = (*env).GetMethodID(confClass, "set", + "(Ljava/lang/String;Ljava/lang/String;)V"); + if (setConfMid == NULL) { + printf("Couldn't find method getConf in %s\n", MINI_CLUSTER_CLASS); + exit(-1); + } + confGetMid = (*env).GetMethodID(confClass, "get", + "(Ljava/lang/String;)Ljava/lang/String;"); + + tableClass = (*env).FindClass(TABLE_CLASS); + putMid = (*env).GetMethodID(tableClass, "put", + "(Lorg/apache/hadoop/hbase/client/Put;)V"); + if (putMid == NULL) { + printf("Couldn't find method put in %s\n", TABLE_CLASS); + exit(-1); + } + connFactoryClass = (*env).FindClass(CONN_FACTORY_CLASS); + createConnMid = (*env).GetStaticMethodID(connFactoryClass, "createConnection", + "()Lorg/apache/hadoop/hbase/client/Connection;"); + if (createConnMid == NULL) { + printf("Couldn't find createConnection\n"); + exit(-1); + } + putClass = (*env).FindClass(PUT_CLASS); + putCtor = (*env).GetMethodID(putClass, "", "([B)V"); + addColMid = (*env).GetMethodID(putClass, "addColumn", + "([B[B[B)Lorg/apache/hadoop/hbase/client/Put;"); + if (addColMid == NULL) { + printf("Couldn't find method addColumn\n"); + exit(-1); + } + } + pthread_mutex_unlock(&count_mutex); +} + +jobject getHTU() +{ + setup(); + return htu; +} + +JNIEnv *getEnv() +{ + setup(); + return env; +} +// converts C char* to Java byte[] +jbyteArray str_to_byte_array(char *str) { + char* p = str; + int n = 0; + while (*p++) { + n++; + } + if (n == 0) return NULL; + jbyteArray arr = (*env).NewByteArray(n); + (*env).SetByteArrayRegion(arr, 0, n, (jbyte*)str); + return arr; +} + +jobject MiniCluster::create_table(char *tblNam, char *familyName) +{ + jstring tblNameStr = (*env).NewStringUTF(tblNam); + jobject tblName = (*env).CallStaticObjectMethod(tableNameClass, tblNameValueOfMid, + tblNameStr); + jstring famStr = (*env).NewStringUTF(familyName); + jobject tbl = (*env).CallObjectMethod(htu, createTableMid, tblName, famStr); + return tbl; +} +jobject MiniCluster::create_table(char *tblNam, char *familyName, char* key1, char*key2) +{ + jstring tblNameStr = (*env).NewStringUTF(tblNam); + jobject tblName = (*env).CallStaticObjectMethod(tableNameClass, tblNameValueOfMid, + tblNameStr); + jclass arrayElemType = env->FindClass("[B"); + + jobjectArray famArray = env->NewObjectArray(1, arrayElemType, env->NewByteArray(1)); + env->SetObjectArrayElement(famArray, 0, str_to_byte_array(familyName)); + + int len = 2; + if (key2 == NULL) len = 1; + jobjectArray keyArray = env->NewObjectArray(len, arrayElemType, env->NewByteArray(1)); + + env->SetObjectArrayElement(keyArray, 0, str_to_byte_array(key1)); + if (key2 != NULL) { + env->SetObjectArrayElement(keyArray, 1, str_to_byte_array(key2)); + } + jobject tbl = (*env).CallObjectMethod(htu, createTableWithSplitMid, tblName, famArray, keyArray); + return tbl; +} +jobject MiniCluster::stop_region_server(jobject cluster, int idx) +{ + env = getEnv(); + (*env).CallObjectMethod(cluster, stopRSMid, (jint)idx); +} + +void table_put(jobject tbl, jobject put) { + (*env).CallObjectMethod(tbl, putMid, put); +} + +// returns the Configuration for the cluster +jobject MiniCluster::getConf(jobject cluster) +{ + JNIEnv* env = getEnv(); + return (*env).CallObjectMethod(cluster, getConfMid); +} +// return the Admin instance for the local cluster +jobject getAdmin() +{ + JNIEnv* env = getEnv(); + jobject conn = (*env).CallObjectMethod(getHTU(), getConnMid); + jobject admin = (*env).CallObjectMethod(conn, getAdminMid); + return admin; +} + +jobject MiniCluster::tablePut(char *table, char *row, char *fam, char *col, char *value) +{ + JNIEnv* env = getEnv(); + jobject conn = (*env).CallObjectMethod(getHTU(), getConnMid); + jobject put = env->NewObject(putClass, putCtor, str_to_byte_array(row)); + if (put == 0) { + printf("Couldn't create Put"); + exit(-1); + } + (*env).CallObjectMethod(put, addColMid, str_to_byte_array(fam), str_to_byte_array(col), + str_to_byte_array(value)); + jobject tblName = (*env).CallStaticObjectMethod(tableNameClass, tblNameValueOfMid, + (*env).NewStringUTF(table)); + jobject tableObj = (*env).CallObjectMethod(conn, getTableMid, tblName); + (*env).CallObjectMethod(tableObj, putMid, put); + return tableObj; +} + +// moves region to server +void MiniCluster::moveRegion(char *region, char *server) +{ + jobject admin = getAdmin(); + (*env).CallObjectMethod(admin, moveMid, str_to_byte_array(region), + str_to_byte_array(server)); +} + +jobject MiniCluster::start_cluster(int numRegionServers) +{ + env = getEnv(); + jmethodID mid = (*env).GetMethodID(testingUtilClass, "startMiniCluster", + "(I)Lorg/apache/hadoop/hbase/MiniHBaseCluster;"); + if (mid == 0) { + printf("Couldn't find method startMiniCluster in the class %s", HTU_CLASS); + exit(-1); + } + cluster = (*env).CallObjectMethod(getHTU(), mid, (jint)numRegionServers); + printf("retrieving port"); + jobject conf = getConf(cluster); + jstring jport = (jstring)(*env).CallObjectMethod(conf, confGetMid, + (*env).NewStringUTF("hbase.zookeeper.property.clientPort")); + const char* port = (*env).GetStringUTFChars(jport, 0); + printf("retrieved port %s", port); + char buf[34]; + strcpy(buf, "localhost:"); + strcpy(buf+10, port); + (*env).CallObjectMethod(conf, setConfMid, (*env).NewStringUTF("hbase.zookeeper.quorum"), (*env).NewStringUTF(buf)); + writeConf(conf, "./build/test-data/client-test/conf/hbase-site.xml"); + return cluster; +} + +void MiniCluster::stop_cluster() +{ + env = getEnv(); + jmethodID mid = (*env).GetMethodID(testingUtilClass, + "shutdownMiniCluster","()V"); + (*env).CallVoidMethod(getHTU(), mid); +} + +// cluster is the object returned by start_cluster() +//const char* getConf(jobject cluster, const std::string& key) +const char* MiniCluster::getConf(jobject cluster, char* key) +{ + jobject conf = getConf(cluster); + printf("retrieving %s\n", key); + jstring jval = (jstring)(*env).CallObjectMethod(conf, confGetMid, + (*env).NewStringUTF(key)); + const char* val = (*env).GetStringUTFChars(jval, 0); + printf("Got string %s\n", val); + return val; +} diff --git a/hbase-native-client/core/mini-cluster.h b/hbase-native-client/core/mini-cluster.h new file mode 100644 index 0000000..a4afa30 --- /dev/null +++ b/hbase-native-client/core/mini-cluster.h @@ -0,0 +1,45 @@ +/* + * 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. + * + */ +#pragma once + +#include "core/client.h" +#include +#include "core/configuration.h" +#include "core/get.h" +#include "core/hbase_configuration_loader.h" +#include "core/result.h" +#include "core/table.h" +#include "serde/table-name.h" +#include "jni.h" +namespace hbase { +class MiniCluster { + public: +jobject start_cluster(int numRegionServers); +void stop_cluster(); +jobject create_table(char *tblNam, char *familyName); +jobject create_table(char *tblNam, char *familyName, char* key1, char*k2); +jobject stop_region_server(jobject cluster, int idx); + +// moves region to server +void moveRegion(char *region, char *server); +jobject getConf(jobject cluster); +const char* getConf(jobject cluster, char* key); +jobject tablePut(char *table, char *row, char *fam, char *col, char *value); +}; +} /*namespace hbase*/