You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2018/01/30 12:58:24 UTC
[1/4] ignite git commit: IGNITE-6810: Implemented SSL support for
ODBC.
Repository: ignite
Updated Branches:
refs/heads/master a824ba8e1 -> 394019eef
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 4e8f4ab..11105b6 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -28,6 +28,10 @@
#include "ignite/odbc/connection.h"
#include "ignite/odbc/message.h"
#include "ignite/odbc/config/configuration.h"
+#include "ignite/odbc/ssl/ssl_mode.h"
+#include "ignite/odbc/ssl/ssl_gateway.h"
+#include "ignite/odbc/ssl/secure_socket_client.h"
+#include "ignite/odbc/system/tcp_socket_client.h"
// Uncomment for per-byte debug.
//#define PER_BYTE_DEBUG
@@ -49,7 +53,6 @@ namespace ignite
{
Connection::Connection() :
socket(),
- connected(false),
timeout(0),
parser(),
config(),
@@ -122,21 +125,44 @@ namespace ignite
SqlResult::Type Connection::InternalEstablish(const config::Configuration cfg)
{
+ using ssl::SslMode;
+
config = cfg;
- if (connected)
+ if (socket.get() != 0)
{
AddStatusRecord(SqlState::S08002_ALREADY_CONNECTED, "Already connected.");
return SqlResult::AI_ERROR;
}
- connected = socket.Connect(cfg.GetHost().c_str(), cfg.GetTcpPort(), *this);
+ SslMode::T sslMode = SslMode::FromString(cfg.GetSslMode(), SslMode::DISABLE);
+
+ if (sslMode != SslMode::DISABLE)
+ {
+ bool loaded = ssl::SslGateway::GetInstance().LoadAll();
+
+ if (!loaded)
+ {
+ AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not load OpenSSL library (did you set OPENSSL_HOME environment variable?).");
+
+ return SqlResult::AI_ERROR;
+ }
+
+ socket.reset(new ssl::SecureSocketClient(cfg.GetSslCertFile(), cfg.GetSslKeyFile(), cfg.GetSslCaFile()));
+ }
+ else
+ socket.reset(new system::TcpSocketClient());
+
+ bool connected = socket->Connect(cfg.GetHost().c_str(), cfg.GetTcpPort(), *this);
if (!connected)
{
AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with the host.");
+ Close();
+
return SqlResult::AI_ERROR;
}
@@ -157,7 +183,7 @@ namespace ignite
SqlResult::Type Connection::InternalRelease()
{
- if (!connected)
+ if (socket.get() == 0)
{
AddStatusRecord(SqlState::S08003_NOT_CONNECTED, "Connection is not open.");
@@ -171,9 +197,12 @@ namespace ignite
void Connection::Close()
{
- socket.Close();
+ if (socket.get() != 0)
+ {
+ socket->Close();
- connected = false;
+ socket.reset();
+ }
}
Statement* Connection::CreateStatement()
@@ -201,7 +230,7 @@ namespace ignite
bool Connection::Send(const int8_t* data, size_t len, int32_t timeout)
{
- if (!connected)
+ if (socket.get() == 0)
throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established");
int32_t newLen = static_cast<int32_t>(len + sizeof(OdbcProtocolHeader));
@@ -235,11 +264,11 @@ namespace ignite
while (sent != static_cast<int64_t>(len))
{
- int res = socket.Send(data + sent, len - sent, timeout);
+ int res = socket->Send(data + sent, len - sent, timeout);
LOG_MSG("Sent: " << res);
- if (res < 0 || res == tcp::SocketClient::WaitResult::TIMEOUT)
+ if (res < 0 || res == SocketClient::WaitResult::TIMEOUT)
{
Close();
@@ -256,7 +285,7 @@ namespace ignite
bool Connection::Receive(std::vector<int8_t>& msg, int32_t timeout)
{
- if (!connected)
+ if (socket.get() == 0)
throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established");
msg.clear();
@@ -307,10 +336,10 @@ namespace ignite
{
size_t received = len - remain;
- int res = socket.Receive(buffer + received, remain, timeout);
+ int res = socket->Receive(buffer + received, remain, timeout);
LOG_MSG("Receive res: " << res << " remain: " << remain);
- if (res < 0 || res == tcp::SocketClient::WaitResult::TIMEOUT)
+ if (res < 0 || res == SocketClient::WaitResult::TIMEOUT)
{
Close();
@@ -382,7 +411,7 @@ namespace ignite
{
SQLUINTEGER *val = reinterpret_cast<SQLUINTEGER*>(buf);
- *val = connected ? SQL_CD_FALSE : SQL_CD_TRUE;
+ *val = socket.get() != 0 ? SQL_CD_FALSE : SQL_CD_TRUE;
if (valueLen)
*valueLen = SQL_IS_INTEGER;
@@ -441,7 +470,7 @@ namespace ignite
{
SQLUINTEGER uTimeout = static_cast<SQLUINTEGER>(reinterpret_cast<ptrdiff_t>(value));
- if (uTimeout != 0 && connected && socket.IsBlocking())
+ if (uTimeout != 0 && socket.get() != 0 && socket->IsBlocking())
{
timeout = 0;
@@ -524,12 +553,13 @@ namespace ignite
try
{
// Workaround for some Linux systems that report connection on non-blocking
- // sockets as successfull but fail to establish real connection.
- bool sent = SyncMessage(req, rsp, tcp::SocketClient::CONNECT_TIMEOUT);
+ // sockets as successful but fail to establish real connection.
+ bool sent = SyncMessage(req, rsp, SocketClient::CONNECT_TIMEOUT);
if (!sent)
{
- AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with the host.");
+ AddStatusRecord(SqlState::S08001_CANNOT_CONNECT,
+ "Failed to get handshake response (Did you forget to enable SSL?).");
return SqlResult::AI_ERROR;
}
@@ -549,7 +579,7 @@ namespace ignite
if (!rsp.IsAccepted())
{
- LOG_MSG("Hanshake message has been rejected.");
+ LOG_MSG("Handshake message has been rejected.");
std::stringstream constructor;
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/dsn_config.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/dsn_config.cpp b/modules/platforms/cpp/odbc/src/dsn_config.cpp
index 536f679..845c8bd 100644
--- a/modules/platforms/cpp/odbc/src/dsn_config.cpp
+++ b/modules/platforms/cpp/odbc/src/dsn_config.cpp
@@ -51,13 +51,13 @@ namespace ignite
ThrowLastSetupError();
}
- std::string ReadDsnString(const char* dsn, const std::string& key, const char* dflt)
+ std::string ReadDsnString(const char* dsn, const std::string& key, const std::string& dflt)
{
char buf[BUFFER_SIZE];
memset(buf, 0, sizeof(buf));
- SQLGetPrivateProfileString(dsn, key.c_str(), dflt, buf, sizeof(buf), CONFIG_FILE);
+ SQLGetPrivateProfileString(dsn, key.c_str(), dflt.c_str(), buf, sizeof(buf), CONFIG_FILE);
return std::string(buf);
}
@@ -90,13 +90,13 @@ namespace ignite
void ReadDsnConfiguration(const char* dsn, Configuration& config)
{
- std::string address = ReadDsnString(dsn, Configuration::Key::address, config.GetAddress().c_str());
+ std::string address = ReadDsnString(dsn, Configuration::Key::address, config.GetAddress());
- std::string server = ReadDsnString(dsn, Configuration::Key::server, config.GetHost().c_str());
+ std::string server = ReadDsnString(dsn, Configuration::Key::server, config.GetHost());
uint16_t port = ReadDsnInt(dsn, Configuration::Key::port, config.GetTcpPort());
- std::string schema = ReadDsnString(dsn, Configuration::Key::schema, config.GetSchema().c_str());
+ std::string schema = ReadDsnString(dsn, Configuration::Key::schema, config.GetSchema());
bool distributedJoins = ReadDsnBool(dsn, Configuration::Key::distributedJoins, config.IsDistributedJoins());
@@ -112,13 +112,21 @@ namespace ignite
ReadDsnBool(dsn, Configuration::Key::skipReducerOnUpdate, config.IsSkipReducerOnUpdate());
std::string version = ReadDsnString(dsn, Configuration::Key::protocolVersion,
- config.GetProtocolVersion().ToString().c_str());
+ config.GetProtocolVersion().ToString());
int32_t pageSize = ReadDsnInt(dsn, Configuration::Key::pageSize, config.GetPageSize());
if (pageSize <= 0)
pageSize = config.GetPageSize();
+ std::string sslMode = ReadDsnString(dsn, Configuration::Key::sslMode, config.GetSslMode());
+
+ std::string sslKeyFile = ReadDsnString(dsn, Configuration::Key::sslKeyFile, config.GetSslKeyFile());
+
+ std::string sslCertFile = ReadDsnString(dsn, Configuration::Key::sslCertFile, config.GetSslCertFile());
+
+ std::string sslCaFile = ReadDsnString(dsn, Configuration::Key::sslCaFile, config.GetSslCaFile());
+
config.SetAddress(address);
config.SetHost(server);
config.SetTcpPort(port);
@@ -131,6 +139,10 @@ namespace ignite
config.SetSkipReducerOnUpdate(skipReducerOnUpdate);
config.SetProtocolVersion(version);
config.SetPageSize(pageSize);
+ config.SetSslMode(sslMode);
+ config.SetSslKeyFile(sslKeyFile);
+ config.SetSslCertFile(sslCertFile);
+ config.SetSslCaFile(sslCaFile);
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 1480d0b..e4b47b9 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -180,7 +180,7 @@ namespace ignite
{
using odbc::Environment;
- LOG_MSG("SQLFreeEnv called");
+ LOG_MSG("SQLFreeEnv called: " << env);
Environment *environment = reinterpret_cast<Environment*>(env);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/ssl/secure_socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/ssl/secure_socket_client.cpp b/modules/platforms/cpp/odbc/src/ssl/secure_socket_client.cpp
new file mode 100644
index 0000000..c305b87
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/ssl/secure_socket_client.cpp
@@ -0,0 +1,419 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+#include <cstdio>
+
+#include "ignite/odbc/log.h"
+#include "ignite/common/concurrent.h"
+#include "ignite/odbc/system/tcp_socket_client.h"
+#include "ignite/odbc/ssl/secure_socket_client.h"
+#include "ignite/odbc/ssl/ssl_bindings.h"
+
+#ifndef SOCKET_ERROR
+# define SOCKET_ERROR (-1)
+#endif // SOCKET_ERROR
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ SecureSocketClient::SecureSocketClient(const std::string& certPath, const std::string& keyPath,
+ const std::string& caPath):
+ certPath(certPath),
+ keyPath(keyPath),
+ caPath(caPath),
+ context(0),
+ sslBio(0),
+ blocking(true)
+ {
+ // No-op.
+ }
+
+ SecureSocketClient::~SecureSocketClient()
+ {
+ CloseInteral();
+
+ if (context)
+ ssl::SSL_CTX_free(reinterpret_cast<SSL_CTX*>(context));
+ }
+
+ bool SecureSocketClient::Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag)
+ {
+ assert(SslGateway::GetInstance().Loaded());
+
+ if (!context)
+ {
+ context = MakeContext(certPath, keyPath, caPath, diag);
+
+ if (!context)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not create SSL context. Aborting connect.");
+
+ return false;
+ }
+ }
+
+ BIO* bio = ssl::BIO_new_ssl_connect(reinterpret_cast<SSL_CTX*>(context));
+ if (!bio)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create SSL connection.");
+
+ return false;
+ }
+
+ blocking = false;
+ long res = ssl::BIO_set_nbio_(bio, 1);
+ if (res != OPERATION_SUCCESS)
+ {
+ blocking = true;
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up non-blocking mode. Timeouts are not available.");
+ }
+
+ std::stringstream stream;
+ stream << hostname << ":" << port;
+
+ std::string address = stream.str();
+
+ res = ssl::BIO_set_conn_hostname_(bio, address.c_str());
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not set SSL connection hostname.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ SSL* ssl = 0;
+ ssl::BIO_get_ssl_(bio, &ssl);
+ if (!ssl)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not get SSL instance from BIO.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ res = ssl::SSL_set_tlsext_host_name_(ssl, hostname);
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not set host name for secure connection");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ do
+ {
+ res = ssl::BIO_do_connect_(bio);
+ } while (ssl::BIO_should_retry_(bio));
+
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::S08001_CANNOT_CONNECT,
+ "Failed to establish secure connection with the host.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ do
+ {
+ res = ssl::BIO_do_handshake_(bio);
+ } while (ssl::BIO_should_retry_(bio));
+
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, "SSL handshake failed.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ // Verify a server certificate was presented during the negotiation
+ X509* cert = ssl::SSL_get_peer_certificate(ssl);
+ if (cert)
+ ssl::X509_free(cert);
+ else
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Remote host did not provide certificate.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ // Verify the result of chain verification
+ // Verification performed according to RFC 4158
+ res = ssl::SSL_get_verify_result(ssl);
+ if (X509_V_OK != res)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Certificate chain verification failed.");
+
+ ssl::BIO_free_all(bio);
+
+ return false;
+ }
+
+ sslBio = reinterpret_cast<void*>(bio);
+
+ return true;
+ }
+
+ void SecureSocketClient::Close()
+ {
+ CloseInteral();
+ }
+
+ int SecureSocketClient::Send(const int8_t* data, size_t size, int32_t timeout)
+ {
+ assert(SslGateway::GetInstance().Loaded());
+
+ if (!sslBio)
+ {
+ LOG_MSG("Trying to send data using closed connection");
+
+ return -1;
+ }
+
+ BIO* sslBio0 = reinterpret_cast<BIO*>(sslBio);
+
+ int res = 0;
+
+ do
+ {
+ res = ssl::BIO_write(sslBio0, data, static_cast<int>(size));
+ }
+ while (ssl::BIO_should_retry_(sslBio0));
+
+ return res;
+ }
+
+ int SecureSocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout)
+ {
+ assert(SslGateway::GetInstance().Loaded());
+
+ if (!sslBio)
+ {
+ LOG_MSG("Trying to receive data using closed connection");
+
+ return -1;
+ }
+
+ BIO* sslBio0 = reinterpret_cast<BIO*>(sslBio);
+
+ int res = 0;
+
+ if (!blocking && BIO_pending_(sslBio0) == 0)
+ {
+ res = WaitOnSocket(timeout, true);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ return res;
+ }
+
+ do
+ {
+ res = ssl::BIO_read(sslBio0, buffer, static_cast<int>(size));
+ }
+ while (ssl::BIO_should_retry_(sslBio0));
+
+ return res;
+ }
+
+ bool SecureSocketClient::IsBlocking() const
+ {
+ return blocking;
+ }
+
+ void* SecureSocketClient::MakeContext(const std::string& certPath, const std::string& keyPath,
+ const std::string& caPath, diagnostic::Diagnosable& diag)
+ {
+ assert(SslGateway::GetInstance().Loaded());
+
+ static bool sslLibInited = false;
+ static common::concurrent::CriticalSection sslCs;
+
+ if (!sslLibInited)
+ {
+ common::concurrent::CsLockGuard lock(sslCs);
+
+ if (!sslLibInited)
+ {
+ LOG_MSG("Initializing SSL library");
+
+ (void)SSL_library_init();
+
+ SSL_load_error_strings();
+
+ OPENSSL_config(0);
+
+ sslLibInited = true;
+ }
+ }
+
+ const SSL_METHOD* method = SSLv23_method();
+ if (!method)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new SSL method.");
+
+ return 0;
+ }
+
+ SSL_CTX* ctx = ssl::SSL_CTX_new(method);
+ if (!ctx)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new SSL context.");
+
+ return 0;
+ }
+
+ ssl::SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
+
+ ssl::SSL_CTX_set_verify_depth(ctx, 8);
+
+ const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
+ ssl::SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, flags, NULL);
+
+ const char* cCaPath = caPath.empty() ? 0 : caPath.c_str();
+
+ long res = ssl::SSL_CTX_load_verify_locations(ctx, cCaPath, 0);
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not set Certificate Authority path for secure connection.");
+
+ ssl::SSL_CTX_free(ctx);
+
+ return 0;
+ }
+
+ res = ssl::SSL_CTX_use_certificate_chain_file(ctx, certPath.c_str());
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not set client certificate file for secure connection.");
+
+ ssl::SSL_CTX_free(ctx);
+
+ return 0;
+ }
+
+ res = ssl::SSL_CTX_use_RSAPrivateKey_file(ctx, keyPath.c_str(), SSL_FILETYPE_PEM);
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not set private key file for secure connection.");
+
+ ssl::SSL_CTX_free(ctx);
+
+ return 0;
+ }
+
+ const char* const PREFERRED_CIPHERS = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
+ res = ssl::SSL_CTX_set_cipher_list(ctx, PREFERRED_CIPHERS);
+ if (res != OPERATION_SUCCESS)
+ {
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
+ "Can not set ciphers list for secure connection.");
+
+ ssl::SSL_CTX_free(ctx);
+
+ return 0;
+ }
+
+ return ctx;
+ }
+
+ void SecureSocketClient::CloseInteral()
+ {
+ assert(SslGateway::GetInstance().Loaded());
+
+ if (sslBio)
+ {
+ ssl::BIO_free_all(reinterpret_cast<BIO*>(sslBio));
+
+ sslBio = 0;
+ }
+ }
+
+ int SecureSocketClient::WaitOnSocket(int32_t timeout, bool rd)
+ {
+ int ready = 0;
+ int lastError = 0;
+ int fdSocket = 0;
+ BIO* sslBio0 = reinterpret_cast<BIO*>(sslBio);
+
+ fd_set fds;
+
+ long res = ssl::BIO_get_fd_(sslBio0, &fdSocket);
+
+ if (res < 0)
+ {
+ LOG_MSG("Can not get file descriptor from the SSL socket: " << res);
+
+ return res;
+ }
+
+ do {
+ struct timeval tv = { 0 };
+ tv.tv_sec = timeout;
+
+ FD_ZERO(&fds);
+ FD_SET(static_cast<long>(fdSocket), &fds);
+
+ fd_set* readFds = 0;
+ fd_set* writeFds = 0;
+
+ if (rd)
+ readFds = &fds;
+ else
+ writeFds = &fds;
+
+ ready = select(fdSocket + 1, readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv));
+
+ if (ready == SOCKET_ERROR)
+ lastError = system::TcpSocketClient::GetLastSocketError();
+
+ } while (ready == SOCKET_ERROR && system::TcpSocketClient::IsSocketOperationInterrupted(lastError));
+
+ if (ready == SOCKET_ERROR)
+ return -lastError;
+
+ lastError = system::TcpSocketClient::GetLastSocketError(fdSocket);
+
+ if (lastError != 0)
+ return -lastError;
+
+ if (ready == 0)
+ return WaitResult::TIMEOUT;
+
+ return WaitResult::SUCCESS;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/ssl/ssl_gateway.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/ssl/ssl_gateway.cpp b/modules/platforms/cpp/odbc/src/ssl/ssl_gateway.cpp
new file mode 100644
index 0000000..c91d44e
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/ssl/ssl_gateway.cpp
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+
+#include <openssl/ssl.h>
+#include <openssl/conf.h>
+
+#include "ignite/common/utils.h"
+
+#include "ignite/odbc/ssl/ssl_gateway.h"
+#include "ignite/odbc/log.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ SslGateway::SslGateway() :
+ inited(false),
+ functions()
+ {
+ // No-op.
+ }
+
+ SslGateway::~SslGateway()
+ {
+ // No-op.
+ }
+
+ common::dynamic::Module SslGateway::LoadSslLibrary(const char* name)
+ {
+ using namespace common;
+ using namespace dynamic;
+
+ std::string fullName = GetDynamicLibraryName(name);
+
+ Module libModule = LoadModule(fullName);
+
+ if (libModule.IsLoaded())
+ return libModule;
+
+ std::string home = GetEnv("OPEN_SSL_HOME");
+
+ if (home.empty())
+ home = GetEnv("OPENSSL_HOME");
+
+ if (home.empty())
+ return libModule;
+
+ std::stringstream constructor;
+
+ constructor << home << Fs << "bin" << Fs << fullName;
+
+ std::string fullPath = constructor.str();
+
+ return LoadModule(fullPath);
+ }
+
+ bool SslGateway::LoadSslLibraries()
+ {
+ libeay32 = LoadSslLibrary("libeay32");
+ ssleay32 = LoadSslLibrary("ssleay32");
+ libssl = LoadSslLibrary("libssl");
+
+ if (!libssl.IsLoaded() && (!libeay32.IsLoaded() || !ssleay32.IsLoaded()))
+ {
+ if (!libeay32.IsLoaded())
+ LOG_MSG("Can not load libeay32.");
+
+ if (!ssleay32.IsLoaded())
+ LOG_MSG("Can not load ssleay32.");
+
+ if (!libssl.IsLoaded())
+ LOG_MSG("Can not load libssl.");
+
+ libeay32.Unload();
+ ssleay32.Unload();
+ libssl.Unload();
+
+ return false;
+ }
+
+ return true;
+ }
+
+ SslGateway& SslGateway::GetInstance()
+ {
+ static SslGateway self;
+
+ return self;
+ }
+
+ bool SslGateway::LoadAll()
+ {
+ using namespace common::dynamic;
+
+ if (inited)
+ return true;
+
+ common::concurrent::CsLockGuard lock(initCs);
+
+ if (inited)
+ return true;
+
+ if (!LoadSslLibraries())
+ {
+ LOG_MSG("Can not load neccessary OpenSSL libraries.");
+
+ return false;
+ }
+
+ functions.fpSSL_CTX_new = LoadSslMethod("SSL_CTX_new");
+ functions.fpSSL_CTX_free = LoadSslMethod("SSL_CTX_free");
+ functions.fpSSL_CTX_set_verify = LoadSslMethod("SSL_CTX_set_verify");
+ functions.fpSSL_CTX_set_verify_depth = LoadSslMethod("SSL_CTX_set_verify_depth");
+ functions.fpSSL_CTX_load_verify_locations = LoadSslMethod("SSL_CTX_load_verify_locations");
+ functions.fpSSL_CTX_use_certificate_chain_file = LoadSslMethod("SSL_CTX_use_certificate_chain_file");
+ functions.fpSSL_CTX_use_RSAPrivateKey_file = LoadSslMethod("SSL_CTX_use_RSAPrivateKey_file");
+ functions.fpSSL_CTX_set_cipher_list = LoadSslMethod("SSL_CTX_set_cipher_list");
+
+ functions.fpSSL_get_verify_result = LoadSslMethod("SSL_get_verify_result");
+ functions.fpSSL_library_init = LoadSslMethod("SSL_library_init");
+ functions.fpSSL_load_error_strings = LoadSslMethod("SSL_load_error_strings");
+ functions.fpSSL_get_peer_certificate = LoadSslMethod("SSL_get_peer_certificate");
+ functions.fpSSL_ctrl = LoadSslMethod("SSL_ctrl");
+ functions.fpSSL_CTX_ctrl = LoadSslMethod("SSL_CTX_ctrl");
+
+ functions.fpSSLv23_method = LoadSslMethod("SSLv23_method");
+ functions.fpBIO_new_ssl_connect = LoadSslMethod("BIO_new_ssl_connect");
+
+ functions.fpOPENSSL_config = LoadSslMethod("OPENSSL_config");
+ functions.fpX509_free = LoadSslMethod("X509_free");
+
+ functions.fpBIO_write = LoadSslMethod("BIO_write");
+ functions.fpBIO_read = LoadSslMethod("BIO_read");
+ functions.fpBIO_free_all = LoadSslMethod("BIO_free_all");
+ functions.fpBIO_test_flags = LoadSslMethod("BIO_test_flags");
+ functions.fpBIO_ctrl = LoadSslMethod("BIO_ctrl");
+
+ bool allLoaded =
+ functions.fpSSL_CTX_new != 0 &&
+ functions.fpSSL_CTX_free != 0 &&
+ functions.fpSSL_CTX_set_verify != 0 &&
+ functions.fpSSL_CTX_set_verify_depth != 0 &&
+ functions.fpSSL_CTX_load_verify_locations != 0 &&
+ functions.fpSSL_CTX_use_certificate_chain_file != 0 &&
+ functions.fpSSL_CTX_use_RSAPrivateKey_file != 0 &&
+ functions.fpSSL_CTX_set_cipher_list != 0 &&
+ functions.fpSSL_get_verify_result != 0 &&
+ functions.fpSSL_library_init != 0 &&
+ functions.fpSSL_load_error_strings != 0 &&
+ functions.fpSSL_get_peer_certificate != 0 &&
+ functions.fpSSL_ctrl != 0 &&
+ functions.fpSSL_CTX_ctrl != 0 &&
+ functions.fpSSLv23_method != 0 &&
+ functions.fpBIO_new_ssl_connect != 0 &&
+ functions.fpOPENSSL_config != 0 &&
+ functions.fpX509_free != 0 &&
+ functions.fpBIO_write != 0 &&
+ functions.fpBIO_read != 0 &&
+ functions.fpBIO_free_all != 0 &&
+ functions.fpBIO_test_flags != 0 &&
+ functions.fpBIO_ctrl != 0;
+
+ if (!allLoaded)
+ {
+ libeay32.Unload();
+ ssleay32.Unload();
+ libssl.Unload();
+ }
+
+ inited = allLoaded;
+
+ return inited;
+ }
+
+ void* SslGateway::LoadSslMethod(const char* name)
+ {
+ void* fp = libeay32.FindSymbol(name);
+
+ if (!fp)
+ fp = ssleay32.FindSymbol(name);
+
+ if (!fp)
+ fp = libssl.FindSymbol(name);
+
+ if (!fp)
+ LOG_MSG("Can not load function " << name);
+
+ return fp;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/ssl/ssl_mode.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/ssl/ssl_mode.cpp b/modules/platforms/cpp/odbc/src/ssl/ssl_mode.cpp
new file mode 100644
index 0000000..0bdbc60
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/ssl/ssl_mode.cpp
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/common/utils.h"
+#include "ignite/odbc/ssl/ssl_mode.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ SslMode::T SslMode::FromString(const std::string& val, T dflt)
+ {
+ std::string lowerVal = common::ToLower(val);
+
+ common::StripSurroundingWhitespaces(lowerVal);
+
+ if (lowerVal == "disable")
+ return SslMode::DISABLE;
+
+ if (lowerVal == "require")
+ return SslMode::REQUIRE;
+
+ return dflt;
+ }
+ }
+ }
+}
[2/4] ignite git commit: IGNITE-6810: Implemented SSL support for
ODBC.
Posted by is...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/linux/src/system/tcp_socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/linux/src/system/tcp_socket_client.cpp b/modules/platforms/cpp/odbc/os/linux/src/system/tcp_socket_client.cpp
new file mode 100644
index 0000000..f145361
--- /dev/null
+++ b/modules/platforms/cpp/odbc/os/linux/src/system/tcp_socket_client.cpp
@@ -0,0 +1,384 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <cstring>
+
+#include <sstream>
+
+#include "ignite/odbc/system/tcp_socket_client.h"
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/log.h"
+
+#define SOCKET_ERROR (-1)
+
+namespace
+{
+ /**
+ * Get last socket error message.
+ * @param error Error code.
+ * @return Last socket error message string.
+ */
+ std::string GetSocketErrorMessage(int error)
+ {
+ std::stringstream res;
+
+ res << "error_code=" << error;
+
+ if (error == 0)
+ return res.str();
+
+ char buffer[1024] = "";
+
+ if (!strerror_r(error, buffer, sizeof(buffer)))
+ res << ", msg=" << buffer;
+
+ return res.str();
+ }
+
+ /**
+ * Get last socket error message.
+ * @return Last socket error message string.
+ */
+ std::string GetLastSocketErrorMessage()
+ {
+ int lastError = errno;
+
+ return GetSocketErrorMessage(lastError);
+ }
+}
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace system
+ {
+
+ TcpSocketClient::TcpSocketClient() :
+ socketHandle(SOCKET_ERROR),
+ blocking(true)
+ {
+ // No-op.
+ }
+
+ TcpSocketClient::~TcpSocketClient()
+ {
+ Close();
+ }
+
+ bool TcpSocketClient::Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag)
+ {
+ LOG_MSG("Host: " << hostname << ", port: " << port);
+
+ addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ std::stringstream converter;
+ converter << port;
+
+ // Resolve the server address and port
+ addrinfo *result = NULL;
+ int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result);
+
+ if (res != 0)
+ {
+ LOG_MSG("Address resolving failed: " << gai_strerror(res));
+
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not resolve host address.");
+
+ return false;
+ }
+
+ // Attempt to connect to an address until one succeeds
+ for (addrinfo *it = result; it != NULL; it = it->ai_next)
+ {
+ LOG_MSG("Addr: " << (it->ai_addr->sa_data[2] & 0xFF) << "."
+ << (it->ai_addr->sa_data[3] & 0xFF) << "."
+ << (it->ai_addr->sa_data[4] & 0xFF) << "."
+ << (it->ai_addr->sa_data[5] & 0xFF));
+
+ // Create a SOCKET for connecting to server
+ socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
+
+ if (socketHandle == SOCKET_ERROR)
+ {
+ LOG_MSG("Socket creation failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new socket.");
+
+ return false;
+ }
+
+ diag.GetDiagnosticRecords().Reset();
+
+ TrySetOptions(diag);
+
+ // Connect to server.
+ res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen));
+ if (SOCKET_ERROR == res)
+ {
+ int lastError = errno;
+
+ if (lastError != EWOULDBLOCK && lastError != EINPROGRESS)
+ {
+ LOG_MSG("Connection failed: " << GetSocketErrorMessage(lastError));
+
+ Close();
+
+ continue;
+ }
+
+ res = WaitOnSocket(CONNECT_TIMEOUT, false);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ {
+ LOG_MSG("Connection timeout expired: " << GetSocketErrorMessage(-res));
+
+ Close();
+
+ continue;
+ }
+ }
+ break;
+ }
+
+ freeaddrinfo(result);
+
+ return socketHandle != SOCKET_ERROR;
+ }
+
+ void TcpSocketClient::Close()
+ {
+ if (socketHandle != SOCKET_ERROR)
+ {
+ close(socketHandle);
+
+ socketHandle = SOCKET_ERROR;
+ }
+ }
+
+ int TcpSocketClient::Send(const int8_t* data, size_t size, int32_t timeout)
+ {
+ if (!blocking)
+ {
+ int res = WaitOnSocket(timeout, false);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ return res;
+ }
+
+ return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0);
+ }
+
+ int TcpSocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout)
+ {
+ if (!blocking)
+ {
+ int res = WaitOnSocket(timeout, true);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ return res;
+ }
+
+ return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0);
+ }
+
+ bool TcpSocketClient::IsBlocking() const
+ {
+ return blocking;
+ }
+
+ void TcpSocketClient::TrySetOptions(diagnostic::Diagnosable& diag)
+ {
+ int trueOpt = 1;
+ int bufSizeOpt = BUFFER_SIZE;
+ int idleOpt = KEEP_ALIVE_IDLE_TIME;
+ int idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD;
+
+ int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF,
+ reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP socket send buffer size setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP socket send buffer size");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF,
+ reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP socket receive buffer size setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP socket receive buffer size");
+ }
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP no-delay mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP no-delay mode");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP out-of-bound data inlining setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP out-of-bound data inlining");
+ }
+
+ blocking = false;
+
+ int flags;
+ if (((flags = fcntl(socketHandle, F_GETFL, 0)) < 0) ||
+ (fcntl(socketHandle, F_SETFL, flags | O_NONBLOCK) < 0))
+ {
+ blocking = true;
+ LOG_MSG("Non-blocking mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up non-blocking mode. Timeouts are not available.");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive mode");
+
+ // There is no sense in configuring keep alive params if we faileed to set up keep alive mode.
+ return;
+ }
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE,
+ reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive idle timeout setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive idle timeout");
+ }
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL,
+ reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive probes period setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive probes period");
+ }
+
+ }
+
+ int TcpSocketClient::WaitOnSocket(int32_t timeout, bool rd)
+ {
+ int ready = 0;
+ int lastError = 0;
+
+ fd_set fds;
+
+ do {
+ struct timeval tv = { 0 };
+ tv.tv_sec = timeout;
+
+ FD_ZERO(&fds);
+ FD_SET(socketHandle, &fds);
+
+ fd_set* readFds = 0;
+ fd_set* writeFds = 0;
+
+ if (rd)
+ readFds = &fds;
+ else
+ writeFds = &fds;
+
+ ready = select(static_cast<int>((socketHandle) + 1),
+ readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv));
+
+ if (ready == SOCKET_ERROR)
+ lastError = GetLastSocketError();
+
+ } while (ready == SOCKET_ERROR && IsSocketOperationInterrupted(lastError));
+
+ if (ready == SOCKET_ERROR)
+ return -lastError;
+
+ socklen_t size = sizeof(lastError);
+ int res = getsockopt(socketHandle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size);
+
+ if (res != SOCKET_ERROR && lastError != 0)
+ return -lastError;
+
+ if (ready == 0)
+ return WaitResult::TIMEOUT;
+
+ return WaitResult::SUCCESS;
+ }
+
+ int TcpSocketClient::GetLastSocketError()
+ {
+ return errno;
+ }
+
+ int TcpSocketClient::GetLastSocketError(int handle)
+ {
+ int lastError = 0;
+ socklen_t size = sizeof(lastError);
+ int res = getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size);
+
+ return res == SOCKET_ERROR ? 0 : lastError;
+ }
+
+ bool TcpSocketClient::IsSocketOperationInterrupted(int errorCode)
+ {
+ return errorCode == EINTR;
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp b/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
deleted file mode 100644
index 6f87b93..0000000
--- a/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp
+++ /dev/null
@@ -1,432 +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.
- */
-
-#define WIN32_LEAN_AND_MEAN
-#define _WINSOCKAPI_
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <mstcpip.h>
-
-#include <cstring>
-
-#include <sstream>
-
-#include "ignite/odbc/system/socket_client.h"
-#include "ignite/odbc/utility.h"
-#include "ignite/odbc/log.h"
-
-namespace
-{
- /**
- * Get socket error message for the error code.
- * @param error Error code.
- * @return Socket error message string.
- */
- std::string GetSocketErrorMessage(HRESULT error)
- {
- std::stringstream res;
-
- res << "error_code=" << error;
-
- if (error == 0)
- return res.str();
-
- LPTSTR errorText = NULL;
-
- DWORD len = FormatMessage(
- // use system message tables to retrieve error text
- FORMAT_MESSAGE_FROM_SYSTEM
- // allocate buffer on local heap for error text
- | FORMAT_MESSAGE_ALLOCATE_BUFFER
- // We're not passing insertion parameters
- | FORMAT_MESSAGE_IGNORE_INSERTS,
- // unused with FORMAT_MESSAGE_FROM_SYSTEM
- NULL,
- error,
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- // output
- reinterpret_cast<LPTSTR>(&errorText),
- // minimum size for output buffer
- 0,
- // arguments - see note
- NULL);
-
- if (NULL != errorText)
- {
- if (len != 0)
- res << ", msg=" << std::string(errorText, len);
-
- LocalFree(errorText);
- }
-
- return res.str();
- }
-
- /**
- * Get last socket error message.
- * @return Last socket error message string.
- */
- std::string GetLastSocketErrorMessage()
- {
- HRESULT lastError = WSAGetLastError();
-
- return GetSocketErrorMessage(lastError);
- }
-}
-
-namespace ignite
-{
- namespace odbc
- {
- namespace tcp
- {
-
- SocketClient::SocketClient() :
- socketHandle(INVALID_SOCKET),
- blocking(true)
- {
- // No-op.
- }
-
- SocketClient::~SocketClient()
- {
- Close();
- }
-
- bool SocketClient::Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag)
- {
- static bool networkInited = false;
-
- // Initing networking if is not inited.
- if (!networkInited)
- {
- WSADATA wsaData;
-
- networkInited = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0);
-
- if (!networkInited)
- {
- LOG_MSG("Networking initialisation failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not initialize Windows networking.");
-
- return false;
- }
- }
-
- addrinfo hints;
-
- LOG_MSG("Host: " << hostname << " port: " << port);
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- std::stringstream converter;
- converter << port;
-
- // Resolve the server address and port
- addrinfo *result = NULL;
- int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result);
-
- if (res != 0)
- {
- LOG_MSG("Address resolving failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not resolve host address.");
-
- return false;
- }
-
- // Attempt to connect to an address until one succeeds
- for (addrinfo *it = result; it != NULL; it = it->ai_next)
- {
- LOG_MSG("Addr: " << (it->ai_addr->sa_data[2] & 0xFF) << "."
- << (it->ai_addr->sa_data[3] & 0xFF) << "."
- << (it->ai_addr->sa_data[4] & 0xFF) << "."
- << (it->ai_addr->sa_data[5] & 0xFF));
-
- // Create a SOCKET for connecting to server
- socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
-
- if (socketHandle == INVALID_SOCKET)
- {
- LOG_MSG("Socket creation failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new socket.");
-
- return false;
- }
-
- diag.GetDiagnosticRecords().Reset();
-
- TrySetOptions(diag);
-
- // Connect to server.
- res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen));
- if (SOCKET_ERROR == res)
- {
- int lastError = WSAGetLastError();
-
- if (lastError != WSAEWOULDBLOCK)
- {
- LOG_MSG("Connection failed: " << GetSocketErrorMessage(lastError));
-
- Close();
-
- continue;
- }
-
- res = WaitOnSocket(CONNECT_TIMEOUT, false);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- {
- LOG_MSG("Connection timeout expired: " << GetSocketErrorMessage(-res));
-
- Close();
-
- continue;
- }
- }
- break;
- }
-
- freeaddrinfo(result);
-
- return socketHandle != INVALID_SOCKET;
- }
-
- void SocketClient::Close()
- {
- if (socketHandle != INVALID_SOCKET)
- {
- closesocket(socketHandle);
-
- socketHandle = INVALID_SOCKET;
- }
- }
-
- int SocketClient::Send(const int8_t* data, size_t size, int32_t timeout)
- {
- if (!blocking)
- {
- int res = WaitOnSocket(timeout, false);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- return res;
- }
-
- return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0);
- }
-
- int SocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout)
- {
- if (!blocking)
- {
- int res = WaitOnSocket(timeout, true);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- return res;
- }
-
- return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0);
- }
-
- void SocketClient::TrySetOptions(diagnostic::Diagnosable& diag)
- {
- BOOL trueOpt = TRUE;
- ULONG uTrueOpt = TRUE;
- int bufSizeOpt = BUFFER_SIZE;
-
-
- int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF,
- reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP socket send buffer size setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP socket send buffer size");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF,
- reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP socket receive buffer size setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP socket receive buffer size");
- }
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP no-delay mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP no-delay mode");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP out-of-bound data inlining setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP out-of-bound data inlining");
- }
-
- blocking = false;
- res = ioctlsocket(socketHandle, FIONBIO, &uTrueOpt);
-
- if (res == SOCKET_ERROR)
- {
- blocking = true;
- LOG_MSG("Non-blocking mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up non-blocking mode. Timeouts are not available.");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive mode");
-
- // There is no sense in configuring keep alive params if we faileed to set up keep alive mode.
- return;
- }
-
- // This option is available starting with Windows 10, version 1709.
-#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
- DWORD idleOpt = KEEP_ALIVE_IDLE_TIME;
- DWORD idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD;
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE,
- reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive idle timeout setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive idle timeout");
- }
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL,
- reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive probes period setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive probes period");
- }
-#else // use old hardcore WSAIoctl
-
- // WinSock structure for KeepAlive timing settings
- struct tcp_keepalive settings = {0};
- settings.onoff = 1;
- settings.keepalivetime = KEEP_ALIVE_IDLE_TIME * 1000;
- settings.keepaliveinterval = KEEP_ALIVE_PROBES_PERIOD * 1000;
-
- // pointers for WinSock call
- DWORD bytesReturned;
- WSAOVERLAPPED overlapped;
- overlapped.hEvent = NULL;
-
- // Set KeepAlive settings
- res = WSAIoctl(
- socketHandle,
- SIO_KEEPALIVE_VALS,
- &settings,
- sizeof(struct tcp_keepalive),
- NULL,
- 0,
- &bytesReturned,
- &overlapped,
- NULL
- );
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive params setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive idle timeout and probes period");
- }
-#endif
- }
-
- int SocketClient::WaitOnSocket(int32_t timeout, bool rd)
- {
- int ready = 0;
- int lastError = 0;
-
- fd_set fds;
-
- do {
- struct timeval tv = { 0 };
- tv.tv_sec = timeout;
-
- FD_ZERO(&fds);
- FD_SET(socketHandle, &fds);
-
- fd_set* readFds = 0;
- fd_set* writeFds = 0;
-
- if (rd)
- readFds = &fds;
- else
- writeFds = &fds;
-
- ready = select(static_cast<int>((socketHandle) + 1),
- readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv));
-
- if (ready == SOCKET_ERROR)
- lastError = WSAGetLastError();
-
- } while (ready == SOCKET_ERROR && lastError == WSAEINTR);
-
- if (ready == SOCKET_ERROR)
- return -lastError;
-
- if (ready == 0)
- return WaitResult::TIMEOUT;
-
- return WaitResult::SUCCESS;
- }
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/win/src/system/tcp_socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/tcp_socket_client.cpp b/modules/platforms/cpp/odbc/os/win/src/system/tcp_socket_client.cpp
new file mode 100644
index 0000000..1459a17
--- /dev/null
+++ b/modules/platforms/cpp/odbc/os/win/src/system/tcp_socket_client.cpp
@@ -0,0 +1,462 @@
+/*
+ * 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.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define _WINSOCKAPI_
+
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <mstcpip.h>
+
+#include <cstring>
+
+#include <sstream>
+
+#include "ignite/common/concurrent.h"
+#include "ignite/odbc/system/tcp_socket_client.h"
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/log.h"
+
+namespace
+{
+ /**
+ * Get socket error message for the error code.
+ * @param error Error code.
+ * @return Socket error message string.
+ */
+ std::string GetSocketErrorMessage(HRESULT error)
+ {
+ std::stringstream res;
+
+ res << "error_code=" << error;
+
+ if (error == 0)
+ return res.str();
+
+ LPTSTR errorText = NULL;
+
+ DWORD len = FormatMessage(
+ // use system message tables to retrieve error text
+ FORMAT_MESSAGE_FROM_SYSTEM
+ // allocate buffer on local heap for error text
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER
+ // We're not passing insertion parameters
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ // unused with FORMAT_MESSAGE_FROM_SYSTEM
+ NULL,
+ error,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ // output
+ reinterpret_cast<LPTSTR>(&errorText),
+ // minimum size for output buffer
+ 0,
+ // arguments - see note
+ NULL);
+
+ if (NULL != errorText)
+ {
+ if (len != 0)
+ res << ", msg=" << std::string(errorText, len);
+
+ LocalFree(errorText);
+ }
+
+ return res.str();
+ }
+
+ /**
+ * Get last socket error message.
+ * @return Last socket error message string.
+ */
+ std::string GetLastSocketErrorMessage()
+ {
+ HRESULT lastError = WSAGetLastError();
+
+ return GetSocketErrorMessage(lastError);
+ }
+}
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace system
+ {
+
+ TcpSocketClient::TcpSocketClient() :
+ socketHandle(INVALID_SOCKET),
+ blocking(true)
+ {
+ // No-op.
+ }
+
+ TcpSocketClient::~TcpSocketClient()
+ {
+ Close();
+ }
+
+ bool TcpSocketClient::Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag)
+ {
+ static common::concurrent::CriticalSection initCs;
+ static bool networkInited = false;
+
+ // Initing networking if is not inited.
+ if (!networkInited)
+ {
+ common::concurrent::CsLockGuard lock(initCs);
+ if (!networkInited)
+ {
+ WSADATA wsaData;
+
+ networkInited = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0);
+
+ if (!networkInited)
+ {
+ LOG_MSG("Networking initialisation failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not initialize Windows networking.");
+
+ return false;
+ }
+ }
+ }
+
+ addrinfo hints;
+
+ LOG_MSG("Host: " << hostname << " port: " << port);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ std::stringstream converter;
+ converter << port;
+
+ // Resolve the server address and port
+ addrinfo *result = NULL;
+ int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result);
+
+ if (res != 0)
+ {
+ LOG_MSG("Address resolving failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not resolve host address.");
+
+ return false;
+ }
+
+ // Attempt to connect to an address until one succeeds
+ for (addrinfo *it = result; it != NULL; it = it->ai_next)
+ {
+ LOG_MSG("Addr: " << (it->ai_addr->sa_data[2] & 0xFF) << "."
+ << (it->ai_addr->sa_data[3] & 0xFF) << "."
+ << (it->ai_addr->sa_data[4] & 0xFF) << "."
+ << (it->ai_addr->sa_data[5] & 0xFF));
+
+ // Create a SOCKET for connecting to server
+ socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
+
+ if (socketHandle == INVALID_SOCKET)
+ {
+ LOG_MSG("Socket creation failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new socket.");
+
+ return false;
+ }
+
+ diag.GetDiagnosticRecords().Reset();
+
+ TrySetOptions(diag);
+
+ // Connect to server.
+ res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen));
+ if (SOCKET_ERROR == res)
+ {
+ int lastError = WSAGetLastError();
+
+ if (lastError != WSAEWOULDBLOCK)
+ {
+ LOG_MSG("Connection failed: " << GetSocketErrorMessage(lastError));
+
+ Close();
+
+ continue;
+ }
+
+ res = WaitOnSocket(CONNECT_TIMEOUT, false);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ {
+ LOG_MSG("Connection timeout expired: " << GetSocketErrorMessage(-res));
+
+ Close();
+
+ continue;
+ }
+ }
+ break;
+ }
+
+ freeaddrinfo(result);
+
+ return socketHandle != INVALID_SOCKET;
+ }
+
+ void TcpSocketClient::Close()
+ {
+ if (socketHandle != INVALID_SOCKET)
+ {
+ closesocket(socketHandle);
+
+ socketHandle = INVALID_SOCKET;
+ }
+ }
+
+ int TcpSocketClient::Send(const int8_t* data, size_t size, int32_t timeout)
+ {
+ if (!blocking)
+ {
+ int res = WaitOnSocket(timeout, false);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ return res;
+ }
+
+ return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0);
+ }
+
+ int TcpSocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout)
+ {
+ if (!blocking)
+ {
+ int res = WaitOnSocket(timeout, true);
+
+ if (res < 0 || res == WaitResult::TIMEOUT)
+ return res;
+ }
+
+ return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0);
+ }
+
+ bool TcpSocketClient::IsBlocking() const
+ {
+ return blocking;
+ }
+
+ void TcpSocketClient::TrySetOptions(diagnostic::Diagnosable& diag)
+ {
+ BOOL trueOpt = TRUE;
+ ULONG uTrueOpt = TRUE;
+ int bufSizeOpt = BUFFER_SIZE;
+
+
+ int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF,
+ reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP socket send buffer size setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP socket send buffer size");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF,
+ reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP socket receive buffer size setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP socket receive buffer size");
+ }
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP no-delay mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP no-delay mode");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP out-of-bound data inlining setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP out-of-bound data inlining");
+ }
+
+ blocking = false;
+ res = ioctlsocket(socketHandle, FIONBIO, &uTrueOpt);
+
+ if (res == SOCKET_ERROR)
+ {
+ blocking = true;
+ LOG_MSG("Non-blocking mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up non-blocking mode. Timeouts are not available.");
+ }
+
+ res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE,
+ reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive mode setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive mode");
+
+ // There is no sense in configuring keep alive params if we faileed to set up keep alive mode.
+ return;
+ }
+
+ // This option is available starting with Windows 10, version 1709.
+#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL)
+ DWORD idleOpt = KEEP_ALIVE_IDLE_TIME;
+ DWORD idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD;
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE,
+ reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive idle timeout setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive idle timeout");
+ }
+
+ res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL,
+ reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt));
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive probes period setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive probes period");
+ }
+#else // use old hardcore WSAIoctl
+
+ // WinSock structure for KeepAlive timing settings
+ struct tcp_keepalive settings = {0};
+ settings.onoff = 1;
+ settings.keepalivetime = KEEP_ALIVE_IDLE_TIME * 1000;
+ settings.keepaliveinterval = KEEP_ALIVE_PROBES_PERIOD * 1000;
+
+ // pointers for WinSock call
+ DWORD bytesReturned;
+ WSAOVERLAPPED overlapped;
+ overlapped.hEvent = NULL;
+
+ // Set KeepAlive settings
+ res = WSAIoctl(
+ socketHandle,
+ SIO_KEEPALIVE_VALS,
+ &settings,
+ sizeof(struct tcp_keepalive),
+ NULL,
+ 0,
+ &bytesReturned,
+ &overlapped,
+ NULL
+ );
+
+ if (SOCKET_ERROR == res)
+ {
+ LOG_MSG("TCP keep-alive params setup failed: " << GetLastSocketErrorMessage());
+
+ diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Can not set up TCP keep-alive idle timeout and probes period");
+ }
+#endif
+ }
+
+ int TcpSocketClient::WaitOnSocket(int32_t timeout, bool rd)
+ {
+ int ready = 0;
+ int lastError = 0;
+
+ fd_set fds;
+
+ do {
+ struct timeval tv = { 0 };
+ tv.tv_sec = timeout;
+
+ FD_ZERO(&fds);
+ FD_SET(socketHandle, &fds);
+
+ fd_set* readFds = 0;
+ fd_set* writeFds = 0;
+
+ if (rd)
+ readFds = &fds;
+ else
+ writeFds = &fds;
+
+ ready = select(static_cast<int>((socketHandle) + 1),
+ readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv));
+
+ if (ready == SOCKET_ERROR)
+ lastError = GetLastSocketError();
+
+ } while (ready == SOCKET_ERROR && IsSocketOperationInterrupted(lastError));
+
+ if (ready == SOCKET_ERROR)
+ return -lastError;
+
+ if (ready == 0)
+ return WaitResult::TIMEOUT;
+
+ return WaitResult::SUCCESS;
+ }
+
+ int TcpSocketClient::GetLastSocketError()
+ {
+ return WSAGetLastError();
+ }
+
+ int TcpSocketClient::GetLastSocketError(int handle)
+ {
+ int lastError = 0;
+ socklen_t size = sizeof(lastError);
+ int res = getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size);
+
+ return res == SOCKET_ERROR ? 0 : lastError;
+ }
+
+ bool TcpSocketClient::IsSocketOperationInterrupted(int errorCode)
+ {
+ return errorCode == WSAEINTR;
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
index d5aa0db..0e742be 100644
--- a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
+++ b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
@@ -16,8 +16,10 @@
*/
#include <Windowsx.h>
+#include <Shlwapi.h>
#include "ignite/odbc/log.h"
+#include "ignite/odbc/ssl/ssl_mode.h"
#include "ignite/odbc/system/ui/dsn_configuration_window.h"
@@ -32,7 +34,7 @@ namespace ignite
DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config):
CustomWindow(parent, "IgniteConfigureDsn", "Configure Apache Ignite DSN"),
width(360),
- height(300),
+ height(480),
connectionSettingsGroupBox(),
nameLabel(),
nameEdit(),
@@ -89,53 +91,56 @@ namespace ignite
void DsnConfigurationWindow::OnCreate()
{
- int margin = 10;
- int interval = 10;
+ int groupPosY = MARGIN;
+ int groupSizeY = width - 2 * MARGIN;
- int labelSizeX = 80;
- int labelPosX = margin + interval;
+ groupPosY += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosY, groupSizeY);
+ groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY);
+ groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY);
- int editSizeX = width - labelSizeX - 2 * margin - 3 * interval;
- int editPosX = margin + labelSizeX + 2 * interval;
+ int cancelPosX = width - MARGIN - BUTTON_WIDTH;
+ int okPosX = cancelPosX - INTERVAL - BUTTON_WIDTH;
- int rowSize = 20;
- int rowPos = margin + 2 * interval;
+ okButton = CreateButton(okPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON);
+ cancelButton = CreateButton(cancelPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT,
+ "Cancel", ChildId::CANCEL_BUTTON);
+ }
+
+ int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, int sizeX)
+ {
+ enum { LABEL_WIDTH = 100 };
+
+ int labelPosX = posX + INTERVAL;
- int checkBoxSize = (editSizeX - interval) / 2;
+ int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL;
+ int editPosX = labelPosX + LABEL_WIDTH + INTERVAL;
- int sectionBegin = margin;
+ int rowPos = posY + 2 * INTERVAL;
const char* val = config.GetDsn().c_str();
- nameLabel = CreateLabel(labelPosX, rowPos, labelSizeX, rowSize, "DSN name:", ChildId::NAME_LABEL);
- nameEdit = CreateEdit(editPosX, rowPos, editSizeX, rowSize, val, ChildId::NAME_EDIT);
+ nameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
+ "Data Source Name:", ChildId::NAME_LABEL);
+ nameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::NAME_EDIT);
- rowPos += interval + rowSize;
+ rowPos += INTERVAL + ROW_HEIGHT;
val = config.GetAddress().c_str();
- addressLabel = CreateLabel(labelPosX, rowPos, labelSizeX, rowSize, "Address:", ChildId::ADDRESS_LABEL);
- addressEdit = CreateEdit(editPosX, rowPos, editSizeX, rowSize, val, ChildId::ADDRESS_EDIT);
+ addressLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
+ "Address:", ChildId::ADDRESS_LABEL);
+ addressEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::ADDRESS_EDIT);
- rowPos += interval + rowSize;
+ rowPos += INTERVAL + ROW_HEIGHT;
val = config.GetSchema().c_str();
- schemaLabel = CreateLabel(labelPosX, rowPos, labelSizeX, rowSize, "Schema name:", ChildId::SCHEMA_LABEL);
- schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, rowSize, val, ChildId::SCHEMA_EDIT);
-
- rowPos += interval + rowSize;
-
- std::string tmp = common::LexicalCast<std::string>(config.GetPageSize());
- val = tmp.c_str();
- pageSizeLabel = CreateLabel(labelPosX, rowPos, labelSizeX,
- rowSize, "Page size:", ChildId::PAGE_SIZE_LABEL);
+ schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
+ "Schema name:", ChildId::SCHEMA_LABEL);
+ schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT);
- pageSizeEdit = CreateEdit(editPosX, rowPos, editSizeX,
- rowSize, val, ChildId::PAGE_SIZE_EDIT, ES_NUMBER);
+ rowPos += INTERVAL + ROW_HEIGHT;
- rowPos += interval + rowSize;
-
- protocolVersionLabel = CreateLabel(labelPosX, rowPos, labelSizeX, rowSize,
+ protocolVersionLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
"Protocol version:", ChildId::PROTOCOL_VERSION_LABEL);
- protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, rowSize,
+ protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT,
"Protocol version", ChildId::PROTOCOL_VERSION_COMBO_BOX);
int id = 0;
@@ -157,48 +162,132 @@ namespace ignite
++id;
}
- rowPos += interval + rowSize;
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ connectionSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY,
+ "Connection settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX);
+
+ return rowPos - posY;
+ }
+
+ int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX)
+ {
+ using ssl::SslMode;
+
+ enum { LABEL_WIDTH = 120 };
+
+ int labelPosX = posX + INTERVAL;
+
+ int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL;
+ int editPosX = labelPosX + LABEL_WIDTH + INTERVAL;
+
+ int rowPos = posY + 2 * INTERVAL;
+
+ const char* val = config.GetSslMode().c_str();
+ SslMode::T sslMode = SslMode::FromString(val, SslMode::DISABLE);
+
+ sslModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Mode:", ChildId::SSL_MODE_LABEL);
+ sslModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, "", ChildId::SSL_MODE_COMBO_BOX);
+
+ sslModeComboBox->AddString("disable");
+ sslModeComboBox->AddString("require");
+
+ sslModeComboBox->SetSelection(sslMode);
+
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ val = config.GetSslKeyFile().c_str();
+ sslKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Private Key:", ChildId::SSL_KEY_FILE_LABEL);
+ sslKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSL_KEY_FILE_EDIT);
+
+ SHAutoComplete(sslKeyFileEdit->GetHandle(), SHACF_DEFAULT);
+
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ val = config.GetSslCertFile().c_str();
+ sslCertFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Certificate:", ChildId::SSL_CERT_FILE_LABEL);
+ sslCertFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSL_CERT_FILE_EDIT);
+
+ SHAutoComplete(sslCertFileEdit->GetHandle(), SHACF_DEFAULT);
- distributedJoinsCheckBox = CreateCheckBox(editPosX, rowPos, checkBoxSize, rowSize,
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ val = config.GetSslCaFile().c_str();
+ sslCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Certificate Authority:", ChildId::SSL_CA_FILE_LABEL);
+ sslCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSL_CA_FILE_EDIT);
+
+ SHAutoComplete(sslCaFileEdit->GetHandle(), SHACF_DEFAULT);
+
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY,
+ "SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX);
+
+ sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+ sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+ sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+
+ return rowPos - posY;
+ }
+
+ int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX)
+ {
+ enum { LABEL_WIDTH = 80 };
+
+ int labelPosX = posX + INTERVAL;
+
+ int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL;
+ int editPosX = labelPosX + LABEL_WIDTH + INTERVAL;
+
+ int checkBoxSize = (sizeX - 3 * INTERVAL) / 2;
+
+ const ProtocolVersion version = config.GetProtocolVersion();
+
+ int rowPos = posY + 2 * INTERVAL;
+
+ std::string tmp = common::LexicalCast<std::string>(config.GetPageSize());
+ const char* val = tmp.c_str();
+ pageSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH,
+ ROW_HEIGHT, "Page size:", ChildId::PAGE_SIZE_LABEL);
+
+ pageSizeEdit = CreateEdit(editPosX, rowPos, editSizeX,
+ ROW_HEIGHT, val, ChildId::PAGE_SIZE_EDIT, ES_NUMBER);
+
+ rowPos += INTERVAL + ROW_HEIGHT;
+
+ distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT,
"Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, config.IsDistributedJoins());
- enforceJoinOrderCheckBox = CreateCheckBox(editPosX + checkBoxSize + interval, rowPos, checkBoxSize,
- rowSize, "Enforce Join Order", ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, config.IsEnforceJoinOrder());
+ enforceJoinOrderCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize,
+ ROW_HEIGHT, "Enforce Join Order", ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, config.IsEnforceJoinOrder());
- rowPos += rowSize;
+ rowPos += ROW_HEIGHT;
- replicatedOnlyCheckBox = CreateCheckBox(editPosX, rowPos, checkBoxSize, rowSize,
+ replicatedOnlyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT,
"Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, config.IsReplicatedOnly());
- collocatedCheckBox = CreateCheckBox(editPosX + checkBoxSize + interval, rowPos, checkBoxSize,
- rowSize, "Collocated", ChildId::COLLOCATED_CHECK_BOX, config.IsCollocated());
+ collocatedCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize,
+ ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, config.IsCollocated());
- rowPos += rowSize;
+ rowPos += ROW_HEIGHT;
- lazyCheckBox = CreateCheckBox(editPosX, rowPos, checkBoxSize, rowSize,
+ lazyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT,
"Lazy", ChildId::LAZY_CHECK_BOX, config.IsLazy());
lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5);
- skipReducerOnUpdateCheckBox = CreateCheckBox(editPosX + checkBoxSize + interval, rowPos,
- checkBoxSize, rowSize, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX,
+ skipReducerOnUpdateCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos,
+ checkBoxSize, ROW_HEIGHT, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX,
config.IsSkipReducerOnUpdate());
skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0);
- rowPos += interval * 2 + rowSize;
-
- connectionSettingsGroupBox = CreateGroupBox(margin, sectionBegin, width - 2 * margin,
- rowPos - interval - sectionBegin, "Connection settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX);
+ rowPos += ROW_HEIGHT + INTERVAL;
- int buttonSizeX = 80;
- int cancelPosX = width - margin - buttonSizeX;
- int okPosX = cancelPosX - interval - buttonSizeX;
+ additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY,
+ "Additional settings", ChildId::ADDITIONAL_SETTINGS_GROUP_BOX);
- rowSize = 25;
-
- okButton = CreateButton(okPosX, rowPos, buttonSizeX, rowSize, "Ok", ChildId::OK_BUTTON);
- cancelButton = CreateButton(cancelPosX, rowPos, buttonSizeX, rowSize, "Cancel", ChildId::CANCEL_BUTTON);
+ return rowPos - posY;
}
bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam)
@@ -289,6 +378,22 @@ namespace ignite
break;
}
+ case ChildId::SSL_MODE_COMBO_BOX:
+ {
+ using ssl::SslMode;
+
+ std::string sslModeStr;
+ sslModeComboBox->GetText(sslModeStr);
+
+ SslMode::T sslMode = SslMode::FromString(sslModeStr, SslMode::DISABLE);
+
+ sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+ sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+ sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE);
+
+ break;
+ }
+
default:
return false;
}
@@ -312,54 +417,32 @@ namespace ignite
void DsnConfigurationWindow::RetrieveParameters(config::Configuration& cfg) const
{
+ RetrieveConnectionParameters(cfg);
+ RetrieveSslParameters(cfg);
+ RetrieveAdditionalParameters(cfg);
+ }
+
+ void DsnConfigurationWindow::RetrieveConnectionParameters(config::Configuration& cfg) const
+ {
std::string dsn;
std::string address;
std::string schema;
- std::string pageSizeStr;
std::string version;
- bool distributedJoins;
- bool enforceJoinOrder;
- bool replicatedOnly;
- bool collocated;
- bool lazy;
- bool skipReducerOnUpdate;
-
nameEdit->GetText(dsn);
addressEdit->GetText(address);
schemaEdit->GetText(schema);
protocolVersionComboBox->GetText(version);
- pageSizeEdit->GetText(pageSizeStr);
-
- int32_t pageSize = common::LexicalCast<int32_t>(pageSizeStr);
-
- if (pageSize <= 0)
- pageSize = config.GetPageSize();
common::StripSurroundingWhitespaces(address);
common::StripSurroundingWhitespaces(dsn);
-
- distributedJoins = distributedJoinsCheckBox->IsEnabled() && distributedJoinsCheckBox->IsChecked();
- enforceJoinOrder = enforceJoinOrderCheckBox->IsEnabled() && enforceJoinOrderCheckBox->IsChecked();
- replicatedOnly = replicatedOnlyCheckBox->IsEnabled() && replicatedOnlyCheckBox->IsChecked();
- collocated = collocatedCheckBox->IsEnabled() && collocatedCheckBox->IsChecked();
- lazy = lazyCheckBox->IsEnabled() && lazyCheckBox->IsChecked();
-
- skipReducerOnUpdate =
- skipReducerOnUpdateCheckBox->IsEnabled() && skipReducerOnUpdateCheckBox->IsChecked();
+ // Stripping of whitespaces off the schema skipped intentionally
LOG_MSG("Retriving arguments:");
LOG_MSG("DSN: " << dsn);
LOG_MSG("Address: " << address);
LOG_MSG("Schema: " << schema);
- LOG_MSG("Page size: " << pageSize);
LOG_MSG("Protocol version: " << version);
- LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false"));
- LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false"));
- LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false"));
- LOG_MSG("Collocated: " << (collocated ? "true" : "false"));
- LOG_MSG("Lazy: " << (lazy ? "true" : "false"));
- LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false"));
if (dsn.empty())
throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "DSN name can not be empty.");
@@ -367,8 +450,68 @@ namespace ignite
cfg.SetDsn(dsn);
cfg.SetAddress(address);
cfg.SetSchema(schema);
- cfg.SetPageSize(pageSize);
cfg.SetProtocolVersion(version);
+ }
+
+ void DsnConfigurationWindow::RetrieveSslParameters(config::Configuration& cfg) const
+ {
+ std::string sslMode;
+ std::string sslKey;
+ std::string sslCert;
+ std::string sslCa;
+
+ sslModeComboBox->GetText(sslMode);
+ sslKeyFileEdit->GetText(sslKey);
+ sslCertFileEdit->GetText(sslCert);
+ sslCaFileEdit->GetText(sslCa);
+
+ LOG_MSG("Retriving arguments:");
+ LOG_MSG("SSL Mode: " << sslMode);
+ LOG_MSG("SSL Key: " << sslKey);
+ LOG_MSG("SSL Certificate: " << sslCert);
+ LOG_MSG("SSL CA: " << sslCa);
+
+ cfg.SetSslMode(sslMode);
+ cfg.SetSslKeyFile(sslKey);
+ cfg.SetSslCertFile(sslCert);
+ cfg.SetSslCaFile(sslCa);
+ }
+
+ void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const
+ {
+ std::string pageSizeStr;
+
+ bool distributedJoins;
+ bool enforceJoinOrder;
+ bool replicatedOnly;
+ bool collocated;
+ bool lazy;
+ bool skipReducerOnUpdate;
+
+ pageSizeEdit->GetText(pageSizeStr);
+
+ int32_t pageSize = common::LexicalCast<int32_t>(pageSizeStr);
+
+ if (pageSize <= 0)
+ pageSize = config.GetPageSize();
+
+ distributedJoins = distributedJoinsCheckBox->IsChecked();
+ enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked();
+ replicatedOnly = replicatedOnlyCheckBox->IsChecked();
+ collocated = collocatedCheckBox->IsChecked();
+ lazy = lazyCheckBox->IsChecked();
+ skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked();
+
+ LOG_MSG("Retriving arguments:");
+ LOG_MSG("Page size: " << pageSize);
+ LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false"));
+ LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false"));
+ LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false"));
+ LOG_MSG("Collocated: " << (collocated ? "true" : "false"));
+ LOG_MSG("Lazy: " << (lazy ? "true" : "false"));
+ LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false"));
+
+ cfg.SetPageSize(pageSize);
cfg.SetDistributedJoins(distributedJoins);
cfg.SetEnforceJoinOrder(enforceJoinOrder);
cfg.SetReplicatedOnly(replicatedOnly);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/win/src/system/ui/window.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/ui/window.cpp b/modules/platforms/cpp/odbc/os/win/src/system/ui/window.cpp
index aca23eb..8f2340a 100644
--- a/modules/platforms/cpp/odbc/os/win/src/system/ui/window.cpp
+++ b/modules/platforms/cpp/odbc/os/win/src/system/ui/window.cpp
@@ -130,6 +130,13 @@ namespace ignite
void Window::GetText(std::string& text) const
{
+ if (!IsEnabled())
+ {
+ text.clear();
+
+ return;
+ }
+
int len = GetWindowTextLength(handle);
if (len <= 0)
@@ -154,7 +161,7 @@ namespace ignite
bool Window::IsChecked() const
{
- return Button_GetCheck(handle) == BST_CHECKED;
+ return IsEnabled() && Button_GetCheck(handle) == BST_CHECKED;
}
void Window::SetChecked(bool state)
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
index c5783ff..239a30f 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
@@ -93,13 +93,16 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
- <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(OPENSSL_HOME)\include;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";_DEBUG;ODBC_DEBUG;ODBC_LOG_PATH="D:\\odbc.log";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>module.def</ModuleDefinitionFile>
- <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OPENSSL_HOME)\lib\VC</AdditionalLibraryDirectories>
+ <DelayLoadDLLs>
+ </DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -107,13 +110,16 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
- <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(OPENSSL_HOME)\include;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>module.def</ModuleDefinitionFile>
- <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OPENSSL_HOME)\lib\VC</AdditionalLibraryDirectories>
+ <DelayLoadDLLs>
+ </DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -122,7 +128,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(OPENSSL_HOME)\include;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
@@ -131,7 +137,8 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>module.def</ModuleDefinitionFile>
- <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OPENSSL_HOME)\lib\VC</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -140,7 +147,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(OPENSSL_HOME)\include;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win\include;$(ProjectDir)\..\..\src</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;TARGET_MODULE_FULL_NAME="$(TargetFileName)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BufferSecurityCheck>false</BufferSecurityCheck>
</ClCompile>
@@ -149,12 +156,13 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>module.def</ModuleDefinitionFile>
- <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OPENSSL_HOME)\lib\VC</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\os\win\src\system_dsn.cpp" />
- <ClCompile Include="..\..\os\win\src\system\socket_client.cpp" />
+ <ClCompile Include="..\..\os\win\src\system\tcp_socket_client.cpp" />
<ClCompile Include="..\..\os\win\src\system\ui\custom_window.cpp" />
<ClCompile Include="..\..\os\win\src\system\ui\dsn_configuration_window.cpp" />
<ClCompile Include="..\..\os\win\src\system\ui\window.cpp" />
@@ -188,6 +196,9 @@
<ClCompile Include="..\..\src\query\type_info_query.cpp" />
<ClCompile Include="..\..\src\result_page.cpp" />
<ClCompile Include="..\..\src\row.cpp" />
+ <ClCompile Include="..\..\src\ssl\secure_socket_client.cpp" />
+ <ClCompile Include="..\..\src\ssl\ssl_gateway.cpp" />
+ <ClCompile Include="..\..\src\ssl\ssl_mode.cpp" />
<ClCompile Include="..\..\src\statement.cpp" />
<ClCompile Include="..\..\src\type_traits.cpp" />
<ClCompile Include="..\..\src\utility.cpp" />
@@ -231,9 +242,14 @@
<ClInclude Include="..\..\include\ignite\odbc\query\type_info_query.h" />
<ClInclude Include="..\..\include\ignite\odbc\result_page.h" />
<ClInclude Include="..\..\include\ignite\odbc\row.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\socket_client.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\secure_socket_client.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_bindings.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_gateway.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_mode.h" />
<ClInclude Include="..\..\include\ignite\odbc\statement.h" />
<ClInclude Include="..\..\include\ignite\odbc\system\odbc_constants.h" />
- <ClInclude Include="..\..\include\ignite\odbc\system\socket_client.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\system\tcp_socket_client.h" />
<ClInclude Include="..\..\include\ignite\odbc\system\ui\dsn_configuration_window.h" />
<ClInclude Include="..\..\include\ignite\odbc\type_traits.h" />
<ClInclude Include="..\..\include\ignite\odbc\utility.h" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
index 8934625..b203b21 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
@@ -29,6 +29,9 @@
<Filter Include="Code\system\ui">
<UniqueIdentifier>{ff144e89-0a10-42c3-97dd-d22bfdbc7abb}</UniqueIdentifier>
</Filter>
+ <Filter Include="Code\ssl">
+ <UniqueIdentifier>{857734a3-6b29-412a-b75e-7fcc9d3fef8c}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\odbc.cpp">
@@ -106,9 +109,6 @@
<ClCompile Include="..\..\src\diagnostic\diagnosable_adapter.cpp">
<Filter>Code\diagnostic</Filter>
</ClCompile>
- <ClCompile Include="..\..\os\win\src\system\socket_client.cpp">
- <Filter>Code\system</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\query\type_info_query.cpp">
<Filter>Code\query</Filter>
</ClCompile>
@@ -148,6 +148,18 @@
<ClCompile Include="..\..\src\message.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\ssl\secure_socket_client.cpp">
+ <Filter>Code\ssl</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\os\win\src\system\tcp_socket_client.cpp">
+ <Filter>Code\system</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\ssl\ssl_mode.cpp">
+ <Filter>Code\ssl</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\ssl\ssl_gateway.cpp">
+ <Filter>Code\ssl</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="module.def">
@@ -245,9 +257,6 @@
<ClInclude Include="..\..\include\ignite\odbc\system\odbc_constants.h">
<Filter>Code\system</Filter>
</ClInclude>
- <ClInclude Include="..\..\include\ignite\odbc\system\socket_client.h">
- <Filter>Code\system</Filter>
- </ClInclude>
<ClInclude Include="..\..\include\ignite\odbc\query\type_info_query.h">
<Filter>Code\query</Filter>
</ClInclude>
@@ -284,5 +293,23 @@
<ClInclude Include="..\..\include\ignite\odbc\odbc_error.h">
<Filter>Code</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\secure_socket_client.h">
+ <Filter>Code\ssl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\socket_client.h">
+ <Filter>Code</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\system\tcp_socket_client.h">
+ <Filter>Code\system</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_mode.h">
+ <Filter>Code\ssl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_gateway.h">
+ <Filter>Code\ssl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\ssl\ssl_bindings.h">
+ <Filter>Code\ssl</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/src/config/configuration.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/configuration.cpp b/modules/platforms/cpp/odbc/src/config/configuration.cpp
index be5a781..769e167 100644
--- a/modules/platforms/cpp/odbc/src/config/configuration.cpp
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -46,12 +46,20 @@ namespace ignite
const std::string Configuration::Key::collocated = "collocated";
const std::string Configuration::Key::lazy = "lazy";
const std::string Configuration::Key::skipReducerOnUpdate = "skip_reducer_on_update";
+ const std::string Configuration::Key::sslMode = "ssl_mode";
+ const std::string Configuration::Key::sslKeyFile = "ssl_key_file";
+ const std::string Configuration::Key::sslCertFile = "ssl_cert_file";
+ const std::string Configuration::Key::sslCaFile = "ssl_ca_file";
const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN";
const std::string Configuration::DefaultValue::driver = "Apache Ignite";
const std::string Configuration::DefaultValue::schema = "PUBLIC";
const std::string Configuration::DefaultValue::address = "";
const std::string Configuration::DefaultValue::server = "";
+ const std::string Configuration::DefaultValue::sslMode = "disable";
+ const std::string Configuration::DefaultValue::sslKeyFile = "";
+ const std::string Configuration::DefaultValue::sslCertFile = "";
+ const std::string Configuration::DefaultValue::sslCaFile = "";
const uint16_t Configuration::DefaultValue::port = 10800;
const int32_t Configuration::DefaultValue::pageSize = 1024;
[3/4] ignite git commit: IGNITE-6810: Implemented SSL support for
ODBC.
Posted by is...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp
new file mode 100644
index 0000000..897544e
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp
@@ -0,0 +1,283 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/regex.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignite.h"
+#include "ignite/common/fixed_size_array.h"
+#include "ignite/ignition.h"
+#include "ignite/impl/binary/binary_utils.h"
+#include "ignite/binary/binary_object.h"
+
+#include "test_type.h"
+#include "complex_type.h"
+#include "test_utils.h"
+#include "odbc_test_suite.h"
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+using namespace ignite_test;
+using namespace ignite::binary;
+using namespace ignite::impl::binary;
+using namespace ignite::impl::interop;
+
+using namespace boost::unit_test;
+
+using ignite::impl::binary::BinaryUtils;
+
+/**
+ * Test setup fixture.
+ */
+struct SslQueriesTestSuiteFixture : odbc::OdbcTestSuite
+{
+ static Ignite StartAdditionalNode(const char* name)
+ {
+ return StartTestNode("queries-ssl.xml", name);
+ }
+
+ /**
+ * Constructor.
+ */
+ SslQueriesTestSuiteFixture() :
+ OdbcTestSuite(),
+ cache1(0),
+ cache2(0)
+ {
+ grid = StartAdditionalNode("NodeMain");
+
+ cache1 = grid.GetCache<int64_t, TestType>("cache");
+ cache2 = grid.GetCache<int64_t, ComplexType>("cache2");
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~SslQueriesTestSuiteFixture()
+ {
+ // No-op.
+ }
+
+ /**
+ * Create default connection string.
+ * @return Default connection string.
+ */
+ std::string MakeDefaultConnectionString()
+ {
+ std::string cfgDirPath = GetTestConfigDir();
+
+ std::stringstream connectString;
+
+ connectString <<
+ "DRIVER={Apache Ignite};"
+ "ADDRESS=127.0.0.1:11110;"
+ "SCHEMA=cache;"
+ "SSL_MODE=require;"
+ "SSL_KEY_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "client_full.pem;"
+ "SSL_CERT_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "client_full.pem;"
+ "SSL_CA_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "ca.pem;";
+
+ return connectString.str();
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+
+ /** Frist cache instance. */
+ Cache<int64_t, TestType> cache1;
+
+ /** Second cache instance. */
+ Cache<int64_t, ComplexType> cache2;
+};
+
+BOOST_FIXTURE_TEST_SUITE(SslQueriesTestSuite, SslQueriesTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TestConnectionSslSuccess)
+{
+ Connect(MakeDefaultConnectionString());
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 2000, 1989);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionSslReject)
+{
+ std::string cfgDirPath = GetTestConfigDir();
+
+ std::stringstream connectString;
+
+ connectString <<
+ "DRIVER={Apache Ignite};"
+ "ADDRESS=127.0.0.1:11110;"
+ "SCHEMA=cache;"
+ "SSL_MODE=require;"
+ "SSL_KEY_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "client_unknown.pem;"
+ "SSL_CERT_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "client_unknown.pem;"
+ "SSL_CA_FILE=" << cfgDirPath << Fs << "ssl" << Fs << "ca.pem;";
+
+ Prepare();
+
+ // Connect string
+ std::string str = connectString.str();
+ std::vector<SQLCHAR> connectStr0(str.begin(), str.end());
+
+ SQLCHAR outstr[ODBC_BUFFER_SIZE];
+ SQLSMALLINT outstrlen;
+
+ // Connecting to ODBC server.
+ SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
+ outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+ // Checking that there is an error.
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+
+ // Checking that error is the connection error.
+ BOOST_CHECK_EQUAL(std::string("08001"), GetOdbcErrorState(SQL_HANDLE_DBC, dbc));
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionTimeoutQuery)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestStrings(10, false);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionTimeoutBatch)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionTimeoutBoth)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryTimeoutQuery)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ InsertTestStrings(10, false);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryTimeoutBatch)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryTimeoutBoth)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryAndConnectionTimeoutQuery)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(3), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestStrings(10, false);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryAndConnectionTimeoutBatch)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(3), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestQueryAndConnectionTimeoutBoth)
+{
+ Connect(MakeDefaultConnectionString());
+
+ SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, reinterpret_cast<SQLPOINTER>(5), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+ ret = SQLSetConnectAttr(dbc, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast<SQLPOINTER>(3), 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestStrings(10, false);
+ InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
index bf9876a..639e16f 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -228,7 +228,7 @@ struct QueriesTestSuiteFixture : odbc::OdbcTestSuite
static Ignite StartAdditionalNode(const char* name)
{
- return StartTestNode("queries-test-noodbc.xml", name);
+ return StartTestNode("queries-test.xml", name);
}
/** Node started during the test. */
@@ -1340,7 +1340,7 @@ void CheckObjectData(int8_t* data, int32_t len, T const& value)
BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0, 0));
T actual = obj.Deserialize<T>();
-
+
BOOST_CHECK_EQUAL(value, actual);
}
@@ -1374,7 +1374,7 @@ BOOST_AUTO_TEST_CASE(TestKeyVal)
int8_t column6[ODBC_BUFFER_SIZE] = { 0 };
//strField
char column7[ODBC_BUFFER_SIZE] = { 0 };
-
+
SQLLEN column1Len = sizeof(column1);
SQLLEN column2Len = sizeof(column2);
SQLLEN column3Len = sizeof(column3);
@@ -1438,7 +1438,7 @@ BOOST_AUTO_TEST_CASE(TestKeyVal)
CheckObjectData(column4, static_cast<int32_t>(column4Len), obj);
BOOST_CHECK_EQUAL(column5, obj.i32Field);
-
+
CheckObjectData(column6, static_cast<int32_t>(column6Len), obj.objField);
BOOST_CHECK_EQUAL(column7, obj.strField);
@@ -1446,6 +1446,10 @@ BOOST_AUTO_TEST_CASE(TestKeyVal)
ret = SQLFetch(stmt);
BOOST_CHECK(ret == SQL_NO_DATA);
+ ret = SQLFreeStmt(stmt, SQL_CLOSE);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
SQLCHAR requestStar[] = "SELECT _key, _val, * FROM ComplexType";
ret = SQLExecDirect(stmt, requestStar, SQL_NTS);
@@ -1534,7 +1538,7 @@ BOOST_AUTO_TEST_CASE(TestExecuteAfterCursorClose)
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
-
+
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
index f905ff7..42dd3f7 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
@@ -110,6 +110,10 @@ namespace ignite
ret = SQLFetch(stmt);
BOOST_CHECK(ret == SQL_NO_DATA);
+
+ ret = SQLFreeStmt(stmt, SQL_CLOSE);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
template<>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/test_utils.cpp b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
index eb08660..6d9ed6b 100644
--- a/modules/platforms/cpp/odbc-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
@@ -17,6 +17,8 @@
#include <cassert>
+#include <ignite/common/platform_utils.h>
+
#include "test_utils.h"
namespace ignite_test
@@ -54,6 +56,11 @@ namespace ignite_test
return res;
}
+ std::string GetTestConfigDir()
+ {
+ return ignite::common::GetEnv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH");
+ }
+
void InitConfig(ignite::IgniteConfiguration& cfg, const char* cfgFile)
{
using namespace ignite;
@@ -70,6 +77,8 @@ namespace ignite_test
cfg.jvmOpts.push_back("-DIGNITE_CONSOLE_APPENDER=false");
cfg.jvmOpts.push_back("-DIGNITE_UPDATE_NOTIFIER=false");
cfg.jvmOpts.push_back("-Duser.language=en");
+ // Un-comment to debug SSL
+ //cfg.jvmOpts.push_back("-Djavax.net.debug=ssl");
cfg.igniteHome = jni::ResolveIgniteHome();
cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(cfg.igniteHome, true);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am
index 8d7693c..ea74c34 100644
--- a/modules/platforms/cpp/odbc/Makefile.am
+++ b/modules/platforms/cpp/odbc/Makefile.am
@@ -49,7 +49,7 @@ libignite_odbc_la_DEPENDENCIES = \
@top_srcdir@/binary/libignite-binary.la
libignite_odbc_la_SOURCES = \
- os/linux/src/system/socket_client.cpp \
+ os/linux/src/system/tcp_socket_client.cpp \
src/app/application_data_buffer.cpp \
src/app/parameter.cpp \
src/app/parameter_set.cpp \
@@ -75,6 +75,9 @@ libignite_odbc_la_SOURCES = \
src/query/table_metadata_query.cpp \
src/query/type_info_query.cpp \
src/query/special_columns_query.cpp \
+ src/ssl/ssl_gateway.cpp \
+ src/ssl/secure_socket_client.cpp \
+ src/ssl/ssl_mode.cpp \
src/protocol_version.cpp \
src/result_page.cpp \
src/row.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/Makefile.am b/modules/platforms/cpp/odbc/include/Makefile.am
index 7c64754..9bdb803 100644
--- a/modules/platforms/cpp/odbc/include/Makefile.am
+++ b/modules/platforms/cpp/odbc/include/Makefile.am
@@ -42,7 +42,7 @@ noinst_HEADERS = \
ignite/odbc/environment.h \
ignite/odbc/dsn_config.h \
ignite/odbc/system/odbc_constants.h \
- ignite/odbc/system/socket_client.h \
+ ignite/odbc/system/tcp_socket_client.h \
ignite/odbc/meta/primary_key_meta.h \
ignite/odbc/meta/column_meta.h \
ignite/odbc/meta/table_meta.h \
@@ -50,6 +50,10 @@ noinst_HEADERS = \
ignite/odbc/diagnostic/diagnostic_record_storage.h \
ignite/odbc/diagnostic/diagnosable.h \
ignite/odbc/diagnostic/diagnosable_adapter.h \
+ ignite/odbc/ssl/ssl_mode.h \
+ ignite/odbc/ssl/ssl_bindings.h \
+ ignite/odbc/ssl/secure_socket_client.h \
+ ignite/odbc/ssl/ssl_gateway.h \
ignite/odbc/connection.h \
ignite/odbc/odbc_error.h \
ignite/odbc/message.h \
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
index 419a65e..89018f5 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
@@ -85,6 +85,18 @@ namespace ignite
/** Connection attribute keyword for skipReducerOnUpdate attribute. */
static const std::string skipReducerOnUpdate;
+
+ /** Connection attribute keyword for sslMode attribute. */
+ static const std::string sslMode;
+
+ /** Connection attribute keyword for sslKeyFile attribute. */
+ static const std::string sslKeyFile;
+
+ /** Connection attribute keyword for sslCertFile attribute. */
+ static const std::string sslCertFile;
+
+ /** Connection attribute keyword for sslCaFile attribute. */
+ static const std::string sslCaFile;
};
/** Default values for configuration. */
@@ -105,6 +117,18 @@ namespace ignite
/** Default value for server attribute. */
static const std::string server;
+ /** Default value for sslMode attribute. */
+ static const std::string sslMode;
+
+ /** Default value for sslKeyFile attribute. */
+ static const std::string sslKeyFile;
+
+ /** Default value for sslCertFile attribute. */
+ static const std::string sslCertFile;
+
+ /** Default value for sslCaFile attribute. */
+ static const std::string sslCaFile;
+
/** Default value for protocol version. */
static const ProtocolVersion& protocolVersion;
@@ -183,8 +207,8 @@ namespace ignite
/**
* Fill configuration data using config attributes string.
*
- * @param str Pointer to list of zero-terminated strings.
- * Terminated by two zero bytes.
+ * @param attributes Pointer to list of zero-terminated strings.
+ * Terminated by two zero bytes.
*/
void FillFromConfigAttributes(const char* attributes);
@@ -290,6 +314,86 @@ namespace ignite
void SetAddress(const std::string& address);
/**
+ * Get SSL mode.
+ *
+ * @return SSL mode.
+ */
+ const std::string& GetSslMode() const
+ {
+ return GetStringValue(Key::sslMode, DefaultValue::sslMode);
+ }
+
+ /**
+ * Set SSL mode.
+ *
+ * @param sslMode SSL mode.
+ */
+ void SetSslMode(const std::string& sslMode)
+ {
+ arguments[Key::sslMode] = sslMode;
+ }
+
+ /**
+ * Get SSL key file path.
+ *
+ * @return SSL key file path.
+ */
+ const std::string& GetSslKeyFile() const
+ {
+ return GetStringValue(Key::sslKeyFile, DefaultValue::sslKeyFile);
+ }
+
+ /**
+ * Set SSL key file path.
+ *
+ * @param sslKeyFile SSL key file path.
+ */
+ void SetSslKeyFile(const std::string& sslKeyFile)
+ {
+ arguments[Key::sslKeyFile] = sslKeyFile;
+ }
+
+ /**
+ * Get SSL certificate file path.
+ *
+ * @return SSL certificate file path.
+ */
+ const std::string& GetSslCertFile() const
+ {
+ return GetStringValue(Key::sslCertFile, DefaultValue::sslCertFile);
+ }
+
+ /**
+ * Set SSL certificate file path.
+ *
+ * @param sslCertFile SSL certificate file path.
+ */
+ void SetSslCertFile(const std::string& sslCertFile)
+ {
+ arguments[Key::sslCertFile] = sslCertFile;
+ }
+
+ /**
+ * Get SSL certificate authority file path.
+ *
+ * @return SSL certificate authority file path.
+ */
+ const std::string& GetSslCaFile() const
+ {
+ return GetStringValue(Key::sslCaFile, DefaultValue::sslCaFile);
+ }
+
+ /**
+ * Set SSL certificate authority file path.
+ *
+ * @param sslCaFile SSL certificate authority file path.
+ */
+ void SetSslCaFile(const std::string& sslCaFile)
+ {
+ arguments[Key::sslCaFile] = sslCaFile;
+ }
+
+ /**
* Check distributed joins flag.
*
* @return True if distributed joins are enabled.
@@ -495,7 +599,7 @@ namespace ignite
*
* @param str String to parse.
* @param len String length.
- * @param params Parsing result.
+ * @param args Parsing result.
*/
static void ParseAttributeList(const char* str, size_t len, char delimeter, ArgumentMap& args);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
index 1577ee7..025b855 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -23,7 +23,7 @@
#include <vector>
#include "ignite/odbc/parser.h"
-#include "ignite/odbc/system/socket_client.h"
+#include "ignite/odbc/socket_client.h"
#include "ignite/odbc/config/connection_info.h"
#include "ignite/odbc/config/configuration.h"
#include "ignite/odbc/diagnostic/diagnosable_adapter.h"
@@ -367,11 +367,8 @@ namespace ignite
*/
Connection();
- /** Socket. */
- tcp::SocketClient socket;
-
- /** State flag. */
- bool connected;
+ /** Client Socket. */
+ std::auto_ptr<SocketClient> socket;
/** Connection timeout in seconds. */
int32_t timeout;
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/socket_client.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/socket_client.h b/modules/platforms/cpp/odbc/include/ignite/odbc/socket_client.h
new file mode 100644
index 0000000..2df035b
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/socket_client.h
@@ -0,0 +1,109 @@
+/*
+ * 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 _IGNITE_ODBC_SOCKET_CLIENT
+#define _IGNITE_ODBC_SOCKET_CLIENT
+
+#include <stdint.h>
+
+#include "ignite/odbc/diagnostic/diagnosable.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ /**
+ * Socket client implementation.
+ */
+ class SocketClient
+ {
+ public:
+ /** Connection establishment timeout in seconds. */
+ enum { CONNECT_TIMEOUT = 5 };
+
+ /**
+ * Non-negative timeout operation result.
+ */
+ struct WaitResult
+ {
+ enum T
+ {
+ /** Timeout. */
+ TIMEOUT = 0,
+
+ /** Success. */
+ SUCCESS = 1
+ };
+ };
+
+ /**
+ * Destructor.
+ */
+ virtual ~SocketClient()
+ {
+ // No-op.
+ }
+
+ /**
+ * Establish connection with remote service.
+ *
+ * @param hostname Remote host name.
+ * @param port Service port.
+ * @param diag Diagnostics collector.
+ * @return True on success.
+ */
+ virtual bool Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag) = 0;
+
+ /**
+ * Close established connection.
+ *
+ * @return True on success.
+ */
+ virtual void Close() = 0;
+
+ /**
+ * Send data by established connection.
+ *
+ * @param data Pointer to data to be sent.
+ * @param size Size of the data in bytes.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been sent on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Send(const int8_t* data, size_t size, int32_t timeout) = 0;
+
+ /**
+ * Receive data from established connection.
+ *
+ * @param buffer Pointer to data buffer.
+ * @param size Size of the buffer in bytes.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been received on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Receive(int8_t* buffer, size_t size, int32_t timeout) = 0;
+
+ /**
+ * Check if the socket is blocking or not.
+ * @return @c true if the socket is blocking and false otherwise.
+ */
+ virtual bool IsBlocking() const = 0;
+ };
+ }
+}
+
+#endif //_IGNITE_ODBC_SYSTEM_SOCKET_CLIENT
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/secure_socket_client.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/secure_socket_client.h b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/secure_socket_client.h
new file mode 100644
index 0000000..4cd5844
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/secure_socket_client.h
@@ -0,0 +1,148 @@
+/*
+ * 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 _IGNITE_ODBC_SSL_SECURE_SOCKET_CLIENT
+#define _IGNITE_ODBC_SSL_SECURE_SOCKET_CLIENT
+
+#include <stdint.h>
+#include <string>
+
+#include "ignite/odbc/diagnostic/diagnosable.h"
+#include "ignite/odbc/socket_client.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ /**
+ * Secure socket client.
+ */
+ class SecureSocketClient : public SocketClient
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param certPath Certificate file path.
+ * @param keyPath Private key file path.
+ * @param caPath Certificate authority file path.
+ */
+ SecureSocketClient(const std::string& certPath, const std::string& keyPath, const std::string& caPath);
+
+ /**
+ * Destructor.
+ */
+ virtual ~SecureSocketClient();
+
+ /**
+ * Establish connection with the host.
+ *
+ * @param hostname Host name or address.
+ * @param port TCP port.
+ * @param diag Diagnostics collector to use for error-reporting.
+ * @return @c true on success and @c false on fail.
+ */
+ virtual bool Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag);
+
+ /**
+ * Close the connection.
+ */
+ virtual void Close();
+
+ /**
+ * Send data using connection.
+ * @param data Data to send.
+ * @param size Number of bytes to send.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been sent on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Send(const int8_t* data, size_t size, int32_t timeout);
+
+ /**
+ * Receive data from established connection.
+ *
+ * @param buffer Pointer to data buffer.
+ * @param size Size of the buffer in bytes.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been received on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Receive(int8_t* buffer, size_t size, int32_t timeout);
+
+ /**
+ * Check if the socket is blocking or not.
+ * @return @c true if the socket is blocking and false otherwise.
+ */
+ virtual bool IsBlocking() const;
+
+ private:
+ /**
+ * Close the connection.
+ * Internal call.
+ */
+ void CloseInteral();
+
+ /**
+ * Wait on the socket for any event for specified time.
+ * This function uses poll to achive timeout functionality
+ * for every separate socket operation.
+ *
+ * @param timeout Timeout.
+ * @param rd Wait for read if @c true, or for write if @c false.
+ * @return -errno on error, WaitResult::TIMEOUT on timeout and
+ * WaitResult::SUCCESS on success.
+ */
+ int WaitOnSocket(int32_t timeout, bool rd);
+
+ /**
+ * Make new context instance.
+ *
+ * @param certPath Certificate file path.
+ * @param keyPath Private key file path.
+ * @param caPath Certificate authority file path.
+ * @param diag Diagnostics collector to use for error-reporting.
+ * @return New context instance on success and null-opinter on fail.
+ */
+ static void* MakeContext(const std::string& certPath, const std::string& keyPath,
+ const std::string& caPath, diagnostic::Diagnosable& diag);
+
+ /** Certificate file path. */
+ std::string certPath;
+
+ /** Private key file path. */
+ std::string keyPath;
+
+ /** Certificate authority file path. */
+ std::string caPath;
+
+ /** SSL context. */
+ void* context;
+
+ /** OpenSSL I/O stream abstraction */
+ void* sslBio;
+
+ /** Blocking flag. */
+ bool blocking;
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_ODBC_SSL_SECURE_SOCKET_CLIENT
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_bindings.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_bindings.h b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_bindings.h
new file mode 100644
index 0000000..b23533a
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_bindings.h
@@ -0,0 +1,303 @@
+/*
+ * 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 _IGNITE_ODBC_SSL_SSL_BINDINGS
+#define _IGNITE_ODBC_SSL_SSL_BINDINGS
+
+#include <openssl/ssl.h>
+#include <openssl/conf.h>
+
+#include "ignite/odbc/ssl/ssl_gateway.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ // Declaring constant used by OpenSSL for readability.
+ enum { OPERATION_SUCCESS = 1 };
+
+ inline SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
+ {
+ typedef SSL_CTX*(FuncType)(const SSL_METHOD*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSL_CTX_new);
+
+ return fp(meth);
+ }
+
+ inline void SSL_CTX_free(SSL_CTX *ctx)
+ {
+ typedef void(FuncType)(SSL_CTX*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSL_CTX_free);
+
+ fp(ctx);
+ }
+
+ inline void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int(*callback) (int, X509_STORE_CTX *))
+ {
+ typedef void(FuncType)(SSL_CTX*, int, int(*)(int, X509_STORE_CTX*));
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_set_verify);
+
+ fp(ctx, mode, callback);
+ }
+
+ inline void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
+ {
+ typedef void(FuncType)(SSL_CTX*, int);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_set_verify_depth);
+
+ fp(ctx, depth);
+ }
+
+ inline int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *cAfile, const char *cApath)
+ {
+ typedef int(FuncType)(SSL_CTX*, const char*, const char*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_load_verify_locations);
+
+ return fp(ctx, cAfile, cApath);
+ }
+
+ inline int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
+ {
+ typedef int(FuncType)(SSL_CTX*, const char*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_use_certificate_chain_file);
+
+ return fp(ctx, file);
+ }
+
+ inline int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+ {
+ typedef int(FuncType)(SSL_CTX*, const char*, int);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_use_RSAPrivateKey_file);
+
+ return fp(ctx, file, type);
+ }
+
+ inline int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
+ {
+ typedef int(FuncType)(SSL_CTX*, const char*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_CTX_set_cipher_list);
+
+ return fp(ctx, str);
+ }
+
+ inline long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+ {
+ typedef long(FuncType)(SSL_CTX*, int, long, void*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSL_CTX_ctrl);
+
+ return fp(ctx, cmd, larg, parg);
+ }
+
+ inline long SSL_get_verify_result(const SSL *s)
+ {
+ typedef long(FuncType)(const SSL*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_get_verify_result);
+
+ return fp(s);
+ }
+
+ inline int SSL_library_init()
+ {
+ typedef int(FuncType)();
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSL_library_init);
+
+ return fp();
+ }
+
+ inline void SSL_load_error_strings()
+ {
+ typedef void(FuncType)();
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_load_error_strings);
+
+ fp();
+ }
+
+ inline X509 *SSL_get_peer_certificate(const SSL *s)
+ {
+ typedef X509*(FuncType)(const SSL*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpSSL_get_peer_certificate);
+
+ return fp(s);
+ }
+
+ inline long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
+ {
+ typedef long(FuncType)(SSL*, int, long, void*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSL_ctrl);
+
+ return fp(s, cmd, larg ,parg);
+ }
+
+ inline long SSL_set_tlsext_host_name_(SSL *s, const char *name)
+ {
+ return ssl::SSL_ctrl(s, SSL_CTRL_SET_TLSEXT_HOSTNAME,
+ TLSEXT_NAMETYPE_host_name, const_cast<char*>(name));
+ }
+
+
+
+ inline const SSL_METHOD *SSLv23_method()
+ {
+ typedef const SSL_METHOD*(FuncType)();
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpSSLv23_method);
+
+ return fp();
+ }
+
+ inline void OPENSSL_config(const char *configName)
+ {
+ typedef void(FuncType)(const char*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpOPENSSL_config);
+
+ fp(configName);
+ }
+
+ inline void X509_free(X509 *a)
+ {
+ typedef void(FuncType)(X509*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpX509_free);
+
+ fp(a);
+ }
+
+ inline BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
+ {
+ typedef BIO*(FuncType)(SSL_CTX*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(
+ SslGateway::GetInstance().GetFunctions().fpBIO_new_ssl_connect);
+
+ return fp(ctx);
+ }
+
+ inline int BIO_write(BIO *b, const void *data, int len)
+ {
+ typedef int(FuncType)(BIO*, const void*, int);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpBIO_write);
+
+ return fp(b, data, len);
+ }
+
+ inline int BIO_read(BIO *b, void *data, int len)
+ {
+ typedef int(FuncType)(BIO*, const void*, int);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpBIO_read);
+
+ return fp(b, data, len);
+ }
+
+ inline void BIO_free_all(BIO *a)
+ {
+ typedef void(FuncType)(BIO*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpBIO_free_all);
+
+ fp(a);
+ }
+
+ inline int BIO_test_flags(const BIO *b, int flags)
+ {
+ typedef int(FuncType)(const BIO*, int);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpBIO_test_flags);
+
+ return fp(b, flags);
+ }
+
+ inline int BIO_should_retry_(const BIO *b)
+ {
+ return ssl::BIO_test_flags(b, BIO_FLAGS_SHOULD_RETRY);
+ }
+
+ inline long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg)
+ {
+ typedef long(FuncType)(BIO*, int, long, void*);
+
+ FuncType* fp = reinterpret_cast<FuncType*>(SslGateway::GetInstance().GetFunctions().fpBIO_ctrl);
+
+ return fp(bp, cmd, larg, parg);
+ }
+
+ inline long BIO_get_fd_(BIO *bp, int *fd)
+ {
+ return ssl::BIO_ctrl(bp, BIO_C_GET_FD, 0, reinterpret_cast<void*>(fd));
+ }
+
+ inline long BIO_do_handshake_(BIO *bp)
+ {
+ return ssl::BIO_ctrl(bp, BIO_C_DO_STATE_MACHINE, 0, NULL);
+ }
+
+ inline long BIO_do_connect_(BIO *bp)
+ {
+ return ssl::BIO_do_handshake_(bp);
+ }
+
+ inline long BIO_get_ssl_(BIO *bp, SSL** ssl)
+ {
+ return ssl::BIO_ctrl(bp, BIO_C_GET_SSL, 0, reinterpret_cast<void*>(ssl));
+ }
+
+ inline long BIO_set_nbio_(BIO *bp, long n)
+ {
+ return ssl::BIO_ctrl(bp, BIO_C_SET_NBIO, n, NULL);
+ }
+
+ inline long BIO_set_conn_hostname_(BIO *bp, const char *name)
+ {
+ return ssl::BIO_ctrl(bp, BIO_C_SET_CONNECT, 0, const_cast<char*>(name));
+ }
+
+ inline long BIO_pending_(BIO *bp)
+ {
+ return ssl::BIO_ctrl(bp, BIO_CTRL_PENDING, 0, NULL);
+ }
+ }
+ }
+}
+
+#endif //_IGNITE_ODBC_SSL_SSL_BINDINGS
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_gateway.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_gateway.h b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_gateway.h
new file mode 100644
index 0000000..b131228
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_gateway.h
@@ -0,0 +1,151 @@
+/*
+ * 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 _IGNITE_ODBC_SSL_SSL_LIBRARY
+#define _IGNITE_ODBC_SSL_SSL_LIBRARY
+
+#include "ignite/common/concurrent.h"
+#include "ignite/common/dynamic_load_os.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ /**
+ * Functions collection.
+ */
+ struct SslFunctions
+ {
+ void *fpSSL_CTX_new;
+ void *fpSSL_CTX_free;
+ void *fpSSL_CTX_set_verify;
+ void *fpSSL_CTX_set_verify_depth;
+ void *fpSSL_CTX_load_verify_locations;
+ void *fpSSL_CTX_use_certificate_chain_file;
+ void *fpSSL_CTX_use_RSAPrivateKey_file;
+ void *fpSSL_CTX_set_cipher_list;
+ void *fpSSL_CTX_ctrl;
+ void *fpSSL_get_verify_result;
+ void *fpSSL_library_init;
+ void *fpSSL_load_error_strings;
+ void *fpSSL_get_peer_certificate;
+ void *fpSSL_ctrl;
+ void *fpSSLv23_method;
+ void *fpOPENSSL_config;
+ void *fpX509_free;
+ void *fpBIO_new_ssl_connect;
+ void *fpBIO_write;
+ void *fpBIO_read;
+ void *fpBIO_free_all;
+ void *fpBIO_test_flags;
+ void *fpBIO_ctrl;
+ };
+
+ /**
+ * SSL Gateway abstraction.
+ * Used as a factory for secure sockets. Needed for dynamic loading
+ * of the SSL libraries.
+ */
+ class SslGateway
+ {
+ public:
+ /**
+ * Get class instance.
+ * @return SslLibrary instance.
+ */
+ static SslGateway& GetInstance();
+
+ /**
+ * Try loading SSL library.
+ * @return @c true if loaded successfully, and false otherwise.
+ */
+ bool LoadAll();
+
+ /**
+ * Get functions.
+ * @return Functions structure.
+ */
+ SslFunctions& GetFunctions()
+ {
+ return functions;
+ }
+
+ /**
+ * Check whether the libraries are loaded.
+ * @return @c true if loaded.
+ */
+ bool Loaded() const
+ {
+ return inited;
+ }
+
+ private:
+ /**
+ * Constructor.
+ */
+ SslGateway();
+
+ /**
+ * Destructor.
+ */
+ ~SslGateway();
+
+ /**
+ * Load SSL library.
+ * @param name Name.
+ * @return Module.
+ */
+ common::dynamic::Module LoadSslLibrary(const char* name);
+
+ /**
+ * Load all SSL libraries.
+ */
+ bool LoadSslLibraries();
+
+ /**
+ * Load SSL method.
+ * @param mod Module.
+ * @param name Name.
+ * @return Method pointer.
+ */
+ void* LoadSslMethod(const char* name);
+
+ /** Indicates whether the library was inited. */
+ bool inited;
+
+ /** Critical section to prevent multiple instance creation. */
+ common::concurrent::CriticalSection initCs;
+
+ /** libeay32 module. */
+ common::dynamic::Module libeay32;
+
+ /** ssleay32 module. */
+ common::dynamic::Module ssleay32;
+
+ /** libssl module. */
+ common::dynamic::Module libssl;
+
+ /** Functions. */
+ SslFunctions functions;
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_ODBC_SSL_SSL_LIBRARY
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_mode.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_mode.h b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_mode.h
new file mode 100644
index 0000000..20472c3
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/ssl/ssl_mode.h
@@ -0,0 +1,55 @@
+/*
+ * 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 _IGNITE_ODBC_SSL_SSL_MODE
+#define _IGNITE_ODBC_SSL_SSL_MODE
+
+#include <string>
+
+#include "ignite/odbc/diagnostic/diagnosable.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace ssl
+ {
+ /** SSL Mode enum. */
+ struct SslMode
+ {
+ enum T
+ {
+ DISABLE = 0,
+
+ REQUIRE = 1,
+
+ UNKNOWN = 100
+ };
+
+ /**
+ * Convert mode from string.
+ * @param val String value.
+ * @param dflt Default value to return on error.
+ * @return Corresponding enum value.
+ */
+ static T FromString(const std::string& val, T dflt = UNKNOWN);
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_ODBC_SSL_SSL_MODE
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/system/socket_client.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/system/socket_client.h b/modules/platforms/cpp/odbc/include/ignite/odbc/system/socket_client.h
deleted file mode 100644
index 2a3cfa3..0000000
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/system/socket_client.h
+++ /dev/null
@@ -1,151 +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.
- */
-
-#ifndef _IGNITE_ODBC_SYSTEM_SOCKET_CLIENT
-#define _IGNITE_ODBC_SYSTEM_SOCKET_CLIENT
-
-#include <stdint.h>
-
-#include "ignite/common/common.h"
-#include "ignite/odbc/diagnostic/diagnosable.h"
-
-namespace ignite
-{
- namespace odbc
- {
- namespace tcp
- {
- /**
- * Socket client implementation.
- */
- class SocketClient
- {
- public:
- /** Buffers size */
- enum { BUFFER_SIZE = 0x10000 };
-
- /** The time in seconds the connection needs to remain idle before starts sending keepalive probes. */
- enum { KEEP_ALIVE_IDLE_TIME = 60 };
-
- /** The time in seconds between individual keepalive probes. */
- enum { KEEP_ALIVE_PROBES_PERIOD = 1 };
-
- /** Connection establishment timeout in seconds. */
- enum { CONNECT_TIMEOUT = 5 };
-
- /**
- * Non-negative timeout operation result.
- */
- struct WaitResult
- {
- enum T
- {
- TIMEOUT = 0,
-
- SUCCESS = 1
- };
- };
-
- /**
- * Constructor.
- */
- SocketClient();
-
- /**
- * Destructor.
- */
- ~SocketClient();
-
- /**
- * Establish connection with remote TCP service.
- *
- * @param hostname Remote host name.
- * @param port TCP service port.
- * @param diag Diagnostics collector.
- * @return True on success.
- */
- bool Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag);
-
- /**
- * Close established connection.
- *
- * @return True on success.
- */
- void Close();
-
- /**
- * Send data by established connection.
- *
- * @param data Pointer to data to be sent.
- * @param size Size of the data in bytes.
- * @param timeout Timeout.
- * @return Number of bytes that have been sent on success,
- * WaitResult::TIMEOUT on timeout and -errno on failure.
- */
- int Send(const int8_t* data, size_t size, int32_t timeout);
-
- /**
- * Receive data from established connection.
- *
- * @param buffer Pointer to data buffer.
- * @param size Size of the buffer in bytes.
- * @param timeout Timeout.
- * @return Number of bytes that have been sent on success,
- * WaitResult::TIMEOUT on timeout and -errno on failure.
- */
- int Receive(int8_t* buffer, size_t size, int32_t timeout);
-
- /**
- * Check if the socket is blocking or not.
- * @return @c true if the socket is blocking and false otherwise.
- */
- bool IsBlocking() const
- {
- return blocking;
- }
-
- private:
- /**
- * Tries set socket options.
- */
- void TrySetOptions(diagnostic::Diagnosable& diag);
-
- /**
- * Wait on the socket for any event for specified time.
- * This function uses poll to achive timeout functionality
- * for every separate socket operation.
- *
- * @param timeout Timeout.
- * @param rd Wait for read if @c true, or for write if @c false.
- * @return -errno on error, WaitResult::TIMEOUT on timeout and
- * WaitResult::SUCCESS on success.
- */
- int WaitOnSocket(int32_t timeout, bool rd);
-
- /** Handle. */
- intptr_t socketHandle;
-
- /** Blocking flag. */
- bool blocking;
-
- IGNITE_NO_COPY_ASSIGNMENT(SocketClient)
- };
- }
- }
-}
-
-#endif //_IGNITE_ODBC_SYSTEM_SOCKET_CLIENT
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/system/tcp_socket_client.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/system/tcp_socket_client.h b/modules/platforms/cpp/odbc/include/ignite/odbc/system/tcp_socket_client.h
new file mode 100644
index 0000000..a3c9c30
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/system/tcp_socket_client.h
@@ -0,0 +1,151 @@
+/*
+ * 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 _IGNITE_ODBC_SYSTEM_TCP_SOCKET_CLIENT
+#define _IGNITE_ODBC_SYSTEM_TCP_SOCKET_CLIENT
+
+#include <stdint.h>
+
+#include "ignite/common/common.h"
+#include "ignite/odbc/diagnostic/diagnosable.h"
+#include "ignite/odbc/socket_client.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace system
+ {
+ /**
+ * Socket client implementation.
+ */
+ class TcpSocketClient : public SocketClient
+ {
+ public:
+ /** Buffers size */
+ enum { BUFFER_SIZE = 0x10000 };
+
+ /** The time in seconds the connection needs to remain idle before starts sending keepalive probes. */
+ enum { KEEP_ALIVE_IDLE_TIME = 60 };
+
+ /** The time in seconds between individual keepalive probes. */
+ enum { KEEP_ALIVE_PROBES_PERIOD = 1 };
+
+ /**
+ * Constructor.
+ */
+ TcpSocketClient();
+
+ /**
+ * Destructor.
+ */
+ virtual ~TcpSocketClient();
+
+ /**
+ * Establish connection with remote TCP service.
+ *
+ * @param hostname Remote host name.
+ * @param port TCP service port.
+ * @param diag Diagnostics collector.
+ * @return True on success.
+ */
+ virtual bool Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag);
+
+ /**
+ * Close established connection.
+ *
+ * @return True on success.
+ */
+ virtual void Close();
+
+ /**
+ * Send data by established connection.
+ *
+ * @param data Pointer to data to be sent.
+ * @param size Size of the data in bytes.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been sent on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Send(const int8_t* data, size_t size, int32_t timeout);
+
+ /**
+ * Receive data from established connection.
+ *
+ * @param buffer Pointer to data buffer.
+ * @param size Size of the buffer in bytes.
+ * @param timeout Timeout.
+ * @return Number of bytes that have been received on success,
+ * WaitResult::TIMEOUT on timeout and -errno on failure.
+ */
+ virtual int Receive(int8_t* buffer, size_t size, int32_t timeout);
+
+ /**
+ * Check if the socket is blocking or not.
+ * @return @c true if the socket is blocking and false otherwise.
+ */
+ virtual bool IsBlocking() const;
+
+ /**
+ * Get socket error.
+ * @return Last socket error.
+ */
+ static int GetLastSocketError();
+
+ /**
+ * Get socket error.
+ * @param handle Socket handle.
+ * @return Last socket error.
+ */
+ static int GetLastSocketError(int handle);
+
+ /**
+ * Check whether socket operation was interupted.
+ * @return @c true if the socket operation was interupted.
+ */
+ static bool IsSocketOperationInterrupted(int errorCode);
+ private:
+ /**
+ * Tries set socket options.
+ */
+ void TrySetOptions(diagnostic::Diagnosable& diag);
+
+ /**
+ * Wait on the socket for any event for specified time.
+ * This function uses poll to achive timeout functionality
+ * for every separate socket operation.
+ *
+ * @param timeout Timeout.
+ * @param rd Wait for read if @c true, or for write if @c false.
+ * @return -errno on error, WaitResult::TIMEOUT on timeout and
+ * WaitResult::SUCCESS on success.
+ */
+ int WaitOnSocket(int32_t timeout, bool rd);
+
+ /** Handle. */
+ intptr_t socketHandle;
+
+ /** Blocking flag. */
+ bool blocking;
+
+ IGNITE_NO_COPY_ASSIGNMENT(TcpSocketClient)
+ };
+ }
+ }
+}
+
+#endif //_IGNITE_ODBC_SYSTEM_SOCKET_CLIENT
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
index 90286b9..b903414 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
@@ -41,7 +41,9 @@ namespace ignite
{
enum Type
{
- CONNECTION_SETTINGS_GROUP_BOX,
+ CONNECTION_SETTINGS_GROUP_BOX = 100,
+ SSL_SETTINGS_GROUP_BOX,
+ ADDITIONAL_SETTINGS_GROUP_BOX,
NAME_EDIT,
NAME_LABEL,
ADDRESS_EDIT,
@@ -58,11 +60,34 @@ namespace ignite
SKIP_REDUCER_ON_UPDATE_CHECK_BOX,
PROTOCOL_VERSION_LABEL,
PROTOCOL_VERSION_COMBO_BOX,
+ SSL_MODE_LABEL,
+ SSL_MODE_COMBO_BOX,
+ SSL_KEY_FILE_LABEL,
+ SSL_KEY_FILE_EDIT,
+ SSL_CERT_FILE_LABEL,
+ SSL_CERT_FILE_EDIT,
+ SSL_CA_FILE_LABEL,
+ SSL_CA_FILE_EDIT,
OK_BUTTON,
CANCEL_BUTTON
};
};
+ // Window margin size.
+ enum { MARGIN = 10 };
+
+ // Standard interval between UI elements.
+ enum { INTERVAL = 10 };
+
+ // Standard row height.
+ enum { ROW_HEIGHT = 20 };
+
+ // Standard button width.
+ enum { BUTTON_WIDTH = 80 };
+
+ // Standard button height.
+ enum { BUTTON_HEIGHT = 25 };
+
public:
/**
* Constructor.
@@ -102,6 +127,60 @@ namespace ignite
*/
void RetrieveParameters(config::Configuration& cfg) const;
+ /**
+ * Retrieves current values from the connection UI group and
+ * stores them to the specified configuration.
+ *
+ * @param cfg Configuration.
+ */
+ void RetrieveConnectionParameters(config::Configuration& cfg) const;
+
+ /**
+ * Retrieves current values from the SSL UI group and
+ * stores them to the specified configuration.
+ *
+ * @param cfg Configuration.
+ */
+ void RetrieveSslParameters(config::Configuration& cfg) const;
+
+ /**
+ * Retrieves current values from the additional UI group and
+ * stores them to the specified configuration.
+ *
+ * @param cfg Configuration.
+ */
+ void RetrieveAdditionalParameters(config::Configuration& cfg) const;
+
+ /**
+ * Create connection settings group box.
+ *
+ * @param posX X position.
+ * @param posY Y position.
+ * @param sizeX Width.
+ * @return Size by Y.
+ */
+ int CreateConnectionSettingsGroup(int posX, int posY, int sizeX);
+
+ /**
+ * Create SSL settings group box.
+ *
+ * @param posX X position.
+ * @param posY Y position.
+ * @param sizeX Width.
+ * @return Size by Y.
+ */
+ int CreateSslSettingsGroup(int posX, int posY, int sizeX);
+
+ /**
+ * Create additional settings group box.
+ *
+ * @param posX X position.
+ * @param posY Y position.
+ * @param sizeX Width.
+ * @return Size by Y.
+ */
+ int CreateAdditionalSettingsGroup(int posX, int posY, int sizeX);
+
/** Window width. */
int width;
@@ -111,6 +190,12 @@ namespace ignite
/** Connection settings group box. */
std::auto_ptr<Window> connectionSettingsGroupBox;
+ /** SSL settings group box. */
+ std::auto_ptr<Window> sslSettingsGroupBox;
+
+ /** Additional settings group box. */
+ std::auto_ptr<Window> additionalSettingsGroupBox;
+
/** DSN name edit field label. */
std::auto_ptr<Window> nameLabel;
@@ -165,6 +250,30 @@ namespace ignite
/** Cancel button. */
std::auto_ptr<Window> cancelButton;
+ /** SSL Mode label. */
+ std::auto_ptr<Window> sslModeLabel;
+
+ /** SSL Mode ComboBox. */
+ std::auto_ptr<Window> sslModeComboBox;
+
+ /** SSL Private Key File label. */
+ std::auto_ptr<Window> sslKeyFileLabel;
+
+ /** SSL Private Key File edit. */
+ std::auto_ptr<Window> sslKeyFileEdit;
+
+ /** SSL Certificate File label. */
+ std::auto_ptr<Window> sslCertFileLabel;
+
+ /** SSL Certificate File edit. */
+ std::auto_ptr<Window> sslCertFileEdit;
+
+ /** SSL Certificate Authority File label. */
+ std::auto_ptr<Window> sslCaFileLabel;
+
+ /** SSL Certificate Authority File edit. */
+ std::auto_ptr<Window> sslCaFileEdit;
+
/** Configuration. */
config::Configuration& config;
@@ -176,4 +285,4 @@ namespace ignite
}
}
-#endif //_IGNITE_ODBC_SYSTEM_UI_DSN_CONFIGURATION_WINDOW
\ No newline at end of file
+#endif //_IGNITE_ODBC_SYSTEM_UI_DSN_CONFIGURATION_WINDOW
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp b/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp
deleted file mode 100644
index a6d6151..0000000
--- a/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <cstring>
-
-#include <sstream>
-
-#include "ignite/odbc/system/socket_client.h"
-#include "ignite/odbc/utility.h"
-#include "ignite/odbc/log.h"
-
-#define SOCKET_ERROR (-1)
-
-namespace
-{
- /**
- * Get last socket error message.
- * @param error Error code.
- * @return Last socket error message string.
- */
- std::string GetSocketErrorMessage(int error)
- {
- std::stringstream res;
-
- res << "error_code=" << error;
-
- if (error == 0)
- return res.str();
-
- char buffer[1024] = "";
-
- if (!strerror_r(error, buffer, sizeof(buffer)))
- res << ", msg=" << buffer;
-
- return res.str();
- }
-
- /**
- * Get last socket error message.
- * @return Last socket error message string.
- */
- std::string GetLastSocketErrorMessage()
- {
- int lastError = errno;
-
- return GetSocketErrorMessage(lastError);
- }
-}
-
-namespace ignite
-{
- namespace odbc
- {
- namespace tcp
- {
-
- SocketClient::SocketClient() :
- socketHandle(SOCKET_ERROR),
- blocking(true)
- {
- // No-op.
- }
-
- SocketClient::~SocketClient()
- {
- Close();
- }
-
- bool SocketClient::Connect(const char* hostname, uint16_t port, diagnostic::Diagnosable& diag)
- {
- LOG_MSG("Host: " << hostname << ", port: " << port);
-
- addrinfo hints;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- std::stringstream converter;
- converter << port;
-
- // Resolve the server address and port
- addrinfo *result = NULL;
- int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result);
-
- if (res != 0)
- {
- LOG_MSG("Address resolving failed: " << gai_strerror(res));
-
- diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not resolve host address.");
-
- return false;
- }
-
- // Attempt to connect to an address until one succeeds
- for (addrinfo *it = result; it != NULL; it = it->ai_next)
- {
- LOG_MSG("Addr: " << (it->ai_addr->sa_data[2] & 0xFF) << "."
- << (it->ai_addr->sa_data[3] & 0xFF) << "."
- << (it->ai_addr->sa_data[4] & 0xFF) << "."
- << (it->ai_addr->sa_data[5] & 0xFF));
-
- // Create a SOCKET for connecting to server
- socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
-
- if (socketHandle == SOCKET_ERROR)
- {
- LOG_MSG("Socket creation failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, "Can not create new socket.");
-
- return false;
- }
-
- diag.GetDiagnosticRecords().Reset();
-
- TrySetOptions(diag);
-
- // Connect to server.
- res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen));
- if (SOCKET_ERROR == res)
- {
- int lastError = errno;
-
- if (lastError != EWOULDBLOCK && lastError != EINPROGRESS)
- {
- LOG_MSG("Connection failed: " << GetSocketErrorMessage(lastError));
-
- Close();
-
- continue;
- }
-
- res = WaitOnSocket(CONNECT_TIMEOUT, false);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- {
- LOG_MSG("Connection timeout expired: " << GetSocketErrorMessage(-res));
-
- Close();
-
- continue;
- }
- }
- break;
- }
-
- freeaddrinfo(result);
-
- return socketHandle != SOCKET_ERROR;
- }
-
- void SocketClient::Close()
- {
- if (socketHandle != SOCKET_ERROR)
- {
- close(socketHandle);
-
- socketHandle = SOCKET_ERROR;
- }
- }
-
- int SocketClient::Send(const int8_t* data, size_t size, int32_t timeout)
- {
- if (!blocking)
- {
- int res = WaitOnSocket(timeout, false);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- return res;
- }
-
- return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0);
- }
-
- int SocketClient::Receive(int8_t* buffer, size_t size, int32_t timeout)
- {
- if (!blocking)
- {
- int res = WaitOnSocket(timeout, true);
-
- if (res < 0 || res == WaitResult::TIMEOUT)
- return res;
- }
-
- return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0);
- }
-
- void SocketClient::TrySetOptions(diagnostic::Diagnosable& diag)
- {
- int trueOpt = 1;
- int bufSizeOpt = BUFFER_SIZE;
- int idleOpt = KEEP_ALIVE_IDLE_TIME;
- int idleRetryOpt = KEEP_ALIVE_PROBES_PERIOD;
-
- int res = setsockopt(socketHandle, SOL_SOCKET, SO_SNDBUF,
- reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP socket send buffer size setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP socket send buffer size");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_RCVBUF,
- reinterpret_cast<char*>(&bufSizeOpt), sizeof(bufSizeOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP socket receive buffer size setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP socket receive buffer size");
- }
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_NODELAY,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP no-delay mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP no-delay mode");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_OOBINLINE,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP out-of-bound data inlining setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP out-of-bound data inlining");
- }
-
- blocking = false;
-
- int flags;
- if (((flags = fcntl(socketHandle, F_GETFL, 0)) < 0) ||
- (fcntl(socketHandle, F_SETFL, flags | O_NONBLOCK) < 0))
- {
- blocking = true;
- LOG_MSG("Non-blocking mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up non-blocking mode. Timeouts are not available.");
- }
-
- res = setsockopt(socketHandle, SOL_SOCKET, SO_KEEPALIVE,
- reinterpret_cast<char*>(&trueOpt), sizeof(trueOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive mode setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive mode");
-
- // There is no sense in configuring keep alive params if we faileed to set up keep alive mode.
- return;
- }
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPIDLE,
- reinterpret_cast<char*>(&idleOpt), sizeof(idleOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive idle timeout setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive idle timeout");
- }
-
- res = setsockopt(socketHandle, IPPROTO_TCP, TCP_KEEPINTVL,
- reinterpret_cast<char*>(&idleRetryOpt), sizeof(idleRetryOpt));
-
- if (SOCKET_ERROR == res)
- {
- LOG_MSG("TCP keep-alive probes period setup failed: " << GetLastSocketErrorMessage());
-
- diag.AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
- "Can not set up TCP keep-alive probes period");
- }
-
- }
-
- int SocketClient::WaitOnSocket(int32_t timeout, bool rd)
- {
- int ready = 0;
- int lastError = 0;
-
- fd_set fds;
-
- do {
- struct timeval tv = { 0 };
- tv.tv_sec = timeout;
-
- FD_ZERO(&fds);
- FD_SET(socketHandle, &fds);
-
- fd_set* readFds = 0;
- fd_set* writeFds = 0;
-
- if (rd)
- readFds = &fds;
- else
- writeFds = &fds;
-
- ready = select(static_cast<int>((socketHandle) + 1),
- readFds, writeFds, NULL, (timeout == 0 ? NULL : &tv));
-
- if (ready == SOCKET_ERROR)
- lastError = errno;
-
- } while (ready == SOCKET_ERROR && lastError == EINTR);
-
- if (ready == SOCKET_ERROR)
- return -lastError;
-
- socklen_t size = sizeof(lastError);
- int res = getsockopt(socketHandle, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&lastError), &size);
-
- if (res != SOCKET_ERROR && lastError != 0)
- return -lastError;
-
- if (ready == 0)
- return WaitResult::TIMEOUT;
-
- return WaitResult::SUCCESS;
- }
- }
- }
-}
-
[4/4] ignite git commit: IGNITE-6810: Implemented SSL support for
ODBC.
Posted by is...@apache.org.
IGNITE-6810: Implemented SSL support for ODBC.
This closes #3361
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/394019ee
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/394019ee
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/394019ee
Branch: refs/heads/master
Commit: 394019eef7b840eccb3a4d6cae18e359db6ff68d
Parents: a824ba8
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Jan 30 15:56:17 2018 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Jan 30 15:57:30 2018 +0300
----------------------------------------------------------------------
.../ClientConnectorConfiguration.java | 116 +++++
.../odbc/ClientListenerBufferedParser.java | 6 +-
.../odbc/ClientListenerNioListener.java | 8 +
.../odbc/ClientListenerNioServerBuffer.java | 12 +-
.../odbc/ClientListenerProcessor.java | 71 ++-
.../include/ignite/common/platform_utils.h | 17 +
.../cpp/common/include/ignite/common/utils.h | 7 +
.../os/linux/src/common/platform_utils.cpp | 15 +
.../os/win/src/common/dynamic_load_os.cpp | 4 +
.../common/os/win/src/common/platform_utils.cpp | 15 +
.../platforms/cpp/common/src/common/utils.cpp | 9 +
.../cpp/core-test/src/cache_query_test.cpp | 15 +-
modules/platforms/cpp/odbc-test/Makefile.am | 1 +
.../cpp/odbc-test/config/queries-default.xml | 10 +-
.../cpp/odbc-test/config/queries-ssl-32.xml | 77 ++++
.../cpp/odbc-test/config/queries-ssl.xml | 59 +++
.../cpp/odbc-test/config/queries-test-32.xml | 3 +-
.../odbc-test/config/queries-test-default.xml | 39 --
.../odbc-test/config/queries-test-noodbc-32.xml | 53 ---
.../odbc-test/config/queries-test-noodbc.xml | 35 --
.../cpp/odbc-test/config/queries-test.xml | 3 +-
.../platforms/cpp/odbc-test/config/ssl/ca.pem | 24 +
.../cpp/odbc-test/config/ssl/client_full.pem | 84 ++++
.../cpp/odbc-test/config/ssl/client_unknown.pem | 50 ++
.../cpp/odbc-test/config/ssl/server.jks | Bin 0 -> 4256 bytes
.../cpp/odbc-test/config/ssl/trust.jks | Bin 0 -> 1089 bytes
.../cpp/odbc-test/include/odbc_test_suite.h | 8 +-
.../cpp/odbc-test/include/test_utils.h | 5 +
.../cpp/odbc-test/project/vs/odbc-test.vcxproj | 15 +-
.../project/vs/odbc-test.vcxproj.filters | 14 +-
.../cpp/odbc-test/src/api_robustness_test.cpp | 101 +---
.../platforms/cpp/odbc-test/src/errors_test.cpp | 90 +---
.../cpp/odbc-test/src/meta_queries_test.cpp | 96 +---
.../cpp/odbc-test/src/odbc_test_suite.cpp | 40 +-
.../cpp/odbc-test/src/queries_ssl_test.cpp | 283 ++++++++++++
.../cpp/odbc-test/src/queries_test.cpp | 14 +-
.../odbc-test/src/sql_test_suite_fixture.cpp | 4 +
.../platforms/cpp/odbc-test/src/test_utils.cpp | 9 +
modules/platforms/cpp/odbc/Makefile.am | 5 +-
modules/platforms/cpp/odbc/include/Makefile.am | 6 +-
.../include/ignite/odbc/config/configuration.h | 110 ++++-
.../cpp/odbc/include/ignite/odbc/connection.h | 9 +-
.../odbc/include/ignite/odbc/socket_client.h | 109 +++++
.../ignite/odbc/ssl/secure_socket_client.h | 148 ++++++
.../odbc/include/ignite/odbc/ssl/ssl_bindings.h | 303 ++++++++++++
.../odbc/include/ignite/odbc/ssl/ssl_gateway.h | 151 ++++++
.../cpp/odbc/include/ignite/odbc/ssl/ssl_mode.h | 55 +++
.../include/ignite/odbc/system/socket_client.h | 151 ------
.../ignite/odbc/system/tcp_socket_client.h | 151 ++++++
.../odbc/system/ui/dsn_configuration_window.h | 113 ++++-
.../odbc/os/linux/src/system/socket_client.cpp | 360 ---------------
.../os/linux/src/system/tcp_socket_client.cpp | 384 +++++++++++++++
.../odbc/os/win/src/system/socket_client.cpp | 432 -----------------
.../os/win/src/system/tcp_socket_client.cpp | 462 +++++++++++++++++++
.../src/system/ui/dsn_configuration_window.cpp | 315 +++++++++----
.../cpp/odbc/os/win/src/system/ui/window.cpp | 9 +-
.../platforms/cpp/odbc/project/vs/odbc.vcxproj | 36 +-
.../cpp/odbc/project/vs/odbc.vcxproj.filters | 39 +-
.../cpp/odbc/src/config/configuration.cpp | 8 +
modules/platforms/cpp/odbc/src/connection.cpp | 66 ++-
modules/platforms/cpp/odbc/src/dsn_config.cpp | 24 +-
modules/platforms/cpp/odbc/src/odbc.cpp | 2 +-
.../cpp/odbc/src/ssl/secure_socket_client.cpp | 419 +++++++++++++++++
.../platforms/cpp/odbc/src/ssl/ssl_gateway.cpp | 210 +++++++++
modules/platforms/cpp/odbc/src/ssl/ssl_mode.cpp | 43 ++
65 files changed, 3992 insertions(+), 1540 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java
index 5827333..ed30db3 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java
@@ -17,7 +17,10 @@
package org.apache.ignite.configuration;
+import javax.cache.configuration.Factory;
+import javax.net.ssl.SSLContext;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.ssl.SslContextFactory;
import org.jetbrains.annotations.Nullable;
/**
@@ -45,6 +48,9 @@ public class ClientConnectorConfiguration {
/** Default idle timeout. */
public static final int DFLT_IDLE_TIMEOUT = 0;
+ /** Default value of whether to use Ignite SSL context factory. */
+ public static final boolean DFLT_USE_IGNITE_SSL_CTX_FACTORY = true;
+
/** Host. */
private String host;
@@ -81,6 +87,18 @@ public class ClientConnectorConfiguration {
/** JDBC connections enabled flag. */
private boolean thinCliEnabled = true;
+ /** SSL enable flag, default is disabled. */
+ private boolean sslEnabled;
+
+ /** If to use SSL context factory from Ignite configuration. */
+ private boolean useIgniteSslCtxFactory = DFLT_USE_IGNITE_SSL_CTX_FACTORY;
+
+ /** SSL need client auth flag. */
+ private boolean sslClientAuth;
+
+ /** SSL connection factory. */
+ private Factory<SSLContext> sslCtxFactory;
+
/**
* Creates SQL connector configuration with all default values.
*/
@@ -105,6 +123,10 @@ public class ClientConnectorConfiguration {
tcpNoDelay = cfg.isTcpNoDelay();
threadPoolSize = cfg.getThreadPoolSize();
idleTimeout = cfg.getIdleTimeout();
+ sslEnabled = cfg.isSslEnabled();
+ sslClientAuth = cfg.isSslClientAuth();
+ useIgniteSslCtxFactory = cfg.isUseIgniteSslContextFactory();
+ sslCtxFactory = cfg.getSslContextFactory();
}
/**
@@ -385,6 +407,100 @@ public class ClientConnectorConfiguration {
return this;
}
+ /**
+ * Whether secure socket layer should be enabled on client connector.
+ * <p>
+ * Note that if this flag is set to {@code true}, an instance of {@code Factory<SSLContext>}
+ * should be provided, otherwise client connector will fail to start.
+ *
+ * @return {@code True} if SSL should be enabled.
+ */
+ public boolean isSslEnabled() {
+ return sslEnabled;
+ }
+
+ /**
+ * Sets whether Secure Socket Layer should be enabled for client connector.
+ * <p/>
+ * Note that if this flag is set to {@code true}, then a valid instance of {@code Factory<SSLContext>}
+ * should be provided in {@link IgniteConfiguration}. Otherwise, TCP binary protocol will fail to start.
+ *
+ * @param sslEnabled {@code True} if SSL should be enabled.
+ * @return {@code this} for chaining.
+ */
+ public ClientConnectorConfiguration setSslEnabled(boolean sslEnabled) {
+ this.sslEnabled = sslEnabled;
+
+ return this;
+ }
+
+ /**
+ * Gets whether to use Ignite SSL context factory configured through
+ * {@link IgniteConfiguration#getSslContextFactory()} if {@link #getSslContextFactory()} is not set.
+ *
+ * @return {@code True} if Ignite SSL context factory can be used.
+ */
+ public boolean isUseIgniteSslContextFactory() {
+ return useIgniteSslCtxFactory;
+ }
+
+ /**
+ * Sets whether to use Ignite SSL context factory. See {@link #isUseIgniteSslContextFactory()} for more information.
+ *
+ * @param useIgniteSslCtxFactory Whether to use Ignite SSL context factory
+ * @return {@code this} for chaining.
+ */
+ public ClientConnectorConfiguration setUseIgniteSslContextFactory(boolean useIgniteSslCtxFactory) {
+ this.useIgniteSslCtxFactory = useIgniteSslCtxFactory;
+
+ return this;
+ }
+
+ /**
+ * Gets a flag indicating whether or not remote clients will be required to have a valid SSL certificate which
+ * validity will be verified with trust manager.
+ *
+ * @return Whether or not client authentication is required.
+ */
+ public boolean isSslClientAuth() {
+ return sslClientAuth;
+ }
+
+ /**
+ * Sets flag indicating whether or not SSL client authentication is required.
+ *
+ * @param sslClientAuth Whether or not client authentication is required.
+ * @return {@code this} for chaining.
+ */
+ public ClientConnectorConfiguration setSslClientAuth(boolean sslClientAuth) {
+ this.sslClientAuth = sslClientAuth;
+
+ return this;
+ }
+
+ /**
+ * Sets SSL context factory that will be used for creating a secure socket layer.
+ *
+ * @param sslCtxFactory Ssl context factory.
+ * @see SslContextFactory
+ * @return {@code this} for chaining.
+ */
+ public ClientConnectorConfiguration setSslContextFactory(Factory<SSLContext> sslCtxFactory) {
+ this.sslCtxFactory = sslCtxFactory;
+
+ return this;
+ }
+
+ /**
+ * Returns SSL context factory that will be used for creating a secure socket layer.
+ *
+ * @return SSL connection factory.
+ * @see SslContextFactory
+ */
+ public Factory<SSLContext> getSslContextFactory() {
+ return sslCtxFactory;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(ClientConnectorConfiguration.class, this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerBufferedParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerBufferedParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerBufferedParser.java
index eb7bfe8..8dd26b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerBufferedParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerBufferedParser.java
@@ -55,7 +55,9 @@ public class ClientListenerBufferedParser implements GridNioParser {
assert old == null;
}
- return nioBuf.read(buf);
+ boolean checkHandshake = ses.meta(ClientListenerNioListener.CONN_CTX_HANDSHAKE_PASSED) == null;
+
+ return nioBuf.read(buf, checkHandshake);
}
/** {@inheritDoc} */
@@ -78,4 +80,4 @@ public class ClientListenerBufferedParser implements GridNioParser {
@Override public String toString() {
return ClientListenerBufferedParser.class.getSimpleName();
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
index 43276a5..f472a9f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
@@ -48,6 +48,12 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte
/** Thin client handshake code. */
public static final byte THIN_CLIENT = 2;
+ /** Connection handshake passed. */
+ public static final int CONN_CTX_HANDSHAKE_PASSED = GridNioSessionMetaKey.nextUniqueKey();
+
+ /** Maximum size of the handshake message. */
+ public static final int MAX_HANDSHAKE_MSG_SIZE = 128;
+
/** Connection-related metadata key. */
private static final int CONN_CTX_META_KEY = GridNioSessionMetaKey.nextUniqueKey();
@@ -114,6 +120,8 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte
if (connCtx == null) {
onHandshake(ses, msg);
+ ses.addMeta(CONN_CTX_HANDSHAKE_PASSED, true);
+
return;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioServerBuffer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioServerBuffer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioServerBuffer.java
index 30ee69f..6ee6e71 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioServerBuffer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioServerBuffer.java
@@ -64,10 +64,11 @@ public class ClientListenerNioServerBuffer {
/**
* @param buf Buffer.
+ * @param checkHandshake Check handshake.
* @return Message bytes or {@code null} if message is not fully read yet.
* @throws IgniteCheckedException If failed to parse message.
*/
- @Nullable public byte[] read(ByteBuffer buf) throws IgniteCheckedException {
+ @Nullable public byte[] read(ByteBuffer buf, boolean checkHandshake) throws IgniteCheckedException {
if (cnt < 0) {
for (; cnt < 0 && buf.hasRemaining(); cnt++)
msgSize |= (buf.get() & 0xFF) << (8*(4 + cnt));
@@ -108,7 +109,12 @@ public class ClientListenerNioServerBuffer {
return data0;
}
- else
+ else {
+ if (checkHandshake && cnt > 0 && (msgSize > ClientListenerNioListener.MAX_HANDSHAKE_MSG_SIZE
+ || data[0] != ClientListenerRequest.HANDSHAKE))
+ throw new IgniteCheckedException("Invalid handshake message");
+
return null;
+ }
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java
index a490cfc..eaa9c7a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java
@@ -21,6 +21,8 @@ import java.net.InetAddress;
import java.nio.ByteOrder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
+import javax.cache.configuration.Factory;
+import javax.net.ssl.SSLContext;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.configuration.ClientConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
@@ -35,10 +37,12 @@ import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
import org.apache.ignite.internal.util.nio.GridNioFilter;
import org.apache.ignite.internal.util.nio.GridNioServer;
import org.apache.ignite.internal.util.nio.GridNioSession;
+import org.apache.ignite.internal.util.nio.ssl.GridNioSslFilter;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.spi.IgnitePortProtocol;
import org.apache.ignite.thread.IgniteThreadPoolExecutor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -110,20 +114,13 @@ public class ClientListenerProcessor extends GridProcessorAdapter {
if (portTo <= 0) // Handle int overflow.
portTo = Integer.MAX_VALUE;
+ GridNioFilter[] filters = makeFilters(cliConnCfg);
+
+ int maxOpenCursors = cliConnCfg.getMaxOpenCursorsPerConnection();
+ long idleTimeout = cliConnCfg.getIdleTimeout();
+
for (int port = cliConnCfg.getPort(); port <= portTo && port <= 65535; port++) {
try {
- GridNioFilter[] filters = new GridNioFilter[] {
- new GridNioAsyncNotifyFilter(ctx.igniteInstanceName(), execSvc, log) {
- @Override public void onSessionOpened(GridNioSession ses)
- throws IgniteCheckedException {
- proceedSessionOpened(ses);
- }
- },
- new GridNioCodecFilter(new ClientListenerBufferedParser(), log, false)
- };
-
- long idleTimeout = cliConnCfg.getIdleTimeout();
-
GridNioServer<byte[]> srv0 = GridNioServer.<byte[]>builder()
.address(hostAddr)
.port(port)
@@ -173,6 +170,54 @@ public class ClientListenerProcessor extends GridProcessorAdapter {
}
}
+ /**
+ * Make NIO server filters.
+ * @param cliConnCfg Client configuration.
+ * @return Array of filters, suitable for the configuration.
+ * @throws IgniteCheckedException if provided SslContextFactory is null.
+ */
+ @NotNull private GridNioFilter[] makeFilters(@NotNull ClientConnectorConfiguration cliConnCfg)
+ throws IgniteCheckedException {
+ GridNioFilter openSesFilter = new GridNioAsyncNotifyFilter(ctx.igniteInstanceName(), execSvc, log) {
+ @Override public void onSessionOpened(GridNioSession ses)
+ throws IgniteCheckedException {
+ proceedSessionOpened(ses);
+ }
+ };
+
+ GridNioFilter codecFilter = new GridNioCodecFilter(new ClientListenerBufferedParser(), log, false);
+
+ if (cliConnCfg.isSslEnabled()) {
+ Factory<SSLContext> sslCtxFactory = cliConnCfg.isUseIgniteSslContextFactory() ?
+ ctx.config().getSslContextFactory() : cliConnCfg.getSslContextFactory();
+
+ if (sslCtxFactory == null)
+ throw new IgniteCheckedException("Failed to create client listener " +
+ "(SSL is enabled but factory is null). Check the ClientConnectorConfiguration");
+
+ GridNioSslFilter sslFilter = new GridNioSslFilter(sslCtxFactory.create(),
+ true, ByteOrder.nativeOrder(), log);
+
+ sslFilter.directMode(false);
+
+ boolean auth = cliConnCfg.isSslClientAuth();
+
+ sslFilter.wantClientAuth(auth);
+ sslFilter.needClientAuth(auth);
+
+ return new GridNioFilter[] {
+ openSesFilter,
+ codecFilter,
+ sslFilter
+ };
+ } else {
+ return new GridNioFilter[] {
+ openSesFilter,
+ codecFilter
+ };
+ }
+ }
+
/** {@inheritDoc} */
@Override public void onKernalStop(boolean cancel) {
if (srv != null) {
@@ -203,7 +248,7 @@ public class ClientListenerProcessor extends GridProcessorAdapter {
/**
* Prepare connector configuration.
*
- * @param cfg Ignote configuration.
+ * @param cfg Ignite configuration.
* @return Connector configuration.
* @throws IgniteCheckedException If failed.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
index b8c6aa6..83da6ec 100644
--- a/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/platform_utils.h
@@ -17,12 +17,15 @@
#ifndef _IGNITE_COMMON_PLATFORM_UTILS
#define _IGNITE_COMMON_PLATFORM_UTILS
+#include <iostream>
#include <ignite/common/common.h>
namespace ignite
{
namespace common
{
+ typedef std::basic_ostream<char, std::char_traits<char> > StdCharOutStream;
+
/**
* Convert struct tm to time_t (UTC).
*
@@ -87,6 +90,20 @@ namespace ignite
* @return @c true if the provided path is the valid directory.
*/
IGNITE_IMPORT_EXPORT bool IsValidDirectory(const std::string& path);
+
+ /**
+ * Write file separator to a stream.
+ * @param ostr Stream.
+ * @return The same stream for chaining.
+ */
+ IGNITE_IMPORT_EXPORT StdCharOutStream& Fs(StdCharOutStream& ostr);
+
+ /**
+ * Write dynamic library expansion to a stream.
+ * @param ostr Stream.
+ * @return The same stream for chaining.
+ */
+ IGNITE_IMPORT_EXPORT StdCharOutStream& Dle(StdCharOutStream& ostr);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/include/ignite/common/utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/utils.h b/modules/platforms/cpp/common/include/ignite/common/utils.h
index 5022897..792bd60 100644
--- a/modules/platforms/cpp/common/include/ignite/common/utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/utils.h
@@ -476,6 +476,13 @@ namespace ignite
{
return BoundInstance<R, T>(instance, mfunc);
}
+
+ /**
+ * Get dynamic library full name.
+ * @param name Name without extension.
+ * @return Full name.
+ */
+ IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
index b74f11c..88ba8ed 100644
--- a/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/linux/src/common/platform_utils.cpp
@@ -89,5 +89,20 @@ namespace ignite
return stat(path.c_str(), &pathStat) != -1 && S_ISDIR(pathStat.st_mode);
}
+
+ StdCharOutStream& Fs(StdCharOutStream& ostr)
+ {
+ ostr.put('/');
+ return ostr;
+ }
+
+ StdCharOutStream& Dle(StdCharOutStream& ostr)
+ {
+ static const char expansion[] = ".so";
+
+ ostr.write(expansion, sizeof(expansion) - 1);
+
+ return ostr;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
index f7812cd..76ca28b 100644
--- a/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
+++ b/modules/platforms/cpp/common/os/win/src/common/dynamic_load_os.cpp
@@ -85,7 +85,11 @@ namespace ignite
void Module::Unload()
{
if (IsLoaded())
+ {
FreeLibrary(handle);
+
+ handle = NULL;
+ }
}
Module LoadModule(const char* path)
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
index a0f4505..057a3d4 100644
--- a/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
+++ b/modules/platforms/cpp/common/os/win/src/common/platform_utils.cpp
@@ -91,5 +91,20 @@ namespace ignite
return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
+
+ StdCharOutStream& Fs(StdCharOutStream& ostr)
+ {
+ ostr.put('\\');
+ return ostr;
+ }
+
+ StdCharOutStream& Dle(StdCharOutStream& ostr)
+ {
+ static const char expansion[] = ".dll";
+
+ ostr.write(expansion, sizeof(expansion) - 1);
+
+ return ostr;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/common/src/common/utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/common/utils.cpp b/modules/platforms/cpp/common/src/common/utils.cpp
index 786d0fb..54a7d03 100644
--- a/modules/platforms/cpp/common/src/common/utils.cpp
+++ b/modules/platforms/cpp/common/src/common/utils.cpp
@@ -180,5 +180,14 @@ namespace ignite
return CTimeToTimestamp(localTime, ns);
}
+
+ std::string GetDynamicLibraryName(const char* name)
+ {
+ std::stringstream libNameBuffer;
+
+ libNameBuffer << name << Dle;
+
+ return libNameBuffer.str();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index 4993279..9dfd879 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -969,10 +969,11 @@ BOOST_AUTO_TEST_CASE(TestSqlQueryDistributedJoins)
// Starting second node.
Ignite node2 = StartNode("Node2");
+ int firstKey = 0;
int entryCnt = 1000;
// Filling caches
- for (int i = 0; i < entryCnt; i++)
+ for (int i = firstKey; i < firstKey + entryCnt; i++)
{
std::stringstream stream;
@@ -987,7 +988,8 @@ BOOST_AUTO_TEST_CASE(TestSqlQueryDistributedJoins)
// Test query with no results.
SqlQuery qry("QueryPerson",
"from \"QueryPerson\".QueryPerson, \"QueryRelation\".QueryRelation "
- "where \"QueryPerson\".QueryPerson.age = \"QueryRelation\".QueryRelation.someVal");
+ "where (\"QueryPerson\".QueryPerson.age = \"QueryRelation\".QueryRelation.someVal) "
+ "and (\"QueryPerson\".QueryPerson._key < 1000)");
QueryCursor<int, QueryPerson> cursor = cache1.Query(qry);
@@ -1245,17 +1247,18 @@ BOOST_AUTO_TEST_CASE(TestSqlFieldsQueryDistributedJoins)
// Starting second node.
Ignite node2 = StartNode("Node2");
+ int firstKey = 2000;
int entryCnt = 1000;
// Filling caches
- for (int i = 0; i < entryCnt; i++)
+ for (int i = firstKey; i < firstKey + entryCnt; i++)
{
std::stringstream stream;
stream << "A" << i;
cache1.Put(i, QueryPerson(stream.str(), i * 10, MakeDateGmt(1970 + i),
- MakeTimestampGmt(2016, 1, 1, i / 60, i % 60)));
+ MakeTimestampGmt(2016, 1, 1, (i / 60) % 24, i % 60)));
cache2.Put(i + 1, QueryRelation(i, i * 10));
}
@@ -1265,7 +1268,9 @@ BOOST_AUTO_TEST_CASE(TestSqlFieldsQueryDistributedJoins)
"select age, name "
"from \"QueryPerson\".QueryPerson "
"inner join \"QueryRelation\".QueryRelation "
- "on \"QueryPerson\".QueryPerson.age = \"QueryRelation\".QueryRelation.someVal");
+ "on \"QueryPerson\".QueryPerson.age = \"QueryRelation\".QueryRelation.someVal "
+ "where (\"QueryPerson\".QueryPerson._key < 3000) and "
+ "(\"QueryPerson\".QueryPerson._key >= 2000)");
QueryFieldsCursor cursor = cache1.Query(qry);
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index b025e2c..3e6467c 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -65,6 +65,7 @@ ignite_odbc_tests_SOURCES = \
src/meta_queries_test.cpp \
src/utility_test.cpp \
src/queries_test.cpp \
+ src/queries_ssl_test.cpp \
src/test_utils.cpp \
src/sql_test_suite_fixture.cpp \
src/sql_string_functions_test.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-default.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-default.xml b/modules/platforms/cpp/odbc-test/config/queries-default.xml
index 56040f1..dbe3a10 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-default.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-default.xml
@@ -26,10 +26,18 @@
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
- <bean abstract="true" id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <bean abstract="true" id="queries.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="localHost" value="127.0.0.1"/>
<property name="connectorConfiguration"><null/></property>
+ <property name="clientConnectorConfiguration">
+ <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
+ <property name="host" value="127.0.0.1"/>
+ <property name="port" value="11110"/>
+ <property name="portRange" value="10"/>
+ </bean>
+ </property>
+
<property name="cacheConfiguration">
<list>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-ssl-32.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-ssl-32.xml b/modules/platforms/cpp/odbc-test/config/queries-ssl-32.xml
new file mode 100644
index 0000000..3fa2659
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-ssl-32.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <import resource="queries-default.xml"/>
+
+ <!--
+ Initialize property configurer so we can reference environment variables.
+ -->
+ <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
+ <property name="searchSystemEnvironment" value="true"/>
+ </bean>
+
+ <bean parent="queries.cfg">
+ <property name="clientConnectorConfiguration">
+ <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
+ <property name="host" value="127.0.0.1"/>
+ <property name="port" value="11110"/>
+ <property name="portRange" value="10"/>
+ <property name="sslEnabled" value="true"/>
+ <property name="useIgniteSslContextFactory" value="false"/>
+ <property name="sslClientAuth" value="true"/>
+
+ <!-- Provide Ssl context. -->
+ <property name="sslContextFactory">
+ <bean class="org.apache.ignite.ssl.SslContextFactory">
+ <property name="keyStoreFilePath" value="${IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH}/ssl/server.jks"/>
+ <property name="keyStorePassword" value="123456"/>
+ <property name="trustStoreFilePath" value="${IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH}/ssl/trust.jks"/>
+ <property name="trustStorePassword" value="123456"/>
+ </bean>
+ </property>
+ </bean>
+ </property>
+
+ <property name="memoryConfiguration">
+ <bean class="org.apache.ignite.configuration.MemoryConfiguration">
+ <property name="systemCacheInitialSize" value="#{40 * 1024 * 1024}"/>
+ <property name="systemCacheMaxSize" value="#{40 * 1024 * 1024}"/>
+ <property name="defaultMemoryPolicyName" value="dfltPlc"/>
+
+ <property name="memoryPolicies">
+ <list>
+ <bean class="org.apache.ignite.configuration.MemoryPolicyConfiguration">
+ <property name="name" value="dfltPlc"/>
+ <property name="maxSize" value="#{100 * 1024 * 1024}"/>
+ <property name="initialSize" value="#{100 * 1024 * 1024}"/>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-ssl.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-ssl.xml b/modules/platforms/cpp/odbc-test/config/queries-ssl.xml
new file mode 100644
index 0000000..8e25b4c
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-ssl.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <import resource="queries-default.xml"/>
+
+ <!--
+ Initialize property configurer so we can reference environment variables.
+ -->
+ <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
+ <property name="searchSystemEnvironment" value="true"/>
+ </bean>
+
+ <bean parent="queries.cfg">
+ <property name="clientConnectorConfiguration">
+ <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
+ <property name="host" value="127.0.0.1"/>
+ <property name="port" value="11110"/>
+ <property name="portRange" value="10"/>
+ <property name="sslEnabled" value="true"/>
+ <property name="useIgniteSslContextFactory" value="false"/>
+ <property name="sslClientAuth" value="true"/>
+
+ <!-- Provide Ssl context. -->
+ <property name="sslContextFactory">
+ <bean class="org.apache.ignite.ssl.SslContextFactory">
+ <property name="keyStoreFilePath" value="${IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH}/ssl/server.jks"/>
+ <property name="keyStorePassword" value="123456"/>
+ <property name="trustStoreFilePath" value="${IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH}/ssl/trust.jks"/>
+ <property name="trustStorePassword" value="123456"/>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-test-32.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-32.xml b/modules/platforms/cpp/odbc-test/config/queries-test-32.xml
index f7d9ff4..a2bac82 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test-32.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test-32.xml
@@ -24,8 +24,7 @@
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-- Imports no-ODBC Ignite configuration -->
- <import resource="queries-test-default.xml"/>
+ <import resource="queries-default.xml"/>
<bean parent="queries.cfg">
<property name="memoryConfiguration">
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-test-default.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-default.xml b/modules/platforms/cpp/odbc-test/config/queries-test-default.xml
deleted file mode 100644
index 22524d2..0000000
--- a/modules/platforms/cpp/odbc-test/config/queries-test-default.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- 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.
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <!-- Imports no-ODBC Ignite configuration -->
- <import resource="queries-default.xml"/>
-
- <bean abstract="true" id="queries.cfg" parent="ignite.cfg">
- <property name="clientConnectorConfiguration">
- <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
- <property name="host" value="127.0.0.1"/>
- <property name="port" value="11110"/>
- <property name="portRange" value="0"/>
- </bean>
- </property>
- </bean>
-</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-test-noodbc-32.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc-32.xml b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc-32.xml
deleted file mode 100644
index b98d668..0000000
--- a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc-32.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- 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.
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <!-- Imports no-ODBC Ignite configuration -->
- <import resource="queries-default.xml"/>
-
- <bean parent="ignite.cfg">
- <property name="clientConnectorConfiguration">
- <null/>
- </property>
-
- <property name="memoryConfiguration">
- <bean class="org.apache.ignite.configuration.MemoryConfiguration">
- <property name="systemCacheInitialSize" value="#{40 * 1024 * 1024}"/>
- <property name="systemCacheMaxSize" value="#{40 * 1024 * 1024}"/>
- <property name="defaultMemoryPolicyName" value="dfltPlc"/>
-
- <property name="memoryPolicies">
- <list>
- <bean class="org.apache.ignite.configuration.MemoryPolicyConfiguration">
- <property name="name" value="dfltPlc"/>
- <property name="maxSize" value="#{100 * 1024 * 1024}"/>
- <property name="initialSize" value="#{100 * 1024 * 1024}"/>
- </bean>
- </list>
- </property>
- </bean>
- </property>
- </bean>
-</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
deleted file mode 100644
index 29fee23..0000000
--- a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- 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.
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:util="http://www.springframework.org/schema/util"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
- <!-- Imports no-ODBC Ignite configuration -->
- <import resource="queries-default.xml"/>
-
- <bean parent="ignite.cfg">
- <property name="clientConnectorConfiguration">
- <null/>
- </property>
- </bean>
-</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/queries-test.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test.xml b/modules/platforms/cpp/odbc-test/config/queries-test.xml
index 882eb1e..46e89aa 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test.xml
@@ -24,8 +24,7 @@
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-- Imports no-ODBC Ignite configuration -->
- <import resource="queries-test-default.xml"/>
+ <import resource="queries-default.xml"/>
<bean parent="queries.cfg"/>
</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/ssl/ca.pem
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/ssl/ca.pem b/modules/platforms/cpp/odbc-test/config/ssl/ca.pem
new file mode 100644
index 0000000..10bf7af
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/ssl/ca.pem
@@ -0,0 +1,24 @@
+-----BEGIN TRUSTED CERTIFICATE-----
+MIID8DCCAtgCCQCo436SJYMUcjANBgkqhkiG9w0BAQsFADCBuTELMAkGA1UEBhMC
+UlUxGTAXBgNVBAgMEFNhaW50LVBldGVyc2J1cmcxGTAXBgNVBAcMEFNhaW50LVBl
+dGVyc2J1cmcxIzAhBgNVBAoMGkFwYWNoZSBTcGZ0d2FyZSBGb3VuZGF0aW9uMRYw
+FAYDVQQLDA1BcGFjaGUgSWduaXRlMRQwEgYDVQQDDAtJZ29yIFNhcGVnbzEhMB8G
+CSqGSIb3DQEJARYSaXNhcGVnb0BhcGFjaGUub3JnMB4XDTE3MTEyODE3MzExNloX
+DTI3MTEyNjE3MzExNlowgbkxCzAJBgNVBAYTAlJVMRkwFwYDVQQIDBBTYWludC1Q
+ZXRlcnNidXJnMRkwFwYDVQQHDBBTYWludC1QZXRlcnNidXJnMSMwIQYDVQQKDBpB
+cGFjaGUgU3BmdHdhcmUgRm91bmRhdGlvbjEWMBQGA1UECwwNQXBhY2hlIElnbml0
+ZTEUMBIGA1UEAwwLSWdvciBTYXBlZ28xITAfBgkqhkiG9w0BCQEWEmlzYXBlZ29A
+YXBhY2hlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALMcDfYN
+Ixc0o4bLX/3T5MQE4pk+Bv9Dfr7vBYNPJKSr/GKQJN+5QA/tr1uxTsMSBoE19y5e
+N1vXFtlWMJ2um3ojNbGeqSGuzuDKk0htbgmisyctvEFTqtiYI7D+f7dalEM2KnLj
+f0jIV6NJVilkFKmgsfuZpbZFRkqJDEx74ZqNAYQQ0qJ+zGv7diEak8FwWa4n6xe7
+VHt7VZIbKIkMgTljJLULbExxCRvTHpSeXPP5IMr5x1RGuSavCu4GDl+HmrXac7ot
+L7sqIFHL9JGXTWO16accOQnQIdLQmhj6qh2Em8z41udabzUyIQmOSP6mmwnJEIdz
+jNyWLA8XtYZOgcsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAT6jBgiQjCdQ02cxe
+H9YDFw5+cfb6YQJcjJW94BspySftUGfJ6GQm/Ybcc/ZqW7lhEILKfifdpHPfWby/
+sqhwA0nsLt5hNCjMsDcBq5onggy9ymZYak0VVWT/XkHiK27sQLK6BXo6wqRDwT4h
+F9CgUWNcLGDVAaVpjLaR8itZZgx98q9MAZ680oERUZWTsj17oO0RK/x9TBWUm7OR
+f9g9VNRz3mwT5dTtuqrSq4NlF1nVD7BN3lRddZUW4KnU6et2mXtIKMnUT/+XyIW3
+g+f6LuhR+Q6yhmVdfBVa8opJQIR5trb0eKnQf4pEQcvT/EX+vWkThNJkdZ4qm0mY
+eIl/jQ==
+-----END TRUSTED CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/ssl/client_full.pem
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/ssl/client_full.pem b/modules/platforms/cpp/odbc-test/config/ssl/client_full.pem
new file mode 100644
index 0000000..9a54f43
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/ssl/client_full.pem
@@ -0,0 +1,84 @@
+Bag Attributes
+ friendlyName: client
+ localKeyID: 54 69 6D 65 20 31 35 31 31 39 36 35 31 38 31 32 33 37
+Key Attributes: <No Attributes>
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAmm+QSwc1yvJWjTG8L4rAiHOg38rM1AtOFInzYizT/B6wzsmx
+3Ql4fb+aHm3dPt5kjhQLZToq1QCUsS9B/47ZFd0waDHGgLiSNKn1WdX7Q+4GgplY
+wznc5j+GM65F2aI3tRnn2Jorfss9OElzU5vLh0aD3e5cEpgYSAGEFl1O9t8b6dHq
+YMERtdTCNQVeBUQPiaNNTwOXixtdsPvGKNgMZtVpvV+AMlgVmV+VTYUqQhlX+ro4
+9E4n00+iDIk/REwAiQi/Kb08kovLY9sF2pqC24zU5swyIopEijoa6Z2WYekq1fyL
+P9NknOiMOmWaKqu5ThVbP6c2xGeCdAGbNi+74wIDAQABAoIBAH2oALPLbg1vGNVR
+flkAgJ+F1YPBst9lQ2aayBk9eE5PenUGz12V8x/94hyYL8iTkyW3UX5P0cH18wYn
++X9Cb4fGrThaJ7VceDm5gBRUc1lWNp3Uv9A5KG9/iGZMijEGOGV2appm9rT4ERvX
+R6rjvLqYuXq+EtReRINyGFNKIJHkuwM7Ycy9Rk7O6SrcjjUEj1Z5gEUP0B7Z0jVI
+bsOGqghRflRVqnFT61+koFWBn8taemWmXNa835beN2lRIWezNqfd+9kL72UUt6sl
+VmkqBydDQ+IXCOgLZDYUu3N0bfrKuYmilsRg9XuKTUv+jvwtfGUWTO1+6eSrFD+B
+3j0YeKECgYEA0XrsUOGVl2O4JWBOa36TRHMz0tRBrZUJMK7apEEiGx7jc7q22PI+
+RyPrf9TR7JOLN1AdXoHrJsKCadnTr6g/CAOZSV1V+lUeQkcDmG4OkY814fESxlBA
+jHg7FnJdjzs6VfA1Cv0eT2KxU0ld461AN77WBgG21E2Gw3AGSddbflcCgYEAvLtV
+fhy3+WOUutFsLv1uTz/y+Emih6pmgwsuRG7WgQD9s2KZS+ejh5TQAq4sD+9MSkKk
+XnvdbwGQkHppdtVP5wMeSfY6tG/9YmY7X5rTG9PTsrzAzNJwrnE9hFv7Xnj3SMnC
+0D9eBnA8XWq49vsair7gxBWwhGYR/5WDicGn31UCgYEAgJb6lbPEhkgadCcoPGhY
+sn4dY+AT6SBBofbUFFw/OXK+oP4O3CHoBPeRysizjIwNu4icXrVVyldAgwXKIlwf
+RSYgZJ689oxlpL2/AUUeAFBu/SFlKwN8fD4Z12+g6xmqd7KafQJgJs8olz3EOszR
+TOcCrnFC8BQfE72ivpVKfsUCgYBBZw3maR9cHiUxZFeAJTTv47JYVnQrXWKu8NX0
+wxA0nlpMqtOC2V/zIR/Afgko8H1YkqWRVI1U5Y7qcnFPy/YnkQ4TBXAsjU6apeDX
+bbjQwORw4TZTBG4mFXoC/zkp8POI1tpa/kqgIo7YtJ4qgLQe9qy/ZuDH0PNVxcNS
+nriFDQKBgF70vrmuYEobLpBD/whcOqMDjn3Zj+xx3TSRmjmjc4w5eRR4+9iquKs5
+lhY1NsAcq3SYA8P5rNDV39FpiPErFqDTjsf0AaOXbpaqo2jOANmvyT15CKW8325R
+yEcxaA8sSbBaz8QRkydzpoKT+4WFJnYzCZtG+kUU+Pgu6uahAs4N
+-----END RSA PRIVATE KEY-----
+Bag Attributes
+ friendlyName: client
+ localKeyID: 54 69 6D 65 20 31 35 31 31 39 36 35 31 38 31 32 33 37
+subject=/CN=ODBC
+issuer=/C=RU/ST=Saint-Petersburg/L=Saint-Petersburg/O=Apache Spftware Foundation/OU=Apache Ignite/CN=Igor Sapego/emailAddress=isapego@apache.org
+-----BEGIN CERTIFICATE-----
+MIIDPTCCAiUCAQIwDQYJKoZIhvcNAQEFBQAwgbkxCzAJBgNVBAYTAlJVMRkwFwYD
+VQQIDBBTYWludC1QZXRlcnNidXJnMRkwFwYDVQQHDBBTYWludC1QZXRlcnNidXJn
+MSMwIQYDVQQKDBpBcGFjaGUgU3BmdHdhcmUgRm91bmRhdGlvbjEWMBQGA1UECwwN
+QXBhY2hlIElnbml0ZTEUMBIGA1UEAwwLSWdvciBTYXBlZ28xITAfBgkqhkiG9w0B
+CQEWEmlzYXBlZ29AYXBhY2hlLm9yZzAeFw0xNzExMjkxNDAwNDhaFw0yNzExMjcx
+NDAwNDhaMA8xDTALBgNVBAMTBE9EQkMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCab5BLBzXK8laNMbwvisCIc6DfyszUC04UifNiLNP8HrDOybHdCXh9
+v5oebd0+3mSOFAtlOirVAJSxL0H/jtkV3TBoMcaAuJI0qfVZ1ftD7gaCmVjDOdzm
+P4YzrkXZoje1GefYmit+yz04SXNTm8uHRoPd7lwSmBhIAYQWXU723xvp0epgwRG1
+1MI1BV4FRA+Jo01PA5eLG12w+8Yo2Axm1Wm9X4AyWBWZX5VNhSpCGVf6ujj0TifT
+T6IMiT9ETACJCL8pvTySi8tj2wXamoLbjNTmzDIiikSKOhrpnZZh6SrV/Is/02Sc
+6Iw6ZZoqq7lOFVs/pzbEZ4J0AZs2L7vjAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB
+AH8heMPYkC/abqg9xtC5WFgYxnXWA6jwjKVuCSnrEhZGQem9HFvFXmZckJr25RXc
+9i8WIehN5oeJgmPioK6j8ylwCJxo9lRii4NFBVpS6IjmqMdYHa+4K1R9Y7XdDEBL
+nVzlL8Hjlv4ESjg+1LW4nSt8f4oBdAvfds4uNTtAwABqmfqXWaOKYdh9OJs84QJa
+pA4PQvxqUz6c4tyPi/VucVAV8uKxR7P+uoy6qKKZK6NkY3RuXwHXxJ5lDr6ET1mb
+St0BbAt4KSktPonCu0qoHWqcynw79KcoPhmQWpzbijVs+y/SlHmZje+H4R7j7xt7
+aw7dWxUa096x4vsi1WvlMOY=
+-----END CERTIFICATE-----
+Bag Attributes
+ friendlyName: 1.2.840.113549.1.9.1=#16126973617065676f406170616368652e6f7267,CN=Igor Sapego,OU=Apache Ignite,O=Apache Spftware Foundation,L=Saint-Petersburg,ST=Saint-Petersburg,C=RU
+subject=/C=RU/ST=Saint-Petersburg/L=Saint-Petersburg/O=Apache Spftware Foundation/OU=Apache Ignite/CN=Igor Sapego/emailAddress=isapego@apache.org
+issuer=/C=RU/ST=Saint-Petersburg/L=Saint-Petersburg/O=Apache Spftware Foundation/OU=Apache Ignite/CN=Igor Sapego/emailAddress=isapego@apache.org
+-----BEGIN CERTIFICATE-----
+MIID8DCCAtgCCQCo436SJYMUcjANBgkqhkiG9w0BAQsFADCBuTELMAkGA1UEBhMC
+UlUxGTAXBgNVBAgMEFNhaW50LVBldGVyc2J1cmcxGTAXBgNVBAcMEFNhaW50LVBl
+dGVyc2J1cmcxIzAhBgNVBAoMGkFwYWNoZSBTcGZ0d2FyZSBGb3VuZGF0aW9uMRYw
+FAYDVQQLDA1BcGFjaGUgSWduaXRlMRQwEgYDVQQDDAtJZ29yIFNhcGVnbzEhMB8G
+CSqGSIb3DQEJARYSaXNhcGVnb0BhcGFjaGUub3JnMB4XDTE3MTEyODE3MzExNloX
+DTI3MTEyNjE3MzExNlowgbkxCzAJBgNVBAYTAlJVMRkwFwYDVQQIDBBTYWludC1Q
+ZXRlcnNidXJnMRkwFwYDVQQHDBBTYWludC1QZXRlcnNidXJnMSMwIQYDVQQKDBpB
+cGFjaGUgU3BmdHdhcmUgRm91bmRhdGlvbjEWMBQGA1UECwwNQXBhY2hlIElnbml0
+ZTEUMBIGA1UEAwwLSWdvciBTYXBlZ28xITAfBgkqhkiG9w0BCQEWEmlzYXBlZ29A
+YXBhY2hlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALMcDfYN
+Ixc0o4bLX/3T5MQE4pk+Bv9Dfr7vBYNPJKSr/GKQJN+5QA/tr1uxTsMSBoE19y5e
+N1vXFtlWMJ2um3ojNbGeqSGuzuDKk0htbgmisyctvEFTqtiYI7D+f7dalEM2KnLj
+f0jIV6NJVilkFKmgsfuZpbZFRkqJDEx74ZqNAYQQ0qJ+zGv7diEak8FwWa4n6xe7
+VHt7VZIbKIkMgTljJLULbExxCRvTHpSeXPP5IMr5x1RGuSavCu4GDl+HmrXac7ot
+L7sqIFHL9JGXTWO16accOQnQIdLQmhj6qh2Em8z41udabzUyIQmOSP6mmwnJEIdz
+jNyWLA8XtYZOgcsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAT6jBgiQjCdQ02cxe
+H9YDFw5+cfb6YQJcjJW94BspySftUGfJ6GQm/Ybcc/ZqW7lhEILKfifdpHPfWby/
+sqhwA0nsLt5hNCjMsDcBq5onggy9ymZYak0VVWT/XkHiK27sQLK6BXo6wqRDwT4h
+F9CgUWNcLGDVAaVpjLaR8itZZgx98q9MAZ680oERUZWTsj17oO0RK/x9TBWUm7OR
+f9g9VNRz3mwT5dTtuqrSq4NlF1nVD7BN3lRddZUW4KnU6et2mXtIKMnUT/+XyIW3
+g+f6LuhR+Q6yhmVdfBVa8opJQIR5trb0eKnQf4pEQcvT/EX+vWkThNJkdZ4qm0mY
+eIl/jQ==
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/ssl/client_unknown.pem
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/ssl/client_unknown.pem b/modules/platforms/cpp/odbc-test/config/ssl/client_unknown.pem
new file mode 100644
index 0000000..b9a8e43
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/ssl/client_unknown.pem
@@ -0,0 +1,50 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC0HaDP3KkkgcT7
+3FWWxXEgiT5vAsW+ZByiWg5Yh5XtU7rAjiXT9VmOm1h/5GNdngF7ofhT+qal1k8W
+yiLsbqWL6qYXkc0e8aKw9ciBaWDWDkgXNnV03butu70hNvm/fzYp/6/WQ5SXUJdm
+mJZyeVjgU4NXnOe0lv2PlzUr5q1yjJCSnTbsHBvs0qfoy7DYqPQFbrwiuIOeYtVg
+mjjL/y6SUCY/uNY8McLG0YFubNsnOCEIyZOgAM1RdmARt+iYZuLVZkicgkaxYtLB
+pbUB8K2Y/A+0WjL7JceZVWbUaQKkDncegccMmHzEOBsJyLRWu+/5ztan7xh+jIGd
+vtlgoz8/AgMBAAECggEBAKx4TnucHW7ywFA3/NEBwUDZiqo8KmQUcwLXXzNQqbT2
+3zXxJ7HeF2KhyE22wZtsaJkdULABrL/SBiuZZXWmwejHyUF6gMMnuJTg1Z1t7acr
+R8bKhBBjHorO4dzDSsUfKBtxVcvDLK70IfXBGRcGsZ8k+PjVK15W0vhDX0vpeJ7c
+9E6FS+Kfz31d8/xLETF3QdevfPTTMliakL0Tr37NKefdGXU8O07tvL/Chq40VWzl
+KqdU0ti+mI18fNsTgpe16JLvEpQBQ1ZRm/ip5ZJPkPloZn7sP7KIpmZOuMplbYlJ
+ZyINe+OKOLB8/65XK8eqwgEyQQi9Iq7/2bWgMbZKP8ECgYEA54ysuNUEVtwhmcXK
+CGiTfuCqguvKmaFraenoCxvf+aY3TU7dguA8soI+yQraqt9nW1fqrMEOnzr/mEFI
+3NE81k3uWLPdcbk/sPKKI2iQqkmlCR7XQYch0Kq2KZ3A4kXvT0M6njBb/8UFtSai
+dWiit9/9c40PGUA28+dYCSnnn2ECgYEAxyKT/+hrCHauj7Enz2jqIBsIJGRq6bc0
+rZZf4yoQO4wJTs7zTUa3REYHQOGYM/zb6BkmO5SaHiUxwrAvWi+3UvSwzSC7SZEw
+2Ym8FRFZLcjG2n9CeHK4jcp8kXnoeoKnD9K9ztQszmjl+YJ5LLAXEQuXlwG0ZSld
+Nz2OHuHYgp8CgYEAnrJequtsZu/Go7LYzjyGYp4unz5mBDeK+/NRk1OOhXczTevw
+i8OONjZoO7gRuK0XFJbEA5TppZ51EXAlNRq/HI4a/naAHnJ9wZPps2z2QY/p6b9W
+ftXUCkUGRq2VRj/yTZvhMAwq8biiOc7554hIhceh2TFjmMXXJAF56AXtduECgYA6
+Y1kh3/QCN0pXt4oEtq5vW323rfnrLVy0yTK0WNEJpLXV9bhBIEr8KcxWqc8G701L
+cJRVQ+0siZtdimtX9kW6fSSaAM7pczjvkAMl6kBLvGMSDd5fksOqT4TW4vfXdBen
+/BLLYksA+qDz193PzJH23X9FN6q9PrOmTtYtF+tz4QKBgQDeUhgpylS0sjTzS36b
+8V86DJ4mj22B7H6jp826Y696V79a2/jSacs1KKExOYXeJBUdhDoutVS0PiT10br9
+lSIKiExbrddmBUd5OEtZKz1bXqRoMZlAvjuOhqadU0DciSQjiZ8CSmSzCX31++7G
+velIMG6xcMV3LKtY4dr7B6KuiA==
+-----END PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgIJAJy64S/DycmkMA0GCSqGSIb3DQEBCwUAMGcxCzAJBgNV
+BAYTAlJVMRkwFwYDVQQIDBBTYWludCBQZXRlcnNidXJnMRkwFwYDVQQHDBBTYWlu
+dCBQZXRlcnNidXJnMRAwDgYDVQQKDAdVbmtub3duMRAwDgYDVQQDDAdVbmtub3du
+MB4XDTE4MDEyNDEwMTUwNFoXDTE5MDEyNDEwMTUwNFowZzELMAkGA1UEBhMCUlUx
+GTAXBgNVBAgMEFNhaW50IFBldGVyc2J1cmcxGTAXBgNVBAcMEFNhaW50IFBldGVy
+c2J1cmcxEDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAMMB1Vua25vd24wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0HaDP3KkkgcT73FWWxXEgiT5vAsW+
+ZByiWg5Yh5XtU7rAjiXT9VmOm1h/5GNdngF7ofhT+qal1k8WyiLsbqWL6qYXkc0e
+8aKw9ciBaWDWDkgXNnV03butu70hNvm/fzYp/6/WQ5SXUJdmmJZyeVjgU4NXnOe0
+lv2PlzUr5q1yjJCSnTbsHBvs0qfoy7DYqPQFbrwiuIOeYtVgmjjL/y6SUCY/uNY8
+McLG0YFubNsnOCEIyZOgAM1RdmARt+iYZuLVZkicgkaxYtLBpbUB8K2Y/A+0WjL7
+JceZVWbUaQKkDncegccMmHzEOBsJyLRWu+/5ztan7xh+jIGdvtlgoz8/AgMBAAGj
+UDBOMB0GA1UdDgQWBBSmehz8ReTNQ6IQmMBXhns97I3U6jAfBgNVHSMEGDAWgBSm
+ehz8ReTNQ6IQmMBXhns97I3U6jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA
+A4IBAQAjtzZtXSqIrWJfCJCp0Kal/swR9EDIhvdZNpH3VJMUKENRPKZF2AdlGLwx
+sSAL6oUkCjew3NC4UM7CH1LZR+RZOQXhLxh+xmlIUDJukjftPcEAXAymCJyEShjD
+qr/YH3SrrVfzf/ViZOa3YrlWXuP9WqEYYAMJcNmgl2A1vhpIwrF0+GLrvnUV2E6a
+qHqBmA8GforiiOye+TQKNuFCgd+m8nr3AUCBaY2aVgFBg5Z2uumMzx5qmejQIdDr
+tiKsr7+QiaY97lXIThMCDxPt63Jk2uO9yUJZSzDJlY2JHuRnMmyO+TnVrUAyCr60
+dBkPpbvH/kMPPFkOhDk6e40YvqWY
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/ssl/server.jks
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/ssl/server.jks b/modules/platforms/cpp/odbc-test/config/ssl/server.jks
new file mode 100644
index 0000000..2632662
Binary files /dev/null and b/modules/platforms/cpp/odbc-test/config/ssl/server.jks differ
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/config/ssl/trust.jks
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/ssl/trust.jks b/modules/platforms/cpp/odbc-test/config/ssl/trust.jks
new file mode 100644
index 0000000..a0f3bcf
Binary files /dev/null and b/modules/platforms/cpp/odbc-test/config/ssl/trust.jks differ
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h b/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h
index f79d65f..c535679 100644
--- a/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h
+++ b/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h
@@ -29,9 +29,6 @@
#include "ignite/ignite.h"
-#include "test_type.h"
-#include "complex_type.h"
-
namespace ignite
{
namespace odbc
@@ -42,6 +39,11 @@ namespace ignite
struct OdbcTestSuite
{
/**
+ * Prepare environment.
+ */
+ void Prepare();
+
+ /**
* Establish connection to node.
*
* @param connectStr Connection string.
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/include/test_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_utils.h b/modules/platforms/cpp/odbc-test/include/test_utils.h
index e65e187..786c2be 100644
--- a/modules/platforms/cpp/odbc-test/include/test_utils.h
+++ b/modules/platforms/cpp/odbc-test/include/test_utils.h
@@ -68,6 +68,11 @@ namespace ignite_test
std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle);
/**
+ * @return Test config directory path.
+ */
+ std::string GetTestConfigDir();
+
+ /**
* Initialize configuration for a node.
*
* Inits Ignite node configuration from specified config file.
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index d565306..b1074b2 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -91,9 +91,10 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME);$(OPENSSL_HOME)\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;IGNITE_IMPL;IGNITE_FRIEND;IGNITE_TESTS_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -105,7 +106,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME);$(OPENSSL_HOME)\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;IGNITE_IMPL;IGNITE_FRIEND;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
@@ -122,7 +123,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME);$(OPENSSL_HOME)\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;IGNITE_IMPL;IGNITE_FRIEND;IGNITE_TESTS_32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
@@ -140,7 +141,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
- <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\..\jni\include;$(ProjectDir)\..\..\..\jni\os\win\include;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\..\core\include;$(ProjectDir)\..\..\..\odbc\include;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\src;$(BOOST_HOME);$(OPENSSL_HOME)\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;BOOST_DATE_TIME_NO_LIB;BOOST_REGEX_NO_LIB;IGNITE_IMPL;IGNITE_FRIEND;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile>
@@ -172,6 +173,7 @@
<ClCompile Include="..\..\src\errors_test.cpp" />
<ClCompile Include="..\..\src\meta_queries_test.cpp" />
<ClCompile Include="..\..\src\odbc_test_suite.cpp" />
+ <ClCompile Include="..\..\src\queries_ssl_test.cpp" />
<ClCompile Include="..\..\src\queries_test.cpp" />
<ClCompile Include="..\..\src\parser_test.cpp" />
<ClCompile Include="..\..\src\row_test.cpp" />
@@ -217,9 +219,8 @@
</ItemGroup>
<ItemGroup>
<None Include="..\..\config\queries-default.xml" />
- <None Include="..\..\config\queries-test-noodbc-32.xml" />
- <None Include="..\..\config\queries-test-noodbc.xml" />
- <None Include="..\..\config\queries-test-default.xml" />
+ <None Include="..\..\config\queries-ssl-32.xml" />
+ <None Include="..\..\config\queries-ssl.xml" />
<None Include="..\..\config\queries-test-32.xml" />
<None Include="..\..\config\queries-test.xml" />
</ItemGroup>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 58cf045..417fac9 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -139,6 +139,9 @@
<ClCompile Include="..\..\src\odbc_test_suite.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\queries_ssl_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\test_type.h">
@@ -167,17 +170,14 @@
<None Include="..\..\config\queries-test.xml">
<Filter>Configs</Filter>
</None>
- <None Include="..\..\config\queries-test-noodbc-32.xml">
- <Filter>Configs</Filter>
- </None>
- <None Include="..\..\config\queries-test-noodbc.xml">
+ <None Include="..\..\config\queries-default.xml">
<Filter>Configs</Filter>
</None>
- <None Include="..\..\config\queries-default.xml">
+ <None Include="..\..\config\queries-ssl.xml">
<Filter>Configs</Filter>
</None>
- <None Include="..\..\config\queries-test-default.xml">
+ <None Include="..\..\config\queries-ssl-32.xml">
<Filter>Configs</Filter>
</None>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
index c17e079..293d8bc 100644
--- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
@@ -37,6 +37,7 @@
#include "test_type.h"
#include "test_utils.h"
+#include "odbc_test_suite.h"
using namespace ignite;
using namespace ignite::cache;
@@ -51,98 +52,21 @@ using ignite::impl::binary::BinaryUtils;
/**
* Test setup fixture.
*/
-struct ApiRobustnessTestSuiteFixture
+struct ApiRobustnessTestSuiteFixture : public odbc::OdbcTestSuite
{
- void Prepare()
- {
- // Allocate an environment handle
- SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
-
- BOOST_REQUIRE(env != NULL);
-
- // We want ODBC 3 support
- SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
-
- // Allocate a connection handle
- SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
-
- BOOST_REQUIRE(dbc != NULL);
- }
-
- /**
- * Establish connection to node.
- *
- * @param connectStr Connection string.
- */
- void Connect(const std::string& connectStr)
- {
- Prepare();
-
- // Connect string
- std::vector<SQLCHAR> connectStr0;
-
- connectStr0.reserve(connectStr.size() + 1);
- std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
-
- SQLCHAR outstr[ODBC_BUFFER_SIZE];
- SQLSMALLINT outstrlen;
-
- // Connecting to ODBC server.
- SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
- outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
-
- ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
-
- // Allocate a statement handle
- SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
-
- BOOST_REQUIRE(stmt != NULL);
- }
-
- void Disconnect()
- {
- // Releasing statement handle.
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-
- // Disconneting from the server.
- SQLDisconnect(dbc);
-
- // Releasing allocated handles.
- SQLFreeHandle(SQL_HANDLE_DBC, dbc);
- SQLFreeHandle(SQL_HANDLE_ENV, env);
- }
-
static Ignite StartAdditionalNode(const char* name)
{
- const char* config = NULL;
-
-#ifdef IGNITE_TESTS_32
- config = "queries-test-noodbc-32.xml";
-#else
- config = "queries-test-noodbc.xml";
-#endif
-
- return StartNode(config, name);
+ return StartTestNode("queries-test.xml", name);
}
/**
* Constructor.
*/
ApiRobustnessTestSuiteFixture() :
- testCache(0),
- env(NULL),
- dbc(NULL),
- stmt(NULL)
+ grid(),
+ testCache(0)
{
- const char* config = NULL;
-
-#ifdef IGNITE_TESTS_32
- config = "queries-test-32.xml";
-#else
- config = "queries-test.xml";
-#endif
-
- grid = StartNode(config, "NodeMain");
+ grid = StartAdditionalNode("NodeMain");
testCache = grid.GetCache<int64_t, TestType>("cache");
}
@@ -227,9 +151,7 @@ struct ApiRobustnessTestSuiteFixture
*/
~ApiRobustnessTestSuiteFixture()
{
- Disconnect();
-
- Ignition::StopAll(true);
+ // No-op.
}
/** Node started during the test. */
@@ -237,15 +159,6 @@ struct ApiRobustnessTestSuiteFixture
/** Test cache instance. */
Cache<int64_t, TestType> testCache;
-
- /** ODBC Environment. */
- SQLHENV env;
-
- /** ODBC Connect. */
- SQLHDBC dbc;
-
- /** ODBC Statement. */
- SQLHSTMT stmt;
};
SQLSMALLINT unsupportedC[] = {
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/errors_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/errors_test.cpp b/modules/platforms/cpp/odbc-test/src/errors_test.cpp
index bac9fd4..9c640ba 100644
--- a/modules/platforms/cpp/odbc-test/src/errors_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/errors_test.cpp
@@ -42,6 +42,7 @@
#include "test_type.h"
#include "complex_type.h"
#include "test_utils.h"
+#include "odbc_test_suite.h"
using namespace ignite;
using namespace ignite::cache;
@@ -59,83 +60,18 @@ using ignite::impl::binary::BinaryUtils;
/**
* Test setup fixture.
*/
-struct ErrorTestSuiteFixture
+struct ErrorTestSuiteFixture : odbc::OdbcTestSuite
{
- /**
- * Establish connection to node.
- *
- * @param connectStr Connection string.
- */
- void Connect(const std::string& connectStr)
- {
- // Allocate an environment handle
- SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
-
- BOOST_REQUIRE(env != NULL);
-
- // We want ODBC 3 support
- SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
-
- // Allocate a connection handle
- SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
-
- BOOST_REQUIRE(dbc != NULL);
-
- // Connect string
- std::vector<SQLCHAR> connectStr0;
-
- connectStr0.reserve(connectStr.size() + 1);
- std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
-
- SQLCHAR outstr[ODBC_BUFFER_SIZE];
- SQLSMALLINT outstrlen;
-
- // Connecting to ODBC server.
- SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
- outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
-
- if (!SQL_SUCCEEDED(ret))
- {
- Ignition::StopAll(true);
-
- BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
- }
-
- // Allocate a statement handle
- SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
-
- BOOST_REQUIRE(stmt != NULL);
- }
-
- void Disconnect()
- {
- // Releasing statement handle.
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-
- // Disconneting from the server.
- SQLDisconnect(dbc);
-
- // Releasing allocated handles.
- SQLFreeHandle(SQL_HANDLE_DBC, dbc);
- SQLFreeHandle(SQL_HANDLE_ENV, env);
- }
-
static Ignite StartAdditionalNode(const char* name)
{
-#ifdef IGNITE_TESTS_32
- return StartNode("queries-test-32.xml", name);
-#else
- return StartNode("queries-test.xml", name);
-#endif
+ return StartTestNode("queries-test.xml", name);
}
/**
* Constructor.
*/
ErrorTestSuiteFixture() :
- env(NULL),
- dbc(NULL),
- stmt(NULL)
+ OdbcTestSuite()
{
// No-op.
}
@@ -145,22 +81,8 @@ struct ErrorTestSuiteFixture
*/
~ErrorTestSuiteFixture()
{
- Disconnect();
-
- Ignition::StopAll(true);
+ // No-op.
}
-
- /** Frist cache instance. */
- //Cache<int64_t, TestType> cache;
-
- /** ODBC Environment. */
- SQLHENV env;
-
- /** ODBC Connect. */
- SQLHDBC dbc;
-
- /** ODBC Statement. */
- SQLHSTMT stmt;
};
BOOST_FIXTURE_TEST_SUITE(ErrorTestSuite, ErrorTestSuiteFixture)
@@ -181,7 +103,7 @@ BOOST_AUTO_TEST_CASE(TestConnectFail)
BOOST_REQUIRE(dbc != NULL);
// Connect string
- SQLCHAR connectStr[] = "DRIVER={Apache Ignite};ADDRESS=127.0.0.1:9999;SCHEMA=cache";
+ SQLCHAR connectStr[] = "DRIVER={Apache Ignite};ADDRESS=127.0.0.1:1111;SCHEMA=cache";
SQLCHAR outstr[ODBC_BUFFER_SIZE];
SQLSMALLINT outstrlen;
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index ba9fd04..8e22e3d 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -40,6 +40,7 @@
#include "test_type.h"
#include "complex_type.h"
#include "test_utils.h"
+#include "odbc_test_suite.h"
using namespace ignite;
using namespace ignite::cache;
@@ -55,82 +56,16 @@ using namespace boost::unit_test;
/**
* Test setup fixture.
*/
-struct MetaQueriesTestSuiteFixture
+struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
{
/**
- * Establish connection to node.
- *
- * @param connectStr Connection string.
- */
- void Connect(const std::string& connectStr)
- {
- // Allocate an environment handle
- SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
-
- BOOST_REQUIRE(env != NULL);
-
- // We want ODBC 3 support
- SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
-
- // Allocate a connection handle
- SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
-
- BOOST_REQUIRE(dbc != NULL);
-
- // Connect string
- std::vector<SQLCHAR> connectStr0;
-
- connectStr0.reserve(connectStr.size() + 1);
- std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
-
- SQLCHAR outstr[ODBC_BUFFER_SIZE];
- SQLSMALLINT outstrlen;
-
- // Connecting to ODBC server.
- SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
- outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
-
- if (!SQL_SUCCEEDED(ret))
- {
- Ignition::Stop(grid.GetName(), true);
-
- BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
- }
-
- // Allocate a statement handle
- SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
-
- BOOST_REQUIRE(stmt != NULL);
- }
-
- /**
- * Disconnect.
- */
- void Disconnect()
- {
- // Releasing statement handle.
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-
- // Disconneting from the server.
- SQLDisconnect(dbc);
-
- // Releasing allocated handles.
- SQLFreeHandle(SQL_HANDLE_DBC, dbc);
- SQLFreeHandle(SQL_HANDLE_ENV, env);
- }
-
- /**
* Start additional node with the specified name.
*
* @param name Node name.
*/
static Ignite StartAdditionalNode(const char* name)
{
-#ifdef IGNITE_TESTS_32
- return StartNode("queries-test-noodbc-32.xml", name);
-#else
- return StartNode("queries-test-noodbc.xml", name);
-#endif
+ return StartTestNode("queries-test.xml", name);
}
/**
@@ -190,17 +125,11 @@ struct MetaQueriesTestSuiteFixture
* Constructor.
*/
MetaQueriesTestSuiteFixture() :
+ grid(0),
cache1(0),
- cache2(0),
- env(NULL),
- dbc(NULL),
- stmt(NULL)
+ cache2(0)
{
-#ifdef IGNITE_TESTS_32
- grid = StartNode("queries-test-32.xml", "NodeMain");
-#else
- grid = StartNode("queries-test.xml", "NodeMain");
-#endif
+ grid = StartTestNode("queries-test.xml", "NodeMain");
cache1 = grid.GetCache<int64_t, TestType>("cache");
cache2 = grid.GetCache<int64_t, ComplexType>("cache2");
@@ -211,9 +140,7 @@ struct MetaQueriesTestSuiteFixture
*/
~MetaQueriesTestSuiteFixture()
{
- Disconnect();
-
- Ignition::StopAll(true);
+ // No-op.
}
/** Node started during the test. */
@@ -224,15 +151,6 @@ struct MetaQueriesTestSuiteFixture
/** Second cache instance. */
Cache<int64_t, ComplexType> cache2;
-
- /** ODBC Environment. */
- SQLHENV env;
-
- /** ODBC Connect. */
- SQLHDBC dbc;
-
- /** ODBC Statement. */
- SQLHSTMT stmt;
};
BOOST_FIXTURE_TEST_SUITE(MetaQueriesTestSuite, MetaQueriesTestSuiteFixture)
http://git-wip-us.apache.org/repos/asf/ignite/blob/394019ee/modules/platforms/cpp/odbc-test/src/odbc_test_suite.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/odbc_test_suite.cpp b/modules/platforms/cpp/odbc-test/src/odbc_test_suite.cpp
index 970c77d..fca3604 100644
--- a/modules/platforms/cpp/odbc-test/src/odbc_test_suite.cpp
+++ b/modules/platforms/cpp/odbc-test/src/odbc_test_suite.cpp
@@ -40,7 +40,7 @@ namespace ignite
{
namespace odbc
{
- void OdbcTestSuite::Connect(const std::string& connectStr)
+ void OdbcTestSuite::Prepare()
{
// Allocate an environment handle
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
@@ -54,12 +54,14 @@ namespace ignite
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
BOOST_REQUIRE(dbc != NULL);
+ }
- // Connect string
- std::vector<SQLCHAR> connectStr0;
+ void OdbcTestSuite::Connect(const std::string& connectStr)
+ {
+ Prepare();
- connectStr0.reserve(connectStr.size() + 1);
- std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
+ // Connect string
+ std::vector<SQLCHAR> connectStr0(connectStr.begin(), connectStr.end());
SQLCHAR outstr[ODBC_BUFFER_SIZE];
SQLSMALLINT outstrlen;
@@ -81,15 +83,29 @@ namespace ignite
void OdbcTestSuite::Disconnect()
{
- // Releasing statement handle.
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ if (stmt)
+ {
+ // Releasing statement handle.
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+ stmt = NULL;
+ }
+
+ if (dbc)
+ {
+ // Disconneting from the server.
+ SQLDisconnect(dbc);
- // Disconneting from the server.
- SQLDisconnect(dbc);
+ // Releasing allocated handles.
+ SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+ dbc = NULL;
+ }
- // Releasing allocated handles.
- SQLFreeHandle(SQL_HANDLE_DBC, dbc);
- SQLFreeHandle(SQL_HANDLE_ENV, env);
+ if (env)
+ {
+ // Releasing allocated handles.
+ SQLFreeHandle(SQL_HANDLE_ENV, env);
+ env = NULL;
+ }
}
Ignite OdbcTestSuite::StartTestNode(const char* cfg, const char* name)