You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2017/09/15 21:20:28 UTC
[11/25] hbase git commit: HBASE-18725 [C++] Install header files as
well as library
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/response.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/response.h b/hbase-native-client/include/hbase/connection/response.h
new file mode 100644
index 0000000..5fe8b79
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/response.h
@@ -0,0 +1,93 @@
+/*
+ * 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 <folly/Conv.h>
+#include <folly/ExceptionWrapper.h>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "hbase/serde/cell-scanner.h"
+
+// Forward
+namespace google {
+namespace protobuf {
+class Message;
+}
+}
+
+namespace hbase {
+
+/**
+ * @brief Class representing a rpc response
+ *
+ * This is the class sent to a service.
+ */
+class Response {
+ public:
+ /**
+ * Constructor.
+ * Initinalizes the call id to 0. 0 should never be a valid call id.
+ */
+ Response() : call_id_(0), resp_msg_(nullptr), cell_scanner_(nullptr), exception_(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; }
+
+ /**
+ * 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_; }
+
+ /** Set the response message. */
+ void set_resp_msg(std::shared_ptr<google::protobuf::Message> response) {
+ resp_msg_ = std::move(response);
+ }
+
+ void set_cell_scanner(std::shared_ptr<CellScanner> cell_scanner) { cell_scanner_ = cell_scanner; }
+
+ const std::shared_ptr<CellScanner> cell_scanner() const { return cell_scanner_; }
+
+ folly::exception_wrapper exception() { return exception_; }
+
+ void set_exception(folly::exception_wrapper value) { exception_ = value; }
+
+ std::string DebugString() const {
+ std::string s{"call_id:"};
+ s += folly::to<std::string>(call_id_);
+ s += ", resp_msg:";
+ s += resp_msg_->ShortDebugString();
+ return s;
+ }
+
+ private:
+ uint32_t call_id_;
+ std::shared_ptr<google::protobuf::Message> resp_msg_;
+ std::shared_ptr<CellScanner> cell_scanner_;
+ folly::exception_wrapper exception_;
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-client.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-client.h b/hbase-native-client/include/hbase/connection/rpc-client.h
new file mode 100644
index 0000000..1189410
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-client.h
@@ -0,0 +1,83 @@
+/*
+ * 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 <google/protobuf/service.h>
+
+#include <folly/ExceptionWrapper.h>
+#include <chrono>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "hbase/connection/connection-id.h"
+#include "hbase/connection/connection-pool.h"
+#include "hbase/connection/request.h"
+#include "hbase/connection/response.h"
+#include "hbase/security/user.h"
+
+namespace hbase {
+
+class RpcClient {
+ public:
+ RpcClient(std::shared_ptr<wangle::IOThreadPoolExecutor> io_executor,
+ std::shared_ptr<wangle::CPUThreadPoolExecutor> cpu_executor,
+ std::shared_ptr<Codec> codec, std::shared_ptr<Configuration> conf,
+ std::chrono::nanoseconds connect_timeout = std::chrono::nanoseconds(0));
+
+ virtual ~RpcClient() { Close(); }
+
+ virtual std::unique_ptr<Response> SyncCall(const std::string &host, uint16_t port,
+ std::unique_ptr<Request> req,
+ std::shared_ptr<security::User> ticket);
+
+ virtual std::unique_ptr<Response> SyncCall(const std::string &host, uint16_t port,
+ std::unique_ptr<Request> req,
+ std::shared_ptr<security::User> ticket,
+ const std::string &service_name);
+
+ virtual folly::Future<std::unique_ptr<Response>> AsyncCall(
+ const std::string &host, uint16_t port, std::unique_ptr<Request> req,
+ std::shared_ptr<security::User> ticket);
+
+ virtual folly::Future<std::unique_ptr<Response>> AsyncCall(const std::string &host, uint16_t port,
+ std::unique_ptr<Request> req,
+ std::shared_ptr<security::User> ticket,
+ const std::string &service_name);
+
+ virtual void Close();
+
+ std::shared_ptr<ConnectionPool> connection_pool() const { return cp_; }
+
+ private:
+ std::shared_ptr<RpcConnection> GetConnection(std::shared_ptr<ConnectionId> remote_id);
+ folly::Future<std::unique_ptr<Response>> SendRequest(std::shared_ptr<ConnectionId> remote_id,
+ std::unique_ptr<Request> req);
+ template <typename EXCEPTION>
+ folly::Future<std::unique_ptr<Response>> GetFutureWithException(const EXCEPTION &e);
+
+ folly::Future<std::unique_ptr<Response>> GetFutureWithException(
+ const folly::exception_wrapper &ew);
+
+ private:
+ std::shared_ptr<ConnectionPool> cp_;
+ std::shared_ptr<wangle::IOThreadPoolExecutor> io_executor_;
+ std::shared_ptr<Configuration> conf_;
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-connection.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-connection.h b/hbase-native-client/include/hbase/connection/rpc-connection.h
new file mode 100644
index 0000000..cbbac63
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-connection.h
@@ -0,0 +1,79 @@
+/*
+ * 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 <memory>
+#include <mutex>
+#include <utility>
+
+#include "hbase/connection/connection-factory.h"
+#include "hbase/connection/connection-id.h"
+#include "hbase/connection/request.h"
+#include "hbase/connection/response.h"
+#include "hbase/connection/service.h"
+
+namespace hbase {
+
+class RpcConnection : public std::enable_shared_from_this<RpcConnection> {
+ public:
+ RpcConnection(std::shared_ptr<ConnectionId> connection_id, std::shared_ptr<ConnectionFactory> cf)
+ : connection_id_(connection_id), cf_(cf), hbase_service_(nullptr) {}
+
+ virtual ~RpcConnection() { Close(); }
+
+ virtual std::shared_ptr<ConnectionId> remote_id() const { return connection_id_; }
+
+ virtual folly::Future<std::unique_ptr<Response>> SendRequest(std::unique_ptr<Request> req) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (hbase_service_ == nullptr) {
+ Connect();
+ }
+ VLOG(5) << "Calling RpcConnection::SendRequest()"; // TODO
+ return (*hbase_service_)(std::move(req));
+ }
+
+ virtual void Close() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (hbase_service_) {
+ hbase_service_->close();
+ hbase_service_ = nullptr;
+ }
+ if (client_bootstrap_) {
+ client_bootstrap_ = nullptr;
+ }
+ }
+
+ private:
+ void Connect() {
+ client_bootstrap_ = cf_->MakeBootstrap();
+ auto dispatcher = cf_->Connect(shared_from_this(), client_bootstrap_, remote_id()->host(),
+ remote_id()->port());
+ hbase_service_ = std::move(dispatcher);
+ }
+
+ private:
+ std::recursive_mutex mutex_;
+ std::shared_ptr<wangle::IOThreadPoolExecutor> io_executor_;
+ std::shared_ptr<wangle::CPUThreadPoolExecutor> cpu_executor_;
+ std::shared_ptr<ConnectionId> connection_id_;
+ std::shared_ptr<HBaseService> hbase_service_;
+ std::shared_ptr<ConnectionFactory> cf_;
+ std::shared_ptr<wangle::ClientBootstrap<SerializePipeline>> client_bootstrap_;
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-fault-injector-inl.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-fault-injector-inl.h b/hbase-native-client/include/hbase/connection/rpc-fault-injector-inl.h
new file mode 100644
index 0000000..8bbaddf
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-fault-injector-inl.h
@@ -0,0 +1,41 @@
+/*
+ * 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
+
+namespace hbase {
+
+template <typename T>
+std::shared_ptr<T> RpcFaultInjector<T>::instance = std::make_shared<T>();
+
+template <typename T>
+RpcFaultInjector<T>::RpcFaultInjector() {}
+
+template <typename T>
+RpcFaultInjector<T>::~RpcFaultInjector() {}
+
+template <typename T>
+std::shared_ptr<T> RpcFaultInjector<T>::Get() {
+ return instance;
+}
+
+template <typename T>
+void RpcFaultInjector<T>::Set(std::shared_ptr<T> injector) {
+ instance = injector;
+}
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-fault-injector.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-fault-injector.h b/hbase-native-client/include/hbase/connection/rpc-fault-injector.h
new file mode 100644
index 0000000..1d21875
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-fault-injector.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <folly/io/async/AsyncTransport.h>
+#include "hbase/connection/pipeline.h"
+
+namespace hbase {
+
+template <typename T>
+class RpcFaultInjector {
+ public:
+ RpcFaultInjector();
+ virtual ~RpcFaultInjector();
+
+ static std::shared_ptr<T> Get();
+ static void Set(std::shared_ptr<T> instance);
+
+ private:
+ static std::shared_ptr<T> instance;
+};
+
+class RpcClientFaultInjector : public RpcFaultInjector<RpcClientFaultInjector> {
+ public:
+ RpcClientFaultInjector() {}
+ virtual ~RpcClientFaultInjector() {}
+ /**
+ * Here goes virtual functions for injecting various faults. They should be no-ops by default.
+ * Sub classes of RpcClientFaultInjector will override by providing concrete faults.
+ */
+};
+} /* namespace hbase */
+
+#include "hbase/connection/rpc-fault-injector-inl.h"
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-test-server-handler.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-test-server-handler.h b/hbase-native-client/include/hbase/connection/rpc-test-server-handler.h
new file mode 100644
index 0000000..ef6ed4e
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-test-server-handler.h
@@ -0,0 +1,47 @@
+/*
+ * 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 <wangle/channel/Handler.h>
+
+#include "hbase/connection/request.h"
+#include "hbase/connection/response.h"
+#include "hbase/serde/rpc-serde.h"
+
+using namespace hbase;
+
+namespace hbase {
+// A real rpc server would probably use generated client/server stubs
+class RpcTestServerSerializeHandler
+ : public wangle::Handler<std::unique_ptr<folly::IOBuf>, std::unique_ptr<Request>,
+ std::unique_ptr<Response>, std::unique_ptr<folly::IOBuf>> {
+ public:
+ RpcTestServerSerializeHandler() : serde_() {}
+
+ void read(Context* ctx, std::unique_ptr<folly::IOBuf> buf) override;
+
+ folly::Future<folly::Unit> write(Context* ctx, std::unique_ptr<Response> resp) override;
+
+ private:
+ std::unique_ptr<Request> CreateReceivedRequest(const std::string& method_name);
+
+ private:
+ hbase::RpcSerde serde_;
+};
+} // end of namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/rpc-test-server.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/rpc-test-server.h b/hbase-native-client/include/hbase/connection/rpc-test-server.h
new file mode 100644
index 0000000..76ab8ba
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/rpc-test-server.h
@@ -0,0 +1,68 @@
+/*
+ * 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 <folly/SocketAddress.h>
+#include <wangle/concurrent/CPUThreadPoolExecutor.h>
+#include <wangle/service/ExecutorFilter.h>
+#include <wangle/service/Service.h>
+
+#include "hbase/connection/request.h"
+#include "hbase/connection/response.h"
+#include "hbase/exceptions/exception.h"
+
+using namespace hbase;
+using namespace folly;
+using namespace wangle;
+
+namespace hbase {
+using RpcTestServerSerializePipeline = wangle::Pipeline<IOBufQueue&, std::unique_ptr<Response>>;
+
+class RpcTestException : public IOException {
+ public:
+ RpcTestException() {}
+ RpcTestException(const std::string& what) : IOException(what) {}
+ RpcTestException(const std::string& what, const folly::exception_wrapper& cause)
+ : IOException(what, cause) {}
+ RpcTestException(const folly::exception_wrapper& cause) : IOException("", cause) {}
+};
+
+class RpcTestService : public Service<std::unique_ptr<Request>, std::unique_ptr<Response>> {
+ public:
+ RpcTestService(std::shared_ptr<folly::SocketAddress> socket_address)
+ : socket_address_(socket_address) {}
+ virtual ~RpcTestService() = default;
+ Future<std::unique_ptr<Response>> operator()(std::unique_ptr<Request> request) override;
+
+ private:
+ std::shared_ptr<folly::SocketAddress> socket_address_;
+};
+
+class RpcTestServerPipelineFactory : public PipelineFactory<RpcTestServerSerializePipeline> {
+ public:
+ RpcTestServerSerializePipeline::Ptr newPipeline(
+ std::shared_ptr<AsyncTransportWrapper> sock) override;
+
+ private:
+ void initService(std::shared_ptr<AsyncTransportWrapper> sock);
+
+ private:
+ std::shared_ptr<ExecutorFilter<std::unique_ptr<Request>, std::unique_ptr<Response>>> service_{
+ nullptr};
+};
+} // end of namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/sasl-handler.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/sasl-handler.h b/hbase-native-client/include/hbase/connection/sasl-handler.h
new file mode 100644
index 0000000..bb7f294
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/sasl-handler.h
@@ -0,0 +1,78 @@
+/*
+ * 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 <glog/logging.h>
+#include <sasl/sasl.h>
+#include <sasl/saslplug.h>
+#include <sasl/saslutil.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "hbase/connection/sasl-util.h"
+#include "hbase/connection/service.h"
+#include "hbase/security/user.h"
+#include "hbase/serde/rpc-serde.h"
+
+namespace hbase {
+
+/**
+ * Class to perform SASL handshake with server (currently works with regionserver principals only)
+ * It is inserted between EventBaseHandler and LengthFieldBasedFrameDecoder in the pipeline
+ * SaslHandler would intercept writes to server by buffering the IOBuf's and start the handshake
+ * process
+ * (via sasl_client_XX calls provided by Cyrus)
+ * After handshake is complete, SaslHandler would send the buffered IOBuf's to server and
+ * act as pass-thru from then on
+ */
+class SaslHandler
+ : public wangle::HandlerAdapter<folly::IOBufQueue&, std::unique_ptr<folly::IOBuf>> {
+ public:
+ explicit SaslHandler(std::string user_name, std::shared_ptr<Configuration> conf);
+ SaslHandler(const SaslHandler& hdlr);
+ ~SaslHandler();
+
+ // from HandlerAdapter
+ void read(Context* ctx, folly::IOBufQueue& buf) override;
+ folly::Future<folly::Unit> write(Context* ctx, std::unique_ptr<folly::IOBuf> buf) override;
+ void transportActive(Context* ctx) override;
+
+ private:
+ // used by Cyrus
+ sasl_conn_t* sconn_ = nullptr;
+ std::string user_name_;
+ std::string service_name_;
+ std::string host_name_;
+ bool secure_;
+ std::atomic_flag sasl_connection_setup_started_;
+ std::atomic<bool> sasl_connection_setup_in_progress_{true};
+ // vector of folly::IOBuf which buffers client writes before handshake is complete
+ std::vector<std::unique_ptr<folly::IOBuf>> iobuf_;
+ SaslUtil sasl_util_;
+
+ // writes the output returned by sasl_client_XX to server
+ folly::Future<folly::Unit> WriteSaslOutput(Context* ctx, const char* out, unsigned int outlen);
+ folly::Future<folly::Unit> SaslInit(Context* ctx);
+ void FinishAuth(Context* ctx, folly::IOBufQueue* bufQueue);
+ void ContinueSaslNegotiation(Context* ctx, folly::IOBufQueue* buf);
+ std::string ParseServiceName(std::shared_ptr<Configuration> conf, bool secure);
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/sasl-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/sasl-util.h b/hbase-native-client/include/hbase/connection/sasl-util.h
new file mode 100644
index 0000000..4d236df
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/sasl-util.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 <memory>
+#include <mutex>
+#include <string>
+
+#include "hbase/client/configuration.h"
+
+class SaslUtil {
+ public:
+ void InitializeSaslLib(void);
+ static std::string ParseServiceName(std::shared_ptr<hbase::Configuration> conf, bool secure);
+
+ private:
+ static constexpr const char *kDefaultPluginDir = "/usr/lib/sasl2";
+ // for now the sasl handler is hardcoded to work against the regionservers only. In the future, if
+ // we
+ // need the master rpc to work, we could have a map of service names to principals to use (similar
+ // to the Java implementation)
+ static constexpr const char *kServerPrincipalConfKey = "hbase.regionserver.kerberos.principal";
+
+ static int GetPluginPath(void *context, const char **path);
+ static void *MutexNew(void);
+ static int MutexLock(void *m);
+ static int MutexUnlock(void *m);
+ static void MutexDispose(void *m);
+ static std::once_flag library_inited_;
+};
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/connection/service.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/connection/service.h b/hbase-native-client/include/hbase/connection/service.h
new file mode 100644
index 0000000..a70fd6b
--- /dev/null
+++ b/hbase-native-client/include/hbase/connection/service.h
@@ -0,0 +1,30 @@
+/*
+ * 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 <wangle/service/Service.h>
+
+#include <memory>
+
+#include "hbase/connection/request.h"
+#include "hbase/connection/response.h"
+
+namespace hbase {
+using HBaseService = wangle::Service<std::unique_ptr<Request>, std::unique_ptr<Response>>;
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/exceptions/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/exceptions/BUCK b/hbase-native-client/include/hbase/exceptions/BUCK
new file mode 100644
index 0000000..ee296ff
--- /dev/null
+++ b/hbase-native-client/include/hbase/exceptions/BUCK
@@ -0,0 +1,28 @@
+##
+# 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.
+
+cxx_library(
+ name="exceptions",
+ header_namespace="hbase/exceptions",
+ exported_headers=[
+ "exception.h",
+ ],
+ deps=[
+ "//third-party:folly",
+ ],
+ compiler_flags=['-Weffc++'],
+ visibility=['//src/hbase/exceptions/...', '//include/hbase/client/...', '//include/hbase/connection/...'],)
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/exceptions/exception.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/exceptions/exception.h b/hbase-native-client/include/hbase/exceptions/exception.h
new file mode 100644
index 0000000..bc3b291
--- /dev/null
+++ b/hbase-native-client/include/hbase/exceptions/exception.h
@@ -0,0 +1,328 @@
+/*
+ * 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 <folly/ExceptionWrapper.h>
+#include <folly/io/IOBuf.h>
+#include <exception>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace hbase {
+
+class ThrowableWithExtraContext {
+ public:
+ ThrowableWithExtraContext(folly::exception_wrapper cause, const int64_t& when)
+ : cause_(cause), when_(when), extras_("") {}
+
+ ThrowableWithExtraContext(folly::exception_wrapper cause, const int64_t& when,
+ const std::string& extras)
+ : cause_(cause), when_(when), extras_(extras) {}
+
+ virtual std::string ToString() {
+ // TODO:
+ // return new Date(this.when).toString() + ", " + extras + ", " + t.toString();
+ return extras_ + ", " + cause_.what().toStdString();
+ }
+
+ virtual folly::exception_wrapper cause() { return cause_; }
+
+ private:
+ folly::exception_wrapper cause_;
+ int64_t when_;
+ std::string extras_;
+};
+
+class IOException : public std::logic_error {
+ public:
+ IOException() : logic_error(""), do_not_retry_(false) {}
+
+ explicit IOException(const std::string& what) : logic_error(what), do_not_retry_(false) {}
+
+ IOException(const std::string& what, bool do_not_retry)
+ : logic_error(what), do_not_retry_(do_not_retry) {}
+
+ IOException(const std::string& what, const folly::exception_wrapper& cause)
+ : logic_error(what), cause_(cause), do_not_retry_(false) {}
+
+ IOException(const std::string& what, folly::exception_wrapper cause, bool do_not_retry)
+ : logic_error(what), cause_(cause), do_not_retry_(do_not_retry) {}
+
+ virtual ~IOException() = default;
+
+ virtual folly::exception_wrapper cause() const { return cause_; }
+
+ bool do_not_retry() const { return do_not_retry_; }
+
+ IOException* set_do_not_retry(bool value) {
+ do_not_retry_ = value;
+ return this;
+ }
+
+ private:
+ folly::exception_wrapper cause_;
+ // In case the exception is a RemoteException, do_not_retry information can come from
+ // the PB field in the RPC response, or it can be deduced from the Java-exception
+ // hierarchy in ExceptionUtil::ShouldRetry(). In case this is a client-side exception
+ // raised from the C++ internals, set this field so that the retrying callers can
+ // re-throw the exception without retrying.
+ bool do_not_retry_;
+};
+
+class RetriesExhaustedException : public IOException {
+ public:
+ RetriesExhaustedException(const int& num_retries,
+ std::shared_ptr<std::vector<ThrowableWithExtraContext>> exceptions)
+ : IOException(GetMessage(num_retries, exceptions),
+ exceptions->empty() ? folly::exception_wrapper{}
+ : (*exceptions)[exceptions->size() - 1].cause()),
+ num_retries_(num_retries) {}
+ virtual ~RetriesExhaustedException() = default;
+
+ int32_t num_retries() const { return num_retries_; }
+
+ private:
+ std::string GetMessage(const int& num_retries,
+ std::shared_ptr<std::vector<ThrowableWithExtraContext>> exceptions) {
+ std::string buffer("Failed after attempts=");
+ buffer.append(std::to_string(num_retries + 1));
+ buffer.append(", exceptions:\n");
+ for (auto it = exceptions->begin(); it != exceptions->end(); it++) {
+ buffer.append(it->ToString());
+ buffer.append("\n");
+ }
+ return buffer;
+ }
+
+ private:
+ int32_t num_retries_;
+};
+
+class ConnectionException : public IOException {
+ public:
+ ConnectionException() {}
+
+ ConnectionException(const std::string& what) : IOException(what) {}
+
+ ConnectionException(const folly::exception_wrapper& cause) : IOException("", cause) {}
+
+ ConnectionException(const std::string& what, const folly::exception_wrapper& cause)
+ : IOException(what, cause) {}
+};
+
+class RemoteException : public IOException {
+ public:
+ RemoteException() : IOException(), port_(0) {}
+
+ explicit RemoteException(const std::string& what) : IOException(what), port_(0) {}
+
+ RemoteException(const std::string& what, folly::exception_wrapper cause)
+ : IOException(what, cause), port_(0) {}
+
+ virtual ~RemoteException() = default;
+
+ std::string exception_class_name() const { return exception_class_name_; }
+
+ RemoteException* set_exception_class_name(const std::string& value) {
+ exception_class_name_ = value;
+ return this;
+ }
+
+ std::string stack_trace() const { return stack_trace_; }
+
+ RemoteException* set_stack_trace(const std::string& value) {
+ stack_trace_ = value;
+ return this;
+ }
+
+ std::string hostname() const { return hostname_; }
+
+ RemoteException* set_hostname(const std::string& value) {
+ hostname_ = value;
+ return this;
+ }
+
+ int port() const { return port_; }
+
+ RemoteException* set_port(int value) {
+ port_ = value;
+ return this;
+ }
+
+ private:
+ std::string exception_class_name_;
+ std::string stack_trace_;
+ std::string hostname_;
+ int port_;
+};
+
+/**
+ * Raised from the client side if we cannot find the table (does not have anything to
+ * do with the Java exception of the same name).
+ */
+class TableNotFoundException : public IOException {
+ public:
+ explicit TableNotFoundException(const std::string& table_name)
+ : IOException("Table cannot be found:" + table_name, true) {}
+
+ virtual ~TableNotFoundException() = default;
+};
+
+/**
+ * List of known exceptions from Java side, and Java-specific exception logic
+ */
+class ExceptionUtil {
+ private:
+ // unknown scanner and sub-classes
+ static constexpr const char* kUnknownScannerException =
+ "org.apache.hadoop.hbase.UnknownScannerException";
+
+ // not serving region and sub-classes
+ static constexpr const char* kNotServingRegionException =
+ "org.apache.hadoop.hbase.NotServingRegionException";
+ static constexpr const char* kRegionInRecoveryException =
+ "org.apache.hadoop.hbase.exceptions.RegionInRecoveryException";
+ static constexpr const char* kRegionOpeningException =
+ "org.apache.hadoop.hbase.exceptions.RegionOpeningException";
+ static constexpr const char* kRegionMovedException =
+ "org.apache.hadoop.hbase.exceptions.RegionMovedException";
+
+ // Region server stopped and sub-classes
+ static constexpr const char* kRegionServerStoppedException =
+ "org.apache.hadoop.hbase.regionserver.RegionServerStoppedException";
+ static constexpr const char* kRegionServerAbortedException =
+ "org.apache.hadoop.hbase.regionserver.RegionServerAbortedException";
+
+ // other scanner related exceptions
+ static constexpr const char* kOutOfOrderScannerNextException =
+ "org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException";
+ static constexpr const char* kScannerResetException =
+ "org.apache.hadoop.hbase.exceptions.ScannerResetException";
+
+ // All other DoNotRetryIOExceptions
+ static constexpr const char* kDoNotRetryIOException =
+ "org.apache.hadoop.hbase.DoNotRetryIOException";
+ static constexpr const char* kTableNotFoundException =
+ "org.apache.hadoop.hbase.TableNotFoundException";
+ static constexpr const char* kTableNotEnabledException =
+ "org.apache.hadoop.hbase.TableNotEnabledException";
+ static constexpr const char* kCoprocessorException =
+ "org.apache.hadoop.hbase.coprocessor.CoprocessorException";
+ static constexpr const char* kBypassCoprocessorException =
+ "org.apache.hadoop.hbase.coprocessor.BypassCoprocessorException";
+ static constexpr const char* kInvalidFamilyOperationException =
+ "org.apache.hadoop.hbase.InvalidFamilyOperationException";
+ static constexpr const char* kServerTooBusyException =
+ "org.apache.hadoop.hbase.ipc.ServerTooBusyException"; // This should NOT be DNRIOE?
+ static constexpr const char* kFailedSanityCheckException =
+ "org.apache.hadoop.hbase.exceptions.FailedSanityCheckException";
+ static constexpr const char* kCorruptHFileException =
+ "org.apache.hadoop.hbase.io.hfile.CorruptHFileException";
+ static constexpr const char* kLabelAlreadyExistsException =
+ "org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException";
+ static constexpr const char* kFatalConnectionException =
+ "org.apache.hadoop.hbase.ipc.FatalConnectionException";
+ static constexpr const char* kUnsupportedCryptoException =
+ "org.apache.hadoop.hbase.ipc.UnsupportedCryptoException";
+ static constexpr const char* kUnsupportedCellCodecException =
+ "org.apache.hadoop.hbase.ipc.UnsupportedCellCodecException";
+ static constexpr const char* kEmptyServiceNameException =
+ "org.apache.hadoop.hbase.ipc.EmptyServiceNameException";
+ static constexpr const char* kUnknownServiceException =
+ "org.apache.hadoop.hbase.ipc.UnknownServiceException";
+ static constexpr const char* kWrongVersionException =
+ "org.apache.hadoop.hbase.ipc.WrongVersionException";
+ static constexpr const char* kBadAuthException = "org.apache.hadoop.hbase.ipc.BadAuthException";
+ static constexpr const char* kUnsupportedCompressionCodecException =
+ "org.apache.hadoop.hbase.ipc.UnsupportedCompressionCodecException";
+ static constexpr const char* kDoNotRetryRegionException =
+ "org.apache.hadoop.hbase.client.DoNotRetryRegionException";
+ static constexpr const char* kRowTooBigException =
+ "org.apache.hadoop.hbase.client.RowTooBigException";
+ static constexpr const char* kRowTooBigExceptionDeprecated =
+ "org.apache.hadoop.hbase.regionserver.RowTooBigException";
+ static constexpr const char* kUnknownRegionException =
+ "org.apache.hadoop.hbase.UnknownRegionException";
+ static constexpr const char* kMergeRegionException =
+ "org.apache.hadoop.hbase.exceptions.MergeRegionException";
+ static constexpr const char* kNoServerForRegionException =
+ "org.apache.hadoop.hbase.client.NoServerForRegionException";
+ static constexpr const char* kQuotaExceededException =
+ "org.apache.hadoop.hbase.quotas.QuotaExceededException";
+ static constexpr const char* kSpaceLimitingException =
+ "org.apache.hadoop.hbase.quotas.SpaceLimitingException";
+ static constexpr const char* kThrottlingException =
+ "org.apache.hadoop.hbase.quotas.ThrottlingException";
+ static constexpr const char* kAccessDeniedException =
+ "org.apache.hadoop.hbase.security.AccessDeniedException";
+ static constexpr const char* kUnknownProtocolException =
+ "org.apache.hadoop.hbase.exceptions.UnknownProtocolException";
+ static constexpr const char* kRequestTooBigException =
+ "org.apache.hadoop.hbase.exceptions.RequestTooBigException";
+ static constexpr const char* kNotAllMetaRegionsOnlineException =
+ "org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException";
+ static constexpr const char* kConstraintException =
+ "org.apache.hadoop.hbase.constraint.ConstraintException";
+ static constexpr const char* kNoSuchColumnFamilyException =
+ "org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException";
+ static constexpr const char* kLeaseException =
+ "org.apache.hadoop.hbase.regionserver.LeaseException";
+ static constexpr const char* kInvalidLabelException =
+ "org.apache.hadoop.hbase.security.visibility.InvalidLabelException";
+
+ // TODO:
+ // These exceptions are not thrown in the regular read / write paths, although they are
+ // DoNotRetryIOExceptions. Add these to the list below in case we start doing Admin/DDL ops
+ // ReplicationPeerNotFoundException, XXXSnapshotException, NamespaceExistException,
+ // NamespaceNotFoundException, TableExistsException, TableNotDisabledException,
+ static const std::vector<const char*> kAllDoNotRetryIOExceptions;
+
+ public:
+ /**
+ * Returns whether or not the exception should be retried by looking at the
+ * client-side IOException, or RemoteException coming from server side.
+ */
+ static bool ShouldRetry(const folly::exception_wrapper& error);
+
+ /**
+ * Returns whether the java exception class extends DoNotRetryException.
+ * In the java side, we just have a hierarchy of Exception classes that we use
+ * both client side and server side. On the client side, we rethrow the server
+ * side exception by un-wrapping the exception from a RemoteException or a ServiceException
+ * (see ConnectionUtils.translateException() in Java).
+ * Since this object-hierarchy info is not available in C++ side, we are doing a
+ * very fragile catch-all list of all exception types in Java that extend the
+ * DoNotRetryException class type.
+ */
+ static bool IsJavaDoNotRetryException(const std::string& java_class_name);
+
+ /**
+ * Returns whether the scanner is closed when the client received the
+ * remote exception.
+ * Since the object-hierarchy info is not available in C++ side, we are doing a
+ * very fragile catch-all list of all exception types in Java that extend these
+ * three base classes: UnknownScannerException, NotServingRegionException,
+ * RegionServerStoppedException
+ */
+ static bool IsScannerClosed(const folly::exception_wrapper& exception);
+
+ static bool IsScannerOutOfOrder(const folly::exception_wrapper& exception);
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/security/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/security/BUCK b/hbase-native-client/include/hbase/security/BUCK
new file mode 100644
index 0000000..2e7530b
--- /dev/null
+++ b/hbase-native-client/include/hbase/security/BUCK
@@ -0,0 +1,30 @@
+##
+# 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.
+
+# This is the library dealing with a single connection
+# to a single server.
+cxx_library(
+ name="security",
+ header_namespace="hbase/security",
+ exported_headers=[
+ "user.h",
+ ],
+ deps=["//src/hbase/client:conf"],
+ compiler_flags=['-Weffc++'],
+ visibility=[
+ 'PUBLIC',
+ ],)
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/security/user.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/security/user.h b/hbase-native-client/include/hbase/security/user.h
new file mode 100644
index 0000000..c958d61
--- /dev/null
+++ b/hbase-native-client/include/hbase/security/user.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 <glog/logging.h>
+#include <mutex>
+#include <string>
+#include "hbase/client/configuration.h"
+
+namespace hbase {
+namespace security {
+static constexpr const char* kKerberos = "kerberos";
+class User {
+ public:
+ explicit User(const std::string& user_name) : user_name_(user_name) {}
+ virtual ~User() = default;
+
+ std::string user_name() { return user_name_; }
+
+ static std::shared_ptr<User> defaultUser() { return std::make_shared<User>("__drwho"); }
+
+ static bool IsSecurityEnabled(const Configuration& conf) {
+ return conf.Get("hbase.security.authentication", "").compare(kKerberos) == 0;
+ }
+
+ private:
+ std::string user_name_;
+};
+}
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/BUCK b/hbase-native-client/include/hbase/serde/BUCK
new file mode 100644
index 0000000..ee8ef82
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/BUCK
@@ -0,0 +1,37 @@
+##
+# 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.
+
+cxx_library(
+ name="serde",
+ header_namespace="hbase/serde",
+ exported_headers=[
+ "cell-scanner.h",
+ "cell-outputstream.h",
+ "codec.h",
+ "region-info.h",
+ "rpc-serde.h",
+ "server-name.h",
+ "table-name.h",
+ "zk.h",
+ ],
+ deps=[
+ "//src/hbase/if:if", "//third-party:folly", "//src/hbase/utils:utils", "//src/hbase/security:security"
+ ],
+ compiler_flags=['-Weffc++'],
+ visibility=[
+ 'PUBLIC',
+ ],)
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/cell-outputstream.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/cell-outputstream.h b/hbase-native-client/include/hbase/serde/cell-outputstream.h
new file mode 100644
index 0000000..963dd31
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/cell-outputstream.h
@@ -0,0 +1,53 @@
+/*
+ * 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 <memory>
+
+namespace hbase {
+
+class Cell;
+
+/**
+ * @brief Encoder / Decoder for Cells.
+ */
+class CellOutputStream {
+ public:
+ virtual ~CellOutputStream() {}
+
+ /**
+ * Implementation must copy the entire state of the Cell. If the written Cell is modified
+ * immediately after the write method returns, the modifications must have absolutely no effect
+ * on the copy of the Cell that was added in the write.
+ * @param cell Cell to write out
+ * @throws IOException
+ */
+ virtual void Write(const Cell& cell) = 0;
+
+ /**
+ * Let the implementation decide what to do. Usually means writing accumulated data into a
+ * byte[] that can then be read from the implementation to be sent to disk, put in the block
+ * cache, or sent over the network.
+ * @throws IOException
+ */
+ virtual void Flush() = 0;
+};
+
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/cell-scanner.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/cell-scanner.h b/hbase-native-client/include/hbase/serde/cell-scanner.h
new file mode 100644
index 0000000..fe4a249
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/cell-scanner.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <folly/io/IOBuf.h>
+#include <memory>
+
+namespace hbase {
+
+class Cell;
+
+/**
+ * @brief Interface for iterating over a sequence of Cells
+ */
+class CellScanner {
+ public:
+ virtual ~CellScanner() {}
+
+ /**
+ * @brief This method will be used to iterate the cells.
+ * Typical usage will be :-
+ * while(cell_scanner.Advance()){
+ * auto current_cell = cell_scanner.Current();
+ * }
+ */
+ virtual bool Advance() = 0;
+
+ /**
+ * @brief returns the current cell
+ */
+ virtual const std::shared_ptr<Cell> Current() const = 0;
+};
+
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/codec.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/codec.h b/hbase-native-client/include/hbase/serde/codec.h
new file mode 100644
index 0000000..adc61b2
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/codec.h
@@ -0,0 +1,50 @@
+/*
+ * 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 <folly/io/IOBuf.h>
+#include <memory>
+
+#include "hbase/serde/cell-outputstream.h"
+#include "hbase/serde/cell-scanner.h"
+
+namespace hbase {
+
+/**
+ * @brief Encoder / Decoder for Cells.
+ */
+class Codec {
+ public:
+ virtual ~Codec() {}
+
+ class Encoder : public CellOutputStream {};
+
+ class Decoder : public CellScanner {};
+
+ virtual std::unique_ptr<Encoder> CreateEncoder() = 0;
+ virtual std::unique_ptr<Decoder> CreateDecoder(std::unique_ptr<folly::IOBuf> cell_block,
+ uint32_t cell_block_start_offset,
+ uint32_t cell_block_length) = 0;
+
+ /** @brief returns the java class name corresponding to this Codec implementation */
+ virtual const char* java_class_name() const = 0;
+};
+
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/region-info.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/region-info.h b/hbase-native-client/include/hbase/serde/region-info.h
new file mode 100644
index 0000000..075e092
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/region-info.h
@@ -0,0 +1,44 @@
+/*
+ * 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 <folly/Conv.h>
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <string>
+
+#include "hbase/if/HBase.pb.h"
+
+namespace hbase {
+namespace pb {
+template <class String>
+void parseTo(String in, RegionInfo &out) {
+ // TODO(eclark): there has to be something better.
+ std::string s = folly::to<std::string>(in);
+
+ if (!boost::starts_with(s, "PBUF")) {
+ throw std::runtime_error("Region Info field doesn't contain preamble");
+ }
+ if (!out.ParseFromArray(s.data() + 4, s.size() - 4)) {
+ throw std::runtime_error("Bad protobuf for RegionInfo");
+ }
+}
+} // namespace pb
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/rpc-serde.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/rpc-serde.h b/hbase-native-client/include/hbase/serde/rpc-serde.h
new file mode 100644
index 0000000..7c89347
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/rpc-serde.h
@@ -0,0 +1,155 @@
+/*
+ * 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 <memory>
+#include <string>
+
+#include <folly/ExceptionWrapper.h>
+#include "hbase/if/HBase.pb.h"
+#include "hbase/serde/cell-scanner.h"
+#include "hbase/serde/codec.h"
+
+using namespace folly;
+// Forward
+namespace folly {
+class IOBuf;
+}
+namespace google {
+namespace protobuf {
+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:
+ RpcSerde();
+ /**
+ * Constructor assumes the default auth type.
+ */
+ RpcSerde(std::shared_ptr<Codec> codec);
+
+ /**
+ * 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.
+ */
+ static std::unique_ptr<folly::IOBuf> Preamble(bool secure);
+
+ /**
+ * 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);
+
+ /**
+ * Take ownership of the passed buffer, and create a CellScanner using the
+ * Codec class to parse Cells out of the wire.
+ */
+ std::unique_ptr<CellScanner> CreateCellScanner(std::unique_ptr<folly::IOBuf> buf, uint32_t offset,
+ uint32_t length);
+
+ /**
+ * 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 response message into a protobuf.
+ * Request consists of:
+ *
+ * - Big endian length
+ * - ResponseHeader object
+ * - The passed in Message object
+ */
+ std::unique_ptr<folly::IOBuf> Response(const uint32_t call_id,
+ const google::protobuf::Message *msg);
+
+ /**
+ * Serialize a response message into a protobuf.
+ * Request consists of:
+ *
+ * - Big endian length
+ * - ResponseHeader object
+ * - The passed in hbase::Response object
+ */
+ std::unique_ptr<folly::IOBuf> Response(const uint32_t call_id,
+ const google::protobuf::Message *msg,
+ const folly::exception_wrapper &exception);
+
+ /**
+ * 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);
+
+ public:
+ static constexpr const char *HBASE_CLIENT_RPC_TEST_MODE = "hbase.client.rpc.test.mode";
+ static constexpr const bool DEFAULT_HBASE_CLIENT_RPC_TEST_MODE = false;
+
+ private:
+ /* data */
+ std::shared_ptr<Codec> codec_;
+ std::unique_ptr<pb::VersionInfo> CreateVersionInfo();
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/server-name.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/server-name.h b/hbase-native-client/include/hbase/serde/server-name.h
new file mode 100644
index 0000000..e650914
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/server-name.h
@@ -0,0 +1,47 @@
+/*
+ * 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 <folly/Conv.h>
+#include <folly/String.h>
+
+#include <string>
+
+#include "hbase/if/HBase.pb.h"
+
+namespace hbase {
+namespace pb {
+
+template <class String>
+void parseTo(String in, ServerName &out) {
+ // TODO see about getting rsplit into folly.
+ std::string s = folly::to<std::string>(in);
+
+ auto delim = s.rfind(":");
+ if (delim == std::string::npos) {
+ throw std::runtime_error("Couldn't parse server name");
+ }
+ out.set_host_name(s.substr(0, delim));
+ // Now keep everything after the : (delim + 1) to the end.
+ out.set_port(folly::to<int>(s.substr(delim + 1)));
+}
+
+} // namespace pb
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/table-name.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/table-name.h b/hbase-native-client/include/hbase/serde/table-name.h
new file mode 100644
index 0000000..756f2aa
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/table-name.h
@@ -0,0 +1,58 @@
+/*
+ * 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 <folly/Conv.h>
+#include <folly/String.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "hbase/if/HBase.pb.h"
+
+namespace hbase {
+namespace pb {
+
+// Provide folly::to<std::string>(TableName);
+template <class String>
+void toAppend(const TableName &in, String *result) {
+ if (!in.has_namespace_() || in.namespace_() == "default") {
+ folly::toAppend(in.qualifier(), result);
+ } else {
+ folly::toAppend(in.namespace_(), ':', in.qualifier(), result);
+ }
+}
+
+template <class String>
+void parseTo(String in, TableName &out) {
+ std::vector<std::string> v;
+ folly::split(":", in, v);
+
+ if (v.size() == 1) {
+ out.set_namespace_("default");
+ out.set_qualifier(v[0]);
+ } else {
+ out.set_namespace_(v[0]);
+ out.set_qualifier(v[1]);
+ }
+}
+
+} // namespace pb
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/serde/zk.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/serde/zk.h b/hbase-native-client/include/hbase/serde/zk.h
new file mode 100644
index 0000000..5cadec2
--- /dev/null
+++ b/hbase-native-client/include/hbase/serde/zk.h
@@ -0,0 +1,49 @@
+/*
+ * 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
+
+namespace google {
+namespace protobuf {
+class Message;
+}
+}
+namespace folly {
+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/128fc306/hbase-native-client/include/hbase/utils/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/BUCK b/hbase-native-client/include/hbase/utils/BUCK
new file mode 100644
index 0000000..d44e908
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/BUCK
@@ -0,0 +1,40 @@
+##
+# 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.
+
+cxx_library(
+ name="utils",
+ header_namespace="hbase/utils",
+ exported_headers=[
+ "bytes-util.h",
+ "connection-util.h",
+ "concurrent-map.h",
+ "optional.h",
+ "sys-util.h",
+ "time-util.h",
+ "user-util.h",
+ "version.h",
+ ],
+ deps=[
+ '//third-party:folly',
+ ],
+ tests=[":user-util-test"],
+ linker_flags=['-L/usr/local/lib', '-lkrb5'],
+ exported_linker_flags=['-L/usr/local/lib', '-lkrb5'],
+ visibility=[
+ 'PUBLIC',
+ ],
+ compiler_flags=['-Weffc++'],)
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/bytes-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/bytes-util.h b/hbase-native-client/include/hbase/utils/bytes-util.h
new file mode 100644
index 0000000..6221bf0
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/bytes-util.h
@@ -0,0 +1,68 @@
+/*
+ * 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 <memory>
+#include <string>
+
+namespace hbase {
+
+class BytesUtil {
+ private:
+ static const constexpr char kHexChars[] = "0123456789ABCDEF";
+
+ public:
+ static std::string ToStringBinary(const std::string& b) { return ToStringBinary(b, 0, b.size()); }
+ /**
+ * Write a printable representation of a byte array. Non-printable
+ * characters are hex escaped in the format \\x%02X, eg:
+ * \x00 \x05 etc
+ *
+ * @param b array to write out
+ * @param off offset to start at
+ * @param len length to write
+ * @return string output
+ */
+ static std::string ToStringBinary(const std::string& b, size_t off, size_t len);
+
+ static std::string ToString(int64_t value);
+
+ static int64_t ToInt64(std::string str);
+
+ static bool IsEmptyStartRow(const std::string& row) { return row == ""; }
+
+ static bool IsEmptyStopRow(const std::string& row) { return row == ""; }
+
+ static int32_t CompareTo(const std::string& a, const std::string& b) {
+ if (a < b) {
+ return -1;
+ }
+ if (a == b) {
+ return 0;
+ }
+ return 1;
+ }
+
+ /**
+ * Create the closest row after the specified row
+ */
+ static std::string CreateClosestRowAfter(std::string row) { return row.append(1, '\0'); }
+};
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/concurrent-map.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/concurrent-map.h b/hbase-native-client/include/hbase/utils/concurrent-map.h
new file mode 100644
index 0000000..aebca0d
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/concurrent-map.h
@@ -0,0 +1,130 @@
+/*
+ * 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 <map>
+#include <memory>
+#include <shared_mutex>
+#include <unordered_map>
+#include <utility>
+
+namespace hbase {
+
+/**
+ * A concurrent version of std::unordered_map where we acquire a shared or exclusive
+ * lock for operations. This is NOT a highly-concurrent and scalable implementation
+ * since there is only one lock object.
+ * Replace this with tbb::concurrent_unordered_map or similar.
+ *
+ * Concurrency here is different than in Java. For example, the iterators returned from
+ * find() will not copy the key, value pairs.
+ */
+template <typename K, typename V>
+class concurrent_map {
+ public:
+ typedef K key_type;
+ typedef V mapped_type;
+ typedef std::pair<const key_type, mapped_type> value_type;
+ typedef typename std::unordered_map<K, V>::iterator iterator;
+ typedef typename std::unordered_map<K, V>::const_iterator const_iterator;
+
+ concurrent_map() : map_(), mutex_() {}
+ explicit concurrent_map(int32_t n) : map_(n), mutex_() {}
+
+ void insert(const value_type& value) {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ map_.insert(value);
+ }
+
+ /**
+ * Return the mapped object for this key. Be careful to not use the return reference
+ * to do assignment. I think it won't be thread safe
+ */
+ mapped_type& at(const key_type& key) {
+ std::shared_lock<std::shared_timed_mutex> lock(mutex_);
+ iterator where = map_.find(key);
+ if (where == end()) {
+ std::runtime_error("Key not found");
+ }
+ return where->second;
+ }
+
+ mapped_type& operator[](const key_type& key) {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ iterator where = map_.find(key);
+ if (where == end()) {
+ return map_[key];
+ }
+ return where->second;
+ }
+
+ /**
+ * Atomically finds the entry and removes it from the map, returning
+ * the previously associated value.
+ */
+ mapped_type find_and_erase(const K& key) {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ auto search = map_.find(key);
+ // It's an error if it's not there.
+ CHECK(search != end());
+ auto val = std::move(search->second);
+ map_.erase(key);
+ return val;
+ }
+
+ void erase(const K& key) {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ map_.erase(key);
+ }
+
+ iterator begin() { return map_.begin(); }
+
+ const_iterator begin() const { return map_.begin(); }
+
+ const_iterator cbegin() const { return map_.begin(); }
+
+ iterator end() { return map_.end(); }
+
+ const_iterator end() const { return map_.end(); }
+
+ const_iterator cend() const { return map_.end(); }
+
+ iterator find(const K& key) {
+ std::shared_lock<std::shared_timed_mutex> lock(mutex_);
+ return map_.find(key);
+ }
+
+ // TODO: find(), at() returning const_iterator
+
+ bool empty() const {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ return map_.empty();
+ }
+
+ void clear() {
+ std::unique_lock<std::shared_timed_mutex> lock(mutex_);
+ map_.clear();
+ }
+
+ private:
+ std::shared_timed_mutex mutex_;
+ std::unordered_map<K, V> map_;
+};
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/connection-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/connection-util.h b/hbase-native-client/include/hbase/utils/connection-util.h
new file mode 100644
index 0000000..b6a53e6
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/connection-util.h
@@ -0,0 +1,62 @@
+/*
+ * 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 <algorithm>
+#include <climits>
+#include <cstdlib>
+#include <memory>
+#include <vector>
+#include "hbase/utils/time-util.h"
+
+namespace hbase {
+class ConnectionUtils {
+ public:
+ static int Retries2Attempts(const int& retries) {
+ return std::max(1, retries == INT_MAX ? INT_MAX : retries + 1);
+ }
+
+ /* Add a delta to avoid timeout immediately after a retry sleeping. */
+ static const uint64_t kSleepDeltaNs = 1000000;
+
+ static const std::vector<uint32_t> kRetryBackoff;
+ /**
+ * Calculate pause time. Built on {@link kRetryBackoff}.
+ * @param pause time to pause
+ * @param tries amount of tries
+ * @return How long to wait after <code>tries</code> retries
+ */
+ static int64_t GetPauseTime(const int64_t& pause, const int32_t& tries) {
+ int32_t ntries = tries;
+ if (static_cast<size_t>(ntries) >= kRetryBackoff.size()) {
+ ntries = kRetryBackoff.size() - 1;
+ }
+ if (ntries < 0) {
+ ntries = 0;
+ }
+
+ int64_t normal_pause = pause * kRetryBackoff[ntries];
+ // 1% possible jitter
+ float r = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
+ int64_t jitter = (int64_t)(normal_pause * r * 0.01f);
+ return normal_pause + jitter;
+ }
+};
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/optional.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/optional.h b/hbase-native-client/include/hbase/utils/optional.h
new file mode 100644
index 0000000..a05eab5
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/optional.h
@@ -0,0 +1,32 @@
+/*
+ * 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 <experimental/optional>
+
+namespace hbase {
+
+/**
+ * An optional value that may or may not be present.
+ */
+template <class T>
+using optional = std::experimental::optional<T>;
+
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/sys-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/sys-util.h b/hbase-native-client/include/hbase/utils/sys-util.h
new file mode 100644
index 0000000..68f00d7
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/sys-util.h
@@ -0,0 +1,39 @@
+/*
+ * 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 <type_traits>
+
+namespace hbase {
+
+class SysUtil {
+ public:
+ template <class BASE, typename DERIVED>
+ static constexpr bool InstanceOf(const DERIVED& object) {
+ return !dynamic_cast<const BASE*>(&object);
+ }
+
+ template <typename BASE, typename DERIVED>
+ static constexpr bool InstanceOf() {
+ return std::is_base_of<BASE, DERIVED>();
+ }
+};
+
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/time-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/time-util.h b/hbase-native-client/include/hbase/utils/time-util.h
new file mode 100644
index 0000000..165e9f1
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/time-util.h
@@ -0,0 +1,71 @@
+/*
+ * 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 <chrono>
+#include <string>
+
+namespace hbase {
+
+class TimeUtil {
+ public:
+ static inline int64_t ToMillis(const int64_t& nanos) {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::nanoseconds(nanos))
+ .count();
+ }
+
+ static inline std::chrono::milliseconds ToMillis(const std::chrono::nanoseconds& nanos) {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::nanoseconds(nanos));
+ }
+
+ static inline std::chrono::nanoseconds ToNanos(const std::chrono::milliseconds& millis) {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(millis);
+ }
+
+ static inline std::chrono::nanoseconds MillisToNanos(const int64_t& millis) {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(millis));
+ }
+
+ static inline std::chrono::nanoseconds SecondsToNanos(const int64_t& secs) {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(secs));
+ }
+
+ static inline std::string ToMillisStr(const std::chrono::nanoseconds& nanos) {
+ return std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(nanos).count());
+ }
+
+ static inline int64_t GetNowNanos() {
+ auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
+ }
+
+ static inline int64_t ElapsedMillis(const int64_t& start_ns) {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::nanoseconds(GetNowNanos() - start_ns))
+ .count();
+ }
+
+ static inline std::string ElapsedMillisStr(const int64_t& start_ns) {
+ return std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::nanoseconds(GetNowNanos() - start_ns))
+ .count());
+ }
+};
+} /* namespace hbase */
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/include/hbase/utils/user-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/include/hbase/utils/user-util.h b/hbase-native-client/include/hbase/utils/user-util.h
new file mode 100644
index 0000000..6258c85
--- /dev/null
+++ b/hbase-native-client/include/hbase/utils/user-util.h
@@ -0,0 +1,54 @@
+/*
+ * 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 <mutex>
+#include <string>
+
+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(bool secure = false);
+
+ private:
+ /**
+ * Compute the username. This will block.
+ */
+ void compute_user_name(bool secure);
+ std::once_flag once_flag_;
+ std::string user_name_;
+};
+} // namespace hbase
http://git-wip-us.apache.org/repos/asf/hbase/blob/128fc306/hbase-native-client/security/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/security/BUCK b/hbase-native-client/security/BUCK
deleted file mode 100644
index f8a5695..0000000
--- a/hbase-native-client/security/BUCK
+++ /dev/null
@@ -1,30 +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.
-
-# This is the library dealing with a single connection
-# to a single server.
-cxx_library(
- name="security",
- exported_headers=[
- "user.h",
- ],
- srcs=[],
- deps=["//core:conf"],
- compiler_flags=['-Weffc++'],
- visibility=[
- 'PUBLIC',
- ],)