| // 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 "runtime/hbase-table.h" | |
| #include <string> | |
| #include "runtime/runtime-state.h" | |
| #include "util/jni-util.h" | |
| #include "common/names.h" | |
| namespace impala { | |
| jclass HBaseTable::table_cl_ = NULL; | |
| jmethodID HBaseTable::table_close_id_ = NULL; | |
| jmethodID HBaseTable::table_get_scanner_id_ = NULL; | |
| jmethodID HBaseTable::table_put_id_ = NULL; | |
| jclass HBaseTable::connection_cl_ = NULL; | |
| jmethodID HBaseTable::connection_get_table_id_ = NULL; | |
| jclass HBaseTable::table_name_cl_ = NULL; | |
| jmethodID HBaseTable::table_name_value_of_id_ = NULL; | |
| HBaseTable::HBaseTable(const string& table_name, jobject connection) | |
| : table_name_(table_name), | |
| connection_(connection), | |
| table_(NULL) { | |
| } | |
| HBaseTable::~HBaseTable() { | |
| DCHECK(table_ == NULL) << "Must call Close()"; | |
| } | |
| void HBaseTable::Close(RuntimeState* state) { | |
| // If this has already been closed then return out early. | |
| if (table_ == NULL) return; | |
| JNIEnv* env = JniUtil::GetJNIEnv(); | |
| if (env == NULL) { | |
| state->LogError(ErrorMsg( | |
| TErrorCode::GENERAL, "HBaseTable::Close(): Error creating JNIEnv")); | |
| } else { | |
| env->CallObjectMethod(table_, table_close_id_); | |
| Status s = JniUtil::GetJniExceptionMsg(env, true, "HBaseTable::Close(): "); | |
| if (!s.ok()) state->LogError(s.msg()); | |
| env->DeleteGlobalRef(table_); | |
| } | |
| table_ = NULL; | |
| } | |
| Status HBaseTable::Init() { | |
| JNIEnv* env = JniUtil::GetJNIEnv(); | |
| JniLocalFrame jni_frame; | |
| RETURN_IF_ERROR(jni_frame.push(env)); | |
| if (env == NULL) return Status("Error creating JNIEnv"); | |
| // Get a TableName object from the table name | |
| jstring jtable_name_string = env->NewStringUTF(table_name_.c_str()); | |
| RETURN_ERROR_IF_EXC(env); | |
| // Convert into a TableName object | |
| jobject jtable_name = env->CallStaticObjectMethod(table_name_cl_, | |
| table_name_value_of_id_, jtable_name_string); | |
| RETURN_ERROR_IF_EXC(env); | |
| // Get a Table from the Connection. | |
| jobject local_table = env->CallObjectMethod(connection_, connection_get_table_id_, | |
| jtable_name); | |
| RETURN_ERROR_IF_EXC(env); | |
| // Make sure the GC doesn't remove the Table until told to. All local refs | |
| // will be deleted when the JniLocalFrame goes out of scope. | |
| RETURN_IF_ERROR(JniUtil::LocalToGlobalRef(env, local_table, &table_)); | |
| return Status::OK(); | |
| } | |
| Status HBaseTable::InitJNI() { | |
| JNIEnv* env = JniUtil::GetJNIEnv(); | |
| if (env == NULL) { | |
| return Status("Failed to get/create JVM"); | |
| } | |
| // TableName | |
| RETURN_IF_ERROR( | |
| JniUtil::GetGlobalClassRef(env, "org/apache/hadoop/hbase/TableName", | |
| &table_name_cl_)); | |
| table_name_value_of_id_ = env->GetStaticMethodID(table_name_cl_, "valueOf", | |
| "(Ljava/lang/String;)Lorg/apache/hadoop/hbase/TableName;"); | |
| RETURN_ERROR_IF_EXC(env); | |
| // Table | |
| RETURN_IF_ERROR( | |
| JniUtil::GetGlobalClassRef(env, "org/apache/hadoop/hbase/client/Table", | |
| &table_cl_)); | |
| table_close_id_ = env->GetMethodID(table_cl_, "close", "()V"); | |
| RETURN_ERROR_IF_EXC(env); | |
| table_get_scanner_id_ = env->GetMethodID(table_cl_, "getScanner", | |
| "(Lorg/apache/hadoop/hbase/client/Scan;)" | |
| "Lorg/apache/hadoop/hbase/client/ResultScanner;"); | |
| RETURN_ERROR_IF_EXC(env); | |
| table_put_id_ = env->GetMethodID(table_cl_, "put", "(Ljava/util/List;)V"); | |
| RETURN_ERROR_IF_EXC(env); | |
| // Connection | |
| RETURN_IF_ERROR( | |
| JniUtil::GetGlobalClassRef(env, | |
| "org/apache/hadoop/hbase/client/Connection", &connection_cl_)); | |
| connection_get_table_id_= env->GetMethodID(connection_cl_, "getTable", | |
| "(Lorg/apache/hadoop/hbase/TableName;)" | |
| "Lorg/apache/hadoop/hbase/client/Table;"); | |
| RETURN_ERROR_IF_EXC(env); | |
| return Status::OK(); | |
| } | |
| Status HBaseTable::GetResultScanner(const jobject& scan, | |
| jobject* result_scanner) { | |
| JNIEnv* env = JniUtil::GetJNIEnv(); | |
| if (env == NULL) return Status("Error creating JNIEnv"); | |
| (*result_scanner) = env->CallObjectMethod(table_, | |
| table_get_scanner_id_, scan); | |
| RETURN_ERROR_IF_EXC(env); | |
| return Status::OK(); | |
| } | |
| Status HBaseTable::Put(const jobject& puts_list) { | |
| JNIEnv* env = JniUtil::GetJNIEnv(); | |
| if (env == NULL) return Status("Error creating JNIEnv"); | |
| env->CallObjectMethod(table_, table_put_id_, puts_list); | |
| RETURN_ERROR_IF_EXC(env); | |
| // TODO(eclark): FlushCommits | |
| return Status::OK(); | |
| } | |
| } // namespace impala |