HBASE-15771 Document all the public classes Summary: Add on a bunch of documentation around implementation so far.
Test Plan: make doc Doxygen has no warnings Differential Revision: https://reviews.facebook.net/D57753 Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/fdf00239 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/fdf00239 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/fdf00239 Branch: refs/heads/HBASE-14850 Commit: fdf00239c691d0de9b1b97745dafe1cea57dbf9c Parents: 16e1de7 Author: Elliott Clark <ecl...@apache.org> Authored: Thu May 5 13:14:20 2016 -0700 Committer: Elliott Clark <ecl...@apache.org> Committed: Mon Jul 11 16:47:26 2016 -0700 ---------------------------------------------------------------------- hbase-native-client/BUILDING.md | 18 +++++- .../connection/client-dispatcher.h | 11 +++- .../connection/client-handler.cc | 37 +++++------- hbase-native-client/connection/client-handler.h | 36 +++++++----- .../connection/connection-factory.h | 18 ++++++ .../connection/connection-pool.cc | 5 +- .../connection/connection-pool.h | 44 +++++++++++++- hbase-native-client/connection/pipeline.h | 18 ++++++ hbase-native-client/connection/request.h | 32 ++++++---- hbase-native-client/connection/response.h | 33 +++++++++-- hbase-native-client/core/BUCK | 1 - hbase-native-client/core/client.h | 12 ++++ hbase-native-client/core/connection.cc | 20 ------- hbase-native-client/core/connection.h | 26 --------- hbase-native-client/core/location-cache.cc | 14 ++++- hbase-native-client/core/location-cache.h | 36 ++++++++++-- hbase-native-client/core/meta-utils.h | 12 ++++ hbase-native-client/core/put.cc | 21 ------- hbase-native-client/core/put.h | 27 --------- hbase-native-client/core/region-location.h | 41 +++++++++++++ hbase-native-client/serde/rpc.cc | 1 - hbase-native-client/serde/rpc.h | 61 +++++++++++++++++++- hbase-native-client/serde/zk.h | 14 +++++ hbase-native-client/utils/user-util.h | 18 ++++++ 24 files changed, 387 insertions(+), 169 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/BUILDING.md ---------------------------------------------------------------------- diff --git a/hbase-native-client/BUILDING.md b/hbase-native-client/BUILDING.md index 20ef2a0..4c06776 100644 --- a/hbase-native-client/BUILDING.md +++ b/hbase-native-client/BUILDING.md @@ -17,7 +17,7 @@ specific language governing permissions and limitations under the License. --> -#Building HBase native client +# Building HBase native client The HBase native client build using buck and produces a linux library. @@ -58,6 +58,20 @@ buck build //core:simple-client ``` That will build the library, then build and test everything, then build -the simple-client binary. Buck will find all modules used, and compile +the simple-client binary. Buck will find all modules used, and compile them in parallel, caching the results. Output from buck is in the buck-out foulder. Generated binaries are in buck-out/gen logs are in buck-out/logs + + +# Make + +If learning buck isn't your thing there is a Makefile wrapper for your +convenience. + +``` +make help +make check +make clean +make all +make build +``` http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/client-dispatcher.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/client-dispatcher.h b/hbase-native-client/connection/client-dispatcher.h index 4435a1b..4bfb35d 100644 --- a/hbase-native-client/connection/client-dispatcher.h +++ b/hbase-native-client/connection/client-dispatcher.h @@ -30,17 +30,22 @@ #include "connection/response.h" namespace hbase { +/** + * Dispatcher that assigns a call_id and then routes the response back to the future. + */ class ClientDispatcher : public wangle::ClientDispatcherBase<SerializePipeline, std::unique_ptr<Request>, Response> { public: + /** Create a new ClientDispatcher */ ClientDispatcher(); - ~ClientDispatcher() { - LOG(ERROR) << "Killing ClientDispatcher call_id = " << current_call_id_; - } + /** Read a response off the pipeline. */ void read(Context *ctx, Response in) override; + /** Take a request as a call and send it down the pipeline. */ folly::Future<Response> operator()(std::unique_ptr<Request> arg) override; + /** Close the dispatcher and the associated pipeline. */ folly::Future<folly::Unit> close(Context *ctx) override; + /** Close the dispatcher and the associated pipeline. */ folly::Future<folly::Unit> close() override; private: http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/client-handler.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/client-handler.cc b/hbase-native-client/connection/client-handler.cc index 4fdb7ae..cae03c7 100644 --- a/hbase-native-client/connection/client-handler.cc +++ b/hbase-native-client/connection/client-handler.cc @@ -37,7 +37,7 @@ using hbase::pb::GetResponse; using google::protobuf::Message; ClientHandler::ClientHandler(std::string user_name) - : user_name_(user_name), serde_(), header_info_(), + : user_name_(user_name), serde_(), once_flag_(), resp_msgs_( make_unique<folly::AtomicHashMap< uint32_t, std::shared_ptr<google::protobuf::Message>>>(5000)) {} @@ -75,36 +75,25 @@ void ClientHandler::read(Context *ctx, std::unique_ptr<IOBuf> buf) { used_bytes = serde_.ParseDelimited(buf.get(), resp_msg.get()); // Make sure that bytes were parsed. CHECK(used_bytes == buf->length()); - received.set_response(resp_msg); + received.set_resp_msg(resp_msg); } ctx->fireRead(std::move(received)); } } Future<Unit> ClientHandler::write(Context *ctx, std::unique_ptr<Request> r) { - // Keep track of if we have sent the header. - // - // even though the bool is atomic we can load it lazily here. - if (UNLIKELY(header_info_->need_.load(std::memory_order_relaxed))) { - - // Grab the lock. - // We need to make sure that no one gets past here without there being a - // hearder sent. - std::lock_guard<std::mutex> lock(header_info_->mutex_); - - // Now see if we are the first thread to get through. - // - // If this is the first thread to get through then the - // need_send_header will have been true before this. - if (header_info_->need_.exchange(false)) { - auto pre = serde_.Preamble(); - auto header = serde_.Header(user_name_); - pre->appendChain(std::move(header)); - ctx->fireWrite(std::move(pre)); - } - } - + // We need to send the header once. + // So use call_once to make sure that only one thread wins this. + std::call_once((*once_flag_), [ctx, this]() { + auto pre = serde_.Preamble(); + auto header = serde_.Header(user_name_); + pre->appendChain(std::move(header)); + ctx->fireWrite(std::move(pre)); + }); + + // Now store the call id to response. resp_msgs_->insert(r->call_id(), r->resp_msg()); + // Send the data down the pipeline. return ctx->fireWrite( serde_.Request(r->call_id(), r->method(), r->req_msg().get())); } http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/client-handler.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/client-handler.h b/hbase-native-client/connection/client-handler.h index 1a4275f..984a947 100644 --- a/hbase-native-client/connection/client-handler.h +++ b/hbase-native-client/connection/client-handler.h @@ -41,17 +41,38 @@ class Message; namespace hbase { +/** + * wangle::Handler implementation to convert hbase::Request to IOBuf and + * convert IOBuf to hbase::Response. + * + * This class deals with sending the connection header and preamble + * on first request. + */ class ClientHandler : public wangle::Handler<std::unique_ptr<folly::IOBuf>, Response, std::unique_ptr<Request>, std::unique_ptr<folly::IOBuf>> { public: + /** + * Create the handler + * @param user_name the user name of the user running this process. + */ ClientHandler(std::string user_name); + + /** + * Get bytes from the wire. + * This should be the full message as the length field decoder should be + * in the pipeline before this. + */ void read(Context *ctx, std::unique_ptr<folly::IOBuf> msg) override; + + /** + * Write the data down the wire. + */ folly::Future<folly::Unit> write(Context *ctx, std::unique_ptr<Request> r) override; private: - std::unique_ptr<HeaderInfo> header_info_; + std::unique_ptr<std::once_flag> once_flag_; std::string user_name_; RpcSerde serde_; @@ -60,17 +81,4 @@ private: uint32_t, std::shared_ptr<google::protobuf::Message>>> resp_msgs_; }; - -/** - * Class to contain the info about if the connection header and preamble has - * been sent. - * - * We use a serperate class here so that ClientHandler is relocatable. - */ -class HeaderInfo { -public: - HeaderInfo() : need_(true), mutex_() {} - std::atomic<bool> need_; - std::mutex mutex_; -}; } // namespace hbase http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/connection-factory.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/connection-factory.h b/hbase-native-client/connection/connection-factory.h index 2284a7c..8b6d8d8 100644 --- a/hbase-native-client/connection/connection-factory.h +++ b/hbase-native-client/connection/connection-factory.h @@ -28,14 +28,32 @@ #include "connection/service.h" namespace hbase { + +/** + * Class to create a ClientBootstrap and turn it into a connected + * pipeline. + */ class ConnectionFactory { public: + /** + * Constructor. + * There should only be one ConnectionFactory per client. + */ ConnectionFactory(); + /** Default Desctructor */ virtual ~ConnectionFactory() = default; + /** + * Create a BootStrap from which a connection can be made. + */ virtual std::shared_ptr<wangle::ClientBootstrap<SerializePipeline>> MakeBootstrap(); + /** + * Connect a ClientBootstrap to a server and return the pipeline. + * + * This is mostly visible so that mocks can override socket connections. + */ virtual std::shared_ptr<HBaseService> Connect(std::shared_ptr<wangle::ClientBootstrap<SerializePipeline>> client, const std::string &hostname, int port); http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/connection-pool.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/connection-pool.cc b/hbase-native-client/connection/connection-pool.cc index 6ed5ad9..75f343e 100644 --- a/hbase-native-client/connection/connection-pool.cc +++ b/hbase-native-client/connection/connection-pool.cc @@ -26,11 +26,11 @@ using std::mutex; using std::unique_ptr; using std::shared_ptr; using hbase::pb::ServerName; +using hbase::ConnectionPool; +using hbase::HBaseService; using folly::SharedMutexWritePriority; using folly::SocketAddress; -namespace hbase { - ConnectionPool::ConnectionPool() : cf_(std::make_shared<ConnectionFactory>()), clients_(), connections_(), map_mutex_() {} @@ -75,4 +75,3 @@ void ConnectionPool::close(const ServerName &sn) { auto service = found->second; connections_.erase(found); } -} http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/connection-pool.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/connection-pool.h b/hbase-native-client/connection/connection-pool.h index 907afdb..5edd407 100644 --- a/hbase-native-client/connection/connection-pool.h +++ b/hbase-native-client/connection/connection-pool.h @@ -18,6 +18,7 @@ */ #pragma once +#include <boost/functional/hash.hpp> #include <folly/SharedMutex.h> #include <mutex> #include <unordered_map> @@ -27,26 +28,63 @@ #include "if/HBase.pb.h" namespace hbase { + +/** Equals function for server name that ignores start time */ struct ServerNameEquals { + + /** equals */ bool operator()(const hbase::pb::ServerName &lhs, const hbase::pb::ServerName &rhs) const { return lhs.host_name() == rhs.host_name() && lhs.port() == rhs.port(); } }; + +/** Hash for ServerName that ignores the start time. */ struct ServerNameHash { + /** hash */ std::size_t operator()(hbase::pb::ServerName const &s) const { - std::size_t h1 = std::hash<std::string>()(s.host_name()); - std::size_t h2 = std::hash<uint32_t>()(s.port()); - return h1 ^ (h2 << 2); + std::size_t h = 0; + boost::hash_combine(h, s.host_name()); + boost::hash_combine(h, s.port()); + return h; } }; +/** + * @brief Connection pooling for HBase rpc connection. + * + * This is a thread safe connection pool. It allows getting + * a shared connection to HBase by server name. This is + * useful for keeping a single connection no matter how many regions a + * regionserver has on it. + */ class ConnectionPool { public: + /** Create connection pool wit default connection factory */ ConnectionPool(); + + /** + * Desctructor. + * All connections will be close. + * All connections will be released + */ ~ConnectionPool(); + + /** + * Constructor that allows specifiying the connetion factory. + * This is useful for testing. + */ explicit ConnectionPool(std::shared_ptr<ConnectionFactory> cf); + + /** + * Get a connection to the server name. Start time is ignored. + * This can be a blocking operation for a short time. + */ std::shared_ptr<HBaseService> get(const hbase::pb::ServerName &sn); + + /** + * Close/remove a connection. + */ void close(const hbase::pb::ServerName &sn); private: http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/pipeline.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/pipeline.h b/hbase-native-client/connection/pipeline.h index e90cb93..88d7845 100644 --- a/hbase-native-client/connection/pipeline.h +++ b/hbase-native-client/connection/pipeline.h @@ -26,12 +26,30 @@ #include "utils/user-util.h" namespace hbase { + +/** Pipeline to turn IOBuf into requests */ using SerializePipeline = wangle::Pipeline<folly::IOBufQueue &, std::unique_ptr<Request>>; +/** + * Factory to create new pipelines for HBase RPC's. + */ class RpcPipelineFactory : public wangle::PipelineFactory<SerializePipeline> { public: + /** + * Constructor. This will create user util. + */ RpcPipelineFactory(); + + /** + * Create a new pipeline. + * The pipeline will be: + * + * - Async Socke Handler + * - Event Base Handler + * - Length Field Based Frame Decoder + * - Client Handler + */ SerializePipeline::Ptr newPipeline(std::shared_ptr<folly::AsyncTransportWrapper> sock) override; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/request.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/request.h b/hbase-native-client/connection/request.h index 743c469..634d1ba 100644 --- a/hbase-native-client/connection/request.h +++ b/hbase-native-client/connection/request.h @@ -25,30 +25,42 @@ #include <string> namespace hbase { + +/** + * Main request class. + * This holds the request object and the un-filled in approriatley typed + * response object. + */ class Request { public: + /** Create a request object for a get */ static std::unique_ptr<Request> get(); + /** Create a request object for a mutate */ static std::unique_ptr<Request> mutate(); + /** Create a request object for a scan */ static std::unique_ptr<Request> scan(); + /** + * This should be private. Do not use this. + * + * + * Constructor that's public for make_unique. This sets all the messages and + * method name. + */ Request(std::shared_ptr<google::protobuf::Message> req, std::shared_ptr<google::protobuf::Message> resp, std::string method); + /** Get the call id. */ uint32_t call_id() { return call_id_; } + /** Set the call id. This should only be set once. */ void set_call_id(uint32_t call_id) { call_id_ = call_id; } - + /** Get the backing request protobuf message. */ std::shared_ptr<google::protobuf::Message> req_msg() { return req_msg_; } + /** Get the backing response protobuf message. */ std::shared_ptr<google::protobuf::Message> resp_msg() { return resp_msg_; } - - void set_req_msg(std::shared_ptr<google::protobuf::Message> msg) { - req_msg_ = msg; - } - void set_resp_msg(std::shared_ptr<google::protobuf::Message> msg) { - resp_msg_ = msg; - } - + /** Get the method name. This is used to the the receiving rpc server what + * method type to decode. */ std::string method() { return method_; } - void set_method(std::string method) { method_ = method; } private: uint32_t call_id_; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/connection/response.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/connection/response.h b/hbase-native-client/connection/response.h index d2eb19a..aac57c2 100644 --- a/hbase-native-client/connection/response.h +++ b/hbase-native-client/connection/response.h @@ -29,20 +29,41 @@ class Message; namespace hbase { +/** + * @brief Class representing a rpc response + * + * This is the class sent to a service. + */ class Response { public: - Response() : call_id_(0), response_(nullptr) {} + /** + * Constructor. + * Initinalizes the call id to 0. 0 should never be a valid call id. + */ + Response() : call_id_(0), resp_msg_(nullptr) {} + + /** Get the call_id */ uint32_t call_id() { return call_id_; } + + /** Set the call_id */ void set_call_id(uint32_t call_id) { call_id_ = call_id; } - std::shared_ptr<google::protobuf::Message> response() const { - return response_; + + /** + * Get the response message. + * The caller is reponsible for knowing the type. In practice the call id is + * used to figure out the type. + */ + std::shared_ptr<google::protobuf::Message> resp_msg() const { + return resp_msg_; } - void set_response(std::shared_ptr<google::protobuf::Message> response) { - response_ = std::move(response); + + /** Set the response message. */ + void set_resp_msg(std::shared_ptr<google::protobuf::Message> response) { + resp_msg_ = std::move(response); } private: uint32_t call_id_; - std::shared_ptr<google::protobuf::Message> response_; + std::shared_ptr<google::protobuf::Message> resp_msg_; }; } // namespace hbase http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/BUCK ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/BUCK b/hbase-native-client/core/BUCK index ef8c2f8..485f9ba 100644 --- a/hbase-native-client/core/BUCK +++ b/hbase-native-client/core/BUCK @@ -20,7 +20,6 @@ cxx_library( name="core", exported_headers=[ "client.h", - "connection.h", "hbase_macros.h", "region-location.h", "location-cache.h", http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/client.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/client.h b/hbase-native-client/core/client.h index 4bed751..4a6d23b 100644 --- a/hbase-native-client/core/client.h +++ b/hbase-native-client/core/client.h @@ -28,8 +28,20 @@ #include "if/Cell.pb.h" namespace hbase { + +/** + * Client. + * + * This is the class that provides access to an HBase cluster. + * It is thread safe and does connection pooling. Current recommendations are to have only one Client per cluster around. + */ class Client { public: + + /** + * Create a new client. + * @param quorum_spec Where to connect to get Zookeeper bootstrap information. + */ explicit Client(std::string quorum_spec); private: http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/connection.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/connection.cc b/hbase-native-client/core/connection.cc deleted file mode 100644 index e9a28eb..0000000 --- a/hbase-native-client/core/connection.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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/connection.h" - -void Connection::set_zk_quorum(char *zk_q) { this->zk_quorum = zk_q; } http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/connection.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/connection.h b/hbase-native-client/core/connection.h deleted file mode 100644 index 5c9d6b8..0000000 --- a/hbase-native-client/core/connection.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -class Connection { - char *zk_quorum; - -public: - void set_zk_quorum(char *zk_q); -}; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/location-cache.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/location-cache.cc b/hbase-native-client/core/location-cache.cc index e2a6251..583d305 100644 --- a/hbase-native-client/core/location-cache.cc +++ b/hbase-native-client/core/location-cache.cc @@ -128,15 +128,24 @@ LocationCache::LocateFromMeta(const TableName &tn, const string &row) { }); } +/** + * Filter to remove a service from the location cache and the connection cache on errors + * or on cloase. + */ class RemoveServiceFilter : public ServiceFilter<std::unique_ptr<Request>, Response> { public: + + /** Create a new filter. */ RemoveServiceFilter(std::shared_ptr<HBaseService> service, ServerName sn, ConnectionPool &cp) : ServiceFilter<unique_ptr<Request>, Response>(service), sn_(sn), cp_(cp) {} + /** + * Close will remove the connection from all caches. + */ folly::Future<folly::Unit> close() override { if (!released.exchange(true)) { return this->service_->close().then([this]() { @@ -148,10 +157,13 @@ public: } } + + /** Has this been closed */ virtual bool isAvailable() override { return !released && service_->isAvailable(); } + /** Send the message. */ folly::Future<Response> operator()(unique_ptr<Request> req) override { // TODO(eclark): add in an on error handler that will // remove the region location from the cache if needed. @@ -168,7 +180,7 @@ private: std::shared_ptr<RegionLocation> LocationCache::CreateLocation(const Response &resp) { - auto resp_msg = static_pointer_cast<ScanResponse>(resp.response()); + auto resp_msg = static_pointer_cast<ScanResponse>(resp.resp_msg()); auto &results = resp_msg->results().Get(0); auto &cells = results.cell(); auto ri = folly::to<RegionInfo>(cells.Get(0).value()); http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/location-cache.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/location-cache.h b/hbase-native-client/core/location-cache.h index 7f76428..88bec18 100644 --- a/hbase-native-client/core/location-cache.h +++ b/hbase-native-client/core/location-cache.h @@ -33,25 +33,48 @@ #include "serde/table-name.h" namespace hbase { - +// Forward class Request; class Response; namespace pb { class ServerName; } +/** + * Class that can look up and cache locations. + */ class LocationCache { public: - explicit LocationCache(std::string quorum_spec, - std::shared_ptr<folly::Executor> executor); + /** + * Constructor. + * @param quorum_spec Where to connect for Zookeeper. + * @param executor The cpu executor to run on. + */ + LocationCache(std::string quorum_spec, + std::shared_ptr<folly::Executor> executor); + /** + * Destructor. + * This will clean up the zookeeper connections. + */ ~LocationCache(); - // Meta Related Methods. - // These are only public until testing is complete + + /** + * Where is meta hosted. + * + * TODO: This should be a RegionLocation. + */ folly::Future<hbase::pb::ServerName> LocateMeta(); + + /** + * Go read meta and find out where a region is located. + */ folly::Future<std::shared_ptr<RegionLocation>> LocateFromMeta(const hbase::pb::TableName &tn, const std::string &row); + + /** + * Remove the cached location of meta. + */ void InvalidateMeta(); - ConnectionPool cp_; private: void RefreshMetaLocation(); @@ -63,6 +86,7 @@ private: std::unique_ptr<folly::SharedPromise<hbase::pb::ServerName>> meta_promise_; std::mutex meta_lock_; MetaUtil meta_util_; + ConnectionPool cp_; // TODO: migrate this to a smart pointer with a deleter. zhandle_t *zk_; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/meta-utils.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/meta-utils.h b/hbase-native-client/core/meta-utils.h index dfef065..f6cc84f 100644 --- a/hbase-native-client/core/meta-utils.h +++ b/hbase-native-client/core/meta-utils.h @@ -26,10 +26,22 @@ namespace hbase { +/** + * @brief Utility for meta operations. + */ class MetaUtil { public: + /** + * Given a table and a row give the row key from which to start a scan to find + * region locations. + */ std::string RegionLookupRowkey(const hbase::pb::TableName &tn, const std::string &row) const; + + /** + * Given a row we're trying to access create a request to look up the + * location. + */ std::unique_ptr<Request> MetaRequest(const hbase::pb::TableName tn, const std::string &row) const; }; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/put.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/put.cc b/hbase-native-client/core/put.cc deleted file mode 100644 index 806a478..0000000 --- a/hbase-native-client/core/put.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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/put.h" - -Put::~Put() {} http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/put.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/put.h b/hbase-native-client/core/put.h deleted file mode 100644 index d34aa0d..0000000 --- a/hbase-native-client/core/put.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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/mutation.h" - -class Put : public Mutation { -public: - ~Put(); -}; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/core/region-location.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/core/region-location.h b/hbase-native-client/core/region-location.h index 7887526..a3d832e 100644 --- a/hbase-native-client/core/region-location.h +++ b/hbase-native-client/core/region-location.h @@ -25,19 +25,60 @@ namespace hbase { +/** + * @brief class to hold where a region is located. + * + * This class holds where a region is located, the information about it, the + * region name, and a connection to the service used for connecting to it. + */ class RegionLocation { public: + /** + * Constructor. + * @param region_name The region name of this region. + * @param ri The decoded RegionInfo of this region. + * @param sn The server name of the HBase regionserver thought to be hosting + * this region. + * @param service the connected service to the regionserver. + */ RegionLocation(std::string region_name, hbase::pb::RegionInfo ri, hbase::pb::ServerName sn, std::shared_ptr<HBaseService> service) : region_name_(region_name), ri_(ri), sn_(sn), service_(service) {} + /** + * Get a reference to the regio info + */ const hbase::pb::RegionInfo ®ion_info() { return ri_; } + + /** + * Get a reference to the server name + */ const hbase::pb::ServerName &server_name() { return sn_; } + + /** + * Get a reference to the region name. + */ const std::string ®ion_name() { return region_name_; } + + /** + * Get a service. This could be closed or null. It's the caller's + * responsibility to check. + */ std::shared_ptr<HBaseService> service() { return service_; } + + /** + * Set the service. + * This should be used if the region moved or if the connection is thought to + * be bad and a new tcp connection needs to be made. + */ void set_service(std::shared_ptr<HBaseService> s) { service_ = s; } + /** + * Set the servername if the region has moved. + */ + void set_server_name(hbase::pb::ServerName sn) { sn_ = sn; } + private: std::string region_name_; hbase::pb::RegionInfo ri_; http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/serde/rpc.cc ---------------------------------------------------------------------- diff --git a/hbase-native-client/serde/rpc.cc b/hbase-native-client/serde/rpc.cc index 4c3c999..b573738 100644 --- a/hbase-native-client/serde/rpc.cc +++ b/hbase-native-client/serde/rpc.cc @@ -85,7 +85,6 @@ int RpcSerde::ParseDelimited(const IOBuf *buf, Message *msg) { } RpcSerde::RpcSerde() : auth_type_(DEFAULT_AUTH_TYPE) {} -RpcSerde::~RpcSerde() {} unique_ptr<IOBuf> RpcSerde::Preamble() { auto magic = IOBuf::copyBuffer(PREAMBLE, 0, 2); http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/serde/rpc.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/serde/rpc.h b/hbase-native-client/serde/rpc.h index cefb583..b28b4a3 100644 --- a/hbase-native-client/serde/rpc.h +++ b/hbase-native-client/serde/rpc.h @@ -32,22 +32,81 @@ class Message; } namespace hbase { + +/** + * @brief Class for serializing a deserializing rpc formatted data. + * + * RpcSerde is the one stop shop for reading/writing data to HBase daemons. + * It should throw exceptions if anything goes wrong. + */ class RpcSerde { public: + /** + * Constructor assumes the default auth type. + */ RpcSerde(); - virtual ~RpcSerde(); + + /** + * Destructor. This is provided just for testing purposes. + */ + virtual ~RpcSerde() = default; + + /** + * Pase a message in the delimited format. + * + * A message in delimited format consists of the following: + * + * - a protobuf var int32. + * - A protobuf object serialized. + */ int ParseDelimited(const folly::IOBuf *buf, google::protobuf::Message *msg); + + /** + * Create a new connection preamble in a new IOBuf. + */ std::unique_ptr<folly::IOBuf> Preamble(); + + /** + * Create the header protobuf object and serialize it to a new IOBuf. + * Header is in the following format: + * + * - Big endian length + * - ConnectionHeader object serialized out. + */ std::unique_ptr<folly::IOBuf> Header(const std::string &user); + + /** + * Serialize a request message into a protobuf. + * Request consists of: + * + * - Big endian length + * - RequestHeader object + * - The passed in Message object + */ std::unique_ptr<folly::IOBuf> Request(const uint32_t call_id, const std::string &method, const google::protobuf::Message *msg); + + /** + * Serialize a message in the delimited format. + * Delimited format consists of the following: + * + * - A protobuf var int32 + * - The message object seriailized after that. + */ std::unique_ptr<folly::IOBuf> SerializeDelimited(const google::protobuf::Message &msg); + /** + * Serilalize a message. This does not add any length prepend. + */ std::unique_ptr<folly::IOBuf> SerializeMessage(const google::protobuf::Message &msg); + /** + * Prepend a length IOBuf to the given IOBuf chain. + * This involves no copies or moves of the passed in data. + */ std::unique_ptr<folly::IOBuf> PrependLength(std::unique_ptr<folly::IOBuf> msg); http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/serde/zk.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/serde/zk.h b/hbase-native-client/serde/zk.h index b672bf4..fa3de5b 100644 --- a/hbase-native-client/serde/zk.h +++ b/hbase-native-client/serde/zk.h @@ -28,8 +28,22 @@ class IOBuf; } namespace hbase { + +/** @brief A class to convert data from ZooKeeper to other formats. + * + * This class will convert data to and from Zookeeper into protobuf objects. + * + */ class ZkDeserializer { public: + /** + * Merge the data from a buffer into a given message. + * + * @param buf Naked pointer to iobuf containing data read from zookeeper. + * @param out Naked pointer into which the data will be merged. The message + * should be the correct type. + * @return returns true if the parsing was successful. + */ bool Parse(folly::IOBuf *buf, google::protobuf::Message *out); }; } // namespace hbase http://git-wip-us.apache.org/repos/asf/hbase/blob/fdf00239/hbase-native-client/utils/user-util.h ---------------------------------------------------------------------- diff --git a/hbase-native-client/utils/user-util.h b/hbase-native-client/utils/user-util.h index da95d78..0b4cc73 100644 --- a/hbase-native-client/utils/user-util.h +++ b/hbase-native-client/utils/user-util.h @@ -24,12 +24,30 @@ #include <mutex> namespace hbase { + +/** + * @brief Class to help with user/group information. + * + * This class will get the current user, and information about them. It caches + * the user information after the first invocation. + */ class UserUtil { public: + /** + * Constructor. + */ UserUtil(); + + /** + * Get the username of the user owning this process. This is thread safe and + * lockless for every invocation other than the first one. + */ std::string user_name(); private: + /** + * Compute the username. This will block. + */ void compute_user_name(); std::atomic<bool> init_; std::string user_name_;