From 2f2338f3f8b66921d6db223064bb23ff41894486 Mon Sep 17 00:00:00 2001 From: Parth Chandra Date: Mon, 16 Mar 2015 13:38:46 -0700 Subject: DRILL-2442: Initial implementation of C++ client support for impersonation. --- .../native/client/src/clientlib/drillClient.cpp | 42 ++++++++++++++++++-- .../client/src/clientlib/drillClientImpl.cpp | 33 +++++++++++++--- .../client/src/clientlib/drillClientImpl.hpp | 2 +- contrib/native/client/src/include/drill/common.hpp | 32 +++++++++++++++ .../client/src/include/drill/drillClient.hpp | 45 +++++++++++++++++++++- 5 files changed, 142 insertions(+), 12 deletions(-) (limited to 'contrib/native/client/src') diff --git a/contrib/native/client/src/clientlib/drillClient.cpp b/contrib/native/client/src/clientlib/drillClient.cpp index 71907e094..90aa55510 100644 --- a/contrib/native/client/src/clientlib/drillClient.cpp +++ b/contrib/native/client/src/clientlib/drillClient.cpp @@ -17,6 +17,7 @@ */ +#include #include "drill/common.hpp" #include "drill/drillClient.hpp" #include "drill/recordBatch.hpp" @@ -119,6 +120,22 @@ logLevel_t DrillClientConfig::getLogLevel(){ return s_logLevel; } +//Using boost assign to initialize maps. +const std::map DrillUserProperties::USER_PROPERTIES=boost::assign::map_list_of + ( USERPROP_USERNAME, USERPROP_FLAGS_SERVERPROP|USERPROP_FLAGS_STRING ) + ( USERPROP_PASSWORD, USERPROP_FLAGS_SERVERPROP|USERPROP_FLAGS_PASSWORD) + ( USERPROP_SCHEMA, USERPROP_FLAGS_SERVERPROP|USERPROP_FLAGS_STRING) + ( USERPROP_USESSL, USERPROP_FLAGS_BOOLEAN|USERPROP_FLAGS_SSLPROP) + ( USERPROP_FILEPATH, USERPROP_FLAGS_STRING|USERPROP_FLAGS_SSLPROP|USERPROP_FLAGS_FILEPATH) + ( USERPROP_FILENAME, USERPROP_FLAGS_STRING|USERPROP_FLAGS_SSLPROP|USERPROP_FLAGS_FILENAME) +; + +bool DrillUserProperties::validate(std::string& err){ + bool ret=true; + //We can add additional validation for any params here + return ret; +} + RecordIterator::~RecordIterator(){ if(m_pColDefs!=NULL){ for(std::vector::iterator it=m_pColDefs->begin(); @@ -288,11 +305,30 @@ DrillClient::~DrillClient(){ connectionStatus_t DrillClient::connect(const char* connectStr, const char* defaultSchema){ connectionStatus_t ret=CONN_SUCCESS; ret=this->m_pImpl->connect(connectStr); - - if(ret==CONN_SUCCESS) - ret=this->m_pImpl->validateHandShake(defaultSchema); + DrillUserProperties props; + std::string schema(defaultSchema); + props.setProperty(USERPROP_SCHEMA, schema); + if(ret==CONN_SUCCESS){ + if(defaultSchema!=NULL){ + ret=this->m_pImpl->validateHandshake(&props); + }else{ + ret=this->m_pImpl->validateHandshake(NULL); + } + } return ret; +} +connectionStatus_t DrillClient::connect(const char* connectStr, DrillUserProperties* properties){ + connectionStatus_t ret=CONN_SUCCESS; + ret=this->m_pImpl->connect(connectStr); + if(ret==CONN_SUCCESS){ + if(properties!=NULL){ + ret=this->m_pImpl->validateHandshake(properties); + }else{ + ret=this->m_pImpl->validateHandshake(NULL); + } + } + return ret; } bool DrillClient::isActive(){ diff --git a/contrib/native/client/src/clientlib/drillClientImpl.cpp b/contrib/native/client/src/clientlib/drillClientImpl.cpp index ea3a7ee9d..e6f8009e6 100644 --- a/contrib/native/client/src/clientlib/drillClientImpl.cpp +++ b/contrib/native/client/src/clientlib/drillClientImpl.cpp @@ -270,7 +270,7 @@ void DrillClientImpl::handleHShakeReadTimeout(const boost::system::error_code & return; } -connectionStatus_t DrillClientImpl::validateHandShake(const char* defaultSchema){ +connectionStatus_t DrillClientImpl::validateHandshake(DrillUserProperties* properties){ DRILL_LOG(LOG_TRACE) << "validateHandShake\n"; @@ -279,13 +279,34 @@ connectionStatus_t DrillClientImpl::validateHandShake(const char* defaultSchema) u2b.set_rpc_version(DRILL_RPC_VERSION); u2b.set_support_listening(true); - if ( defaultSchema != NULL ){ - DRILL_LOG(LOG_TRACE) << "defaultSchema = " << defaultSchema << "\n"; + if(properties != NULL && properties->size()>0){ + std::string err; + if(!properties->validate(err)){ + DRILL_LOG(LOG_INFO) << "Invalid user input:" << err << std::endl; + } exec::user::UserProperties* userProperties = u2b.mutable_properties(); - exec::user::Property* connSchema = userProperties->add_properties(); - connSchema->set_key("schema"); - connSchema->set_value(defaultSchema); + + std::map::iterator it; + for(size_t i=0; isize(); i++){ + std::map::const_iterator it=DrillUserProperties::USER_PROPERTIES.find(properties->keyAt(i)); + if(it==DrillUserProperties::USER_PROPERTIES.end()){ + DRILL_LOG(LOG_WARNING) << "Connection property ("<< properties->keyAt(i) + << ") is unknown and is being skipped" << std::endl; + continue; + } + if(IS_BITSET((*it).second,USERPROP_FLAGS_SERVERPROP)){ + exec::user::Property* connProp = userProperties->add_properties(); + connProp->set_key(properties->keyAt(i)); + connProp->set_value(properties->valueAt(i)); + if(IS_BITSET((*it).second,USERPROP_FLAGS_PASSWORD)){ + DRILL_LOG(LOG_INFO) << properties->keyAt(i) << ": ********** " << std::endl; + }else{ + DRILL_LOG(LOG_INFO) << properties->keyAt(i) << ":" << properties->valueAt(i) << std::endl; + } + }// Server properties + } } + { boost::lock_guard lock(this->m_dcMutex); uint64_t coordId = this->getNextCoordinationId(); diff --git a/contrib/native/client/src/clientlib/drillClientImpl.hpp b/contrib/native/client/src/clientlib/drillClientImpl.hpp index d287bfc17..a6de40b48 100644 --- a/contrib/native/client/src/clientlib/drillClientImpl.hpp +++ b/contrib/native/client/src/clientlib/drillClientImpl.hpp @@ -241,7 +241,7 @@ class DrillClientImpl{ DrillClientError* getError(){ return m_pError;} DrillClientQueryResult* SubmitQuery(::exec::shared::QueryType t, const std::string& plan, pfnQueryResultsListener listener, void* listenerCtx); void waitForResults(); - connectionStatus_t validateHandShake(const char* defaultSchema); + connectionStatus_t validateHandshake(DrillUserProperties* props); private: friend class DrillClientQueryResult; diff --git a/contrib/native/client/src/include/drill/common.hpp b/contrib/native/client/src/include/drill/common.hpp index e149ed11d..dbfa6fec6 100644 --- a/contrib/native/client/src/include/drill/common.hpp +++ b/contrib/native/client/src/include/drill/common.hpp @@ -58,6 +58,16 @@ #endif // _WIN32 && !_WIN64 +//DEPRECATED MACRO +#if defined(__GNUC__) || defined(__llvm__) +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: DEPRECATED not available for this compiler") +#define DEPRECATED +#endif + namespace Drill { typedef std::vector DataBuf; @@ -118,6 +128,28 @@ typedef enum{ RET_FAILURE=1 } ret_t; + +// User Property Names +#define USERPROP_USERNAME "userName" +#define USERPROP_PASSWORD "password" +#define USERPROP_SCHEMA "schema" +#define USERPROP_USESSL "useSSL" // Not implemented yet +#define USERPROP_FILEPATH "pemLocation" // Not implemented yet +#define USERPROP_FILENAME "pemFile" // Not implemented yet + +// Bitflags to describe user properties +// Used in DrillUserProperties::USER_PROPERTIES +#define USERPROP_FLAGS_SERVERPROP 0x00000001 +#define USERPROP_FLAGS_SSLPROP 0x00000002 +#define USERPROP_FLAGS_PASSWORD 0x00000004 +#define USERPROP_FLAGS_FILENAME 0x00000008 +#define USERPROP_FLAGS_FILEPATH 0x00000010 +#define USERPROP_FLAGS_STRING 0x00000020 +#define USERPROP_FLAGS_BOOLEAN 0x00000040 + +#define IS_BITSET(val, bit) \ + ((val&bit)==bit) + } // namespace Drill #endif diff --git a/contrib/native/client/src/include/drill/drillClient.hpp b/contrib/native/client/src/include/drill/drillClient.hpp index 71a5c800f..9289df3c7 100644 --- a/contrib/native/client/src/include/drill/drillClient.hpp +++ b/contrib/native/client/src/include/drill/drillClient.hpp @@ -135,6 +135,29 @@ class DECLSPEC_DRILL_CLIENT DrillClientConfig{ }; +class DECLSPEC_DRILL_CLIENT DrillUserProperties{ + public: + static const std::map USER_PROPERTIES; + + DrillUserProperties(){}; + + void setProperty( std::string propName, std::string propValue){ + std::pair< std::string, std::string> in = make_pair(propName, propValue); + m_properties.push_back(in); + } + + size_t size() const { return m_properties.size(); } + + const std::string& keyAt(size_t i) const { return m_properties.at(i).first; } + + const std::string& valueAt(size_t i) const { return m_properties.at(i).second; } + + bool validate(std::string& err); + + private: + std::vector< std::pair< std::string, std::string> > m_properties; +}; + /* * Handle to the Query submitted for execution. * */ @@ -233,6 +256,15 @@ class DECLSPEC_DRILL_CLIENT DrillClient{ /** * Connect the client to a Drillbit using connection string and default schema. * + * @param[in] connectStr: connection string + * @param[in] defaultSchema: default schema (set to NULL and ignore it + * if not specified) + * @return connection status + */ + DEPRECATED connectionStatus_t connect(const char* connectStr, const char* defaultSchema=NULL); + + /* + * Connect the client to a Drillbit using connection string and a set of user properties. * The connection string format can be found in comments of * [DRILL-780](https://issues.apache.org/jira/browse/DRILL-780) * @@ -253,12 +285,21 @@ class DECLSPEC_DRILL_CLIENT DrillClient{ * local=127.0.0.1:31010 * ``` * + * User properties is a set of name value pairs. The following properties are recognized: + * schema + * userName + * password + * useSSL [true|false] + * pemLocation + * pemFile + * (see drill/common.hpp for friendly defines and the latest list of supported proeprties) + * * @param[in] connectStr: connection string - * @param[in] defaultSchema: default schema (set to NULL and ignore it + * @param[in] properties * if not specified) * @return connection status */ - connectionStatus_t connect(const char* connectStr, const char* defaultSchema=NULL); + connectionStatus_t connect(const char* connectStr, DrillUserProperties* properties); /* test whether the client is active */ bool isActive(); -- cgit v1.2.3