Github user parthchandra commented on a diff in the pull request:
https://github.com/apache/drill/pull/950#discussion_r141740253
--- Diff: contrib/native/client/src/clientlib/channel.hpp ---
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+#ifndef CHANNEL_HPP
+#define CHANNEL_HPP
+
+#include "drill/common.hpp"
+#include "drill/drillClient.hpp"
+#include "streamSocket.hpp"
+
+namespace Drill {
+
+class UserProperties;
+
+ class ConnectionEndpoint{
+ public:
+ ConnectionEndpoint(const char* connStr);
+ ConnectionEndpoint(const char* host, const char* port);
+ ~ConnectionEndpoint();
+
+ //parse the connection string and set up the host and port to
connect to
+ connectionStatus_t getDrillbitEndpoint();
+
+ std::string& getProtocol(){return m_protocol;}
+ std::string& getHost(){return m_host;}
+ std::string& getPort(){return m_port;}
+ DrillClientError* getError(){ return m_pError;};
+
+ private:
+ void parseConnectString();
+ connectionStatus_t validateConnectionString();
+ bool isDirectConnection();
+ bool isZookeeperConnection();
+ connectionStatus_t getDrillbitEndpointFromZk();
+ connectionStatus_t handleError(connectionStatus_t status,
std::string msg);
+
+ std::string m_connectString;
+ std::string m_pathToDrill;
+ std::string m_protocol;
+ std::string m_hostPortStr;
+ std::string m_host;
+ std::string m_port;
+
+ DrillClientError* m_pError;
+
+ };
+
+ class ChannelContext{
+ public:
+ ChannelContext(DrillUserProperties*
props):m_properties(props){};
+ virtual ~ChannelContext(){};
+ const DrillUserProperties* getUserProperties() const { return
m_properties;}
+ protected:
+ DrillUserProperties* m_properties;
+ };
+
+ class SSLChannelContext: public ChannelContext{
+ public:
+ static boost::asio::ssl::context::method
getTlsVersion(std::string version){
+ if(version.empty()){
+ return boost::asio::ssl::context::tlsv12;
+ } else if (version == "tlsv12") {
+ return boost::asio::ssl::context::tlsv12;
+ } else if (version == "tlsv11") {
+ return boost::asio::ssl::context::tlsv11;
+ } else if (version == "sslv23") {
+ return boost::asio::ssl::context::sslv23;
+ } else if (version == "tlsv1") {
+ return boost::asio::ssl::context::tlsv1;
+ } else if (version == "sslv3") {
+ return boost::asio::ssl::context::sslv3;
+ } else {
+ return boost::asio::ssl::context::tlsv12;
+ }
+ }
+
+ SSLChannelContext(DrillUserProperties *props,
boost::asio::ssl::context::method tlsVersion, boost::asio::ssl::verify_mode
verifyMode) :
+ ChannelContext(props),
+ m_SSLContext(tlsVersion) {
+ m_SSLContext.set_default_verify_paths();
+ m_SSLContext.set_options(
+ boost::asio::ssl::context::default_workarounds
+ | boost::asio::ssl::context::no_sslv2
+ | boost::asio::ssl::context::single_dh_use
+ );
+ m_SSLContext.set_verify_mode(verifyMode);
+ };
+ ~SSLChannelContext(){};
+ boost::asio::ssl::context& getSslContext(){ return
m_SSLContext;}
+ private:
+ boost::asio::ssl::context m_SSLContext;
+ };
+
+ typedef ChannelContext ChannelContext_t;
+ typedef SSLChannelContext SSLChannelContext_t;
+
+ class ChannelContextFactory{
+ public:
+ static ChannelContext_t* getChannelContext(channelType_t t,
DrillUserProperties* props);
+ };
+
+ /***
+ * The Channel class encapsulates a connection to a drillbit. Based on
+ * the connection string and the options, the connection will be
either
+ * a simple socket or a socket using an ssl stream. The class also
encapsulates
+ * connecting to a drillbit directly or thru zookeeper.
+ * The channel class owns the socket and the io_service that the
applications
+ * will use to communicate with the server.
+ ***/
+ class Channel{
+ public:
+ Channel(const char* connStr);
+ Channel(const char* host, const char* port);
+ Channel(boost::asio::io_service& ioService, const char*
connStr);
+ Channel(boost::asio::io_service& ioService, const char* host,
const char* port);
+ virtual ~Channel();
+ virtual connectionStatus_t init(ChannelContext_t* context)=0;
+ connectionStatus_t connect();
+ connectionStatus_t protocolClose();
+ template <typename SettableSocketOption> void
setOption(SettableSocketOption& option);
+ DrillClientError* getError(){ return m_pError;}
+ void close(){
+
if(m_state==CHANNEL_INITIALIZED||m_state==CHANNEL_CONNECTED){
+ m_pSocket->protocolClose();
+ m_state=CHANNEL_CLOSED;
+ }
+ } // Not OK to use the channel after this call.
+
+ boost::asio::io_service& getIOService(){
+ return m_ioService;
+ }
+
+ // returns a reference to the underlying socket
+ // This access should really be removed and encapsulated in
calls that
+ // manage async_send and async_recv
+ // Until then we will let DrillClientImpl have direct access
+ streamSocket_t& getInnerSocket(){
+ return m_pSocket->getInnerSocket();
+ }
+
+ AsioStreamSocket& getSocketStream(){
+ return *m_pSocket;
+ }
+
+ ConnectionEndpoint* getEndpoint(){return m_pEndpoint;}
+
+ protected:
+ connectionStatus_t handleError(connectionStatus_t status,
std::string msg);
+
+ boost::asio::io_service& m_ioService;
+ boost::asio::io_service m_ioServiceFallback; // used if
m_ioService is not provided
+ AsioStreamSocket* m_pSocket;
+ ConnectionEndpoint *m_pEndpoint;
+ ChannelContext_t *m_pContext;
+
+ private:
+ typedef enum channelState{
+ CHANNEL_UNINITIALIZED=1,
+ CHANNEL_INITIALIZED,
+ CHANNEL_CONNECTED,
+ CHANNEL_CLOSED
+ } channelState_t;
+
+ connectionStatus_t connectInternal();
+ connectionStatus_t protocolHandshake(bool useSystemConfig){
+ connectionStatus_t status = CONN_SUCCESS;
+ try{
+ m_pSocket->protocolHandshake(useSystemConfig);
+ } catch (boost::system::system_error e) {
+ status = handleError(CONN_HANDSHAKE_FAILED, e.what());
+ }
+ return status;
+ }
+
+ channelState_t m_state;
+ DrillClientError* m_pError;
+ bool m_ownIoService;
--- End diff --
Artifact of an earlier version where the caller could pass in an io_service
or choose to let the Channel provide a default one. That led to all sorts of
clean up issues and so I simplified it. The flag is not needed any more.
---