diff --git a/hbase-native-client/src/hbase/client/BUCK b/hbase-native-client/src/hbase/client/BUCK index 1a8f434..d036a6b 100644 --- a/hbase-native-client/src/hbase/client/BUCK +++ b/hbase-native-client/src/hbase/client/BUCK @@ -298,4 +298,5 @@ cxx_binary( srcs=[ "load-client.cc", ], - deps=[":client", "//src/hbase/connection:connection"],) + deps=[":client", "//src/hbase/connection:connection", + "//src/hbase/test-util:test-util"],) diff --git a/hbase-native-client/src/hbase/client/load-client.cc b/hbase-native-client/src/hbase/client/load-client.cc index a321845..ca8601f 100644 --- a/hbase-native-client/src/hbase/client/load-client.cc +++ b/hbase-native-client/src/hbase/client/load-client.cc @@ -31,6 +31,7 @@ #include "hbase/client/put.h" #include "hbase/client/table.h" #include "hbase/serde/table-name.h" +#include "hbase/test-util/monkey-runner.h" #include "hbase/utils/time-util.h" using hbase::Client; @@ -56,6 +57,7 @@ DEFINE_bool(gets, true, "perform gets"); DEFINE_bool(scans, true, "perform scans"); DEFINE_bool(puts, true, "perform put's"); DEFINE_bool(appends, true, "perform append's"); +DEFINE_string(monkey, "", "activate designated chaos monkey, such as slowDeterministic"); static constexpr const char *kNumColumn = "num"; static constexpr const char *incrPrefix = "i"; @@ -296,6 +298,15 @@ int main(int argc, char *argv[]) { conf = std::make_shared(loader.LoadDefaultResources().value()); } auto tn = std::make_shared(folly::to(FLAGS_table)); + hbase::MonkeyRunner runner; + if (!FLAGS_monkey.empty()) { + if (FLAGS_conf == "") { + LOG(ERROR) + << "Must provide conf directory where hbase-site.xml points to distributed cluster"; + return -1; + } + runner.Run(FLAGS_monkey, FLAGS_table, FLAGS_conf); + } auto num_puts = FLAGS_num_rows; auto client = std::make_unique(*conf); diff --git a/hbase-native-client/src/hbase/test-util/BUCK b/hbase-native-client/src/hbase/test-util/BUCK index f1aedab..349c331 100644 --- a/hbase-native-client/src/hbase/test-util/BUCK +++ b/hbase-native-client/src/hbase/test-util/BUCK @@ -19,8 +19,8 @@ import os cxx_library( name="test-util", header_namespace="hbase/test-util", - exported_headers=["test-util.h", "mini-cluster.h"], - srcs=["test-util.cc", "mini-cluster.cc"], + exported_headers=["test-util.h", "mini-cluster.h", "monkey-runner.h"], + srcs=["test-util.cc", "mini-cluster.cc", "monkey-runner.cc"], deps=[ "//third-party:folly", "//src/hbase/client:client", diff --git a/hbase-native-client/src/hbase/test-util/mini-cluster.cc b/hbase-native-client/src/hbase/test-util/mini-cluster.cc index 1e491a2..2f55fee 100644 --- a/hbase-native-client/src/hbase/test-util/mini-cluster.cc +++ b/hbase-native-client/src/hbase/test-util/mini-cluster.cc @@ -65,9 +65,10 @@ JNIEnv *MiniCluster::CreateVM(JavaVM **jvm) { args.options = &jvm_options; args.ignoreUnrecognized = 0; int rv; - rv = JNI_CreateJavaVM(jvm, reinterpret_cast(&env_), &args); - CHECK(rv >= 0 && env_); - return env_; + JNIEnv *env; + rv = JNI_CreateJavaVM(jvm, reinterpret_cast(&env), &args); + CHECK(rv >= 0 && env); + return env; } MiniCluster::~MiniCluster() { @@ -189,13 +190,13 @@ JNIEnv *MiniCluster::env() { return env_; } // converts C char* to Java byte[] -jbyteArray MiniCluster::StrToByteChar(const std::string &str) { +jbyteArray MiniCluster::StrToByteChar(JNIEnv *env, const std::string &str) { if (str.length() == 0) { return nullptr; } int n = str.length(); - jbyteArray arr = env_->NewByteArray(n); - env_->SetByteArrayRegion(arr, 0, n, reinterpret_cast(str.c_str())); + jbyteArray arr = env->NewByteArray(n); + env->SetByteArrayRegion(arr, 0, n, reinterpret_cast(str.c_str())); return arr; } @@ -217,7 +218,7 @@ jobject MiniCluster::CreateTable(const std::string &table, jobjectArray family_array = env_->NewObjectArray(families.size(), array_element_type, nullptr); int i = 0; for (auto family : families) { - env_->SetObjectArrayElement(family_array, i++, StrToByteChar(family)); + env_->SetObjectArrayElement(family_array, i++, StrToByteChar(env_, family)); } jobject table_obj = env_->CallObjectMethod(htu_, create_table_families_mid_, table_name, family_array); @@ -241,14 +242,14 @@ jobject MiniCluster::CreateTable(const std::string &table, const std::vectorNewObjectArray(families.size(), array_element_type, nullptr); for (auto family : families) { - env_->SetObjectArrayElement(family_array, i++, StrToByteChar(family)); + env_->SetObjectArrayElement(family_array, i++, StrToByteChar(env_, family)); } jobjectArray key_array = env_->NewObjectArray(keys.size(), array_element_type, nullptr); i = 0; for (auto key : keys) { - env_->SetObjectArrayElement(key_array, i++, StrToByteChar(key)); + env_->SetObjectArrayElement(key_array, i++, StrToByteChar(env_, key)); } jobject tbl = env_->CallObjectMethod(htu_, create_table_with_split_mid_, table_name, family_array, @@ -277,7 +278,7 @@ jobject MiniCluster::admin() { // moves region to server void MiniCluster::MoveRegion(const std::string ®ion, const std::string &server) { jobject admin_ = admin(); - env_->CallObjectMethod(admin_, move_mid_, StrToByteChar(region), StrToByteChar(server)); + env_->CallObjectMethod(admin_, move_mid_, StrToByteChar(env_, region), StrToByteChar(env_, server)); } jobject MiniCluster::StartCluster(int num_region_servers) { diff --git a/hbase-native-client/src/hbase/test-util/mini-cluster.h b/hbase-native-client/src/hbase/test-util/mini-cluster.h index 6b4547c..d9ebd1d 100644 --- a/hbase-native-client/src/hbase/test-util/mini-cluster.h +++ b/hbase-native-client/src/hbase/test-util/mini-cluster.h @@ -43,6 +43,8 @@ class MiniCluster { jobject GetConf(); // returns the value for config key retrieved from cluster const std::string GetConfValue(const std::string &key); + static JNIEnv *CreateVM(JavaVM **jvm); + static jbyteArray StrToByteChar(JNIEnv *env, const std::string &str); private: JNIEnv *env_; @@ -71,11 +73,9 @@ class MiniCluster { jobject cluster_; pthread_mutex_t count_mutex_; JavaVM *jvm_; - JNIEnv *CreateVM(JavaVM **jvm); void Setup(); jobject htu(); JNIEnv *env(); - jbyteArray StrToByteChar(const std::string &str); jobject admin(); }; } /*namespace hbase*/ diff --git a/hbase-native-client/src/hbase/test-util/monkey-runner.h b/hbase-native-client/src/hbase/test-util/monkey-runner.h new file mode 100644 index 0000000..c66d1c4 --- /dev/null +++ b/hbase-native-client/src/hbase/test-util/monkey-runner.h @@ -0,0 +1,46 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "hbase/test-util/mini-cluster.h" + +namespace hbase { + +class MonkeyRunner { + public: + MonkeyRunner(); + ~MonkeyRunner(); + void Run(std::string monkey, std::string tablename, std::string confdir); + void Stop(); + + private: + JNIEnv *env_; + JavaVM *jvm_; + jclass runner_class_; + std::thread monkey_runner_; + jmethodID stop_method_; +}; +} /*namespace hbase*/ diff --git a/hbase-native-client/src/hbase/test-util/monkey-runner.cc b/hbase-native-client/src/hbase/test-util/monkey-runner.cc new file mode 100644 index 0000000..fa5023c --- /dev/null +++ b/hbase-native-client/src/hbase/test-util/monkey-runner.cc @@ -0,0 +1,66 @@ +/* + * 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 "hbase/test-util/monkey-runner.h" +#include +#include +#include +#include +#include + +using hbase::MonkeyRunner; + +MonkeyRunner::MonkeyRunner() {} + +void MonkeyRunner::Run(std::string monkey, std::string tablename, std::string confdir) { + monkey_runner_ = std::thread([&] { + env_ = MiniCluster::CreateVM(&jvm_); + runner_class_ = env_->FindClass("org/apache/hadoop/hbase/chaos/util/ChaosMonkeyRunner"); + if (runner_class_ == NULL) { + LOG(ERROR) << "Couldn't find class ChaosMonkeyRunner"; + exit(-1); + } + jmethodID runner_method = + env_->GetStaticMethodID(runner_class_, "main", "([Ljava/lang/String;)V"); + if (runner_method == NULL) { + LOG(ERROR) << "Couldn't find main for ChaosMonkeyRunner"; + exit(-1); + } + stop_method_ = env_->GetStaticMethodID(runner_class_, "stopRunner", "()V"); + + jclass str_class = env_->FindClass("java/lang/String"); + jobjectArray args = env_->NewObjectArray(6, str_class, nullptr); + env_->SetObjectArrayElement(args, 0, env_->NewStringUTF("-c")); + env_->SetObjectArrayElement(args, 1, env_->NewStringUTF((confdir + "/hbase-site.xml").c_str())); + env_->SetObjectArrayElement(args, 2, env_->NewStringUTF("-m")); + env_->SetObjectArrayElement(args, 3, env_->NewStringUTF(monkey.c_str())); + env_->SetObjectArrayElement(args, 4, env_->NewStringUTF("--tableName")); + env_->SetObjectArrayElement(args, 5, env_->NewStringUTF(tablename.c_str())); + + env_->CallStaticObjectMethod(runner_class_, runner_method, args); + }); +} + +void MonkeyRunner::Stop() { + if (stop_method_ != NULL) { + env_->CallStaticObjectMethod(runner_class_, stop_method_); + } +} +MonkeyRunner::~MonkeyRunner() { +}