Skip to content
Snippets Groups Projects
Verified Commit fdfc5367 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

add configuration manager

parent 59c37487
Branches
Tags
1 merge request!1Minimal c interface
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
set(libcaosdb_SRC set(libcaosdb_SRC
${CMAKE_CURRENT_SOURCE_DIR}/caosdb/authentication.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/authentication.cpp
${CMAKE_CURRENT_SOURCE_DIR}/caosdb/connection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/connection.cpp
${CMAKE_CURRENT_SOURCE_DIR}/caosdb/configuration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/transaction.cpp
) )
......
/*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "caosdb/configuration.h"
#include <cstdlib> // for getenv
#include <cassert> // for assert
#include <string> // for char_traits, string
#include "boost/iterator/iterator_facade.hpp" // for iterator_facade_base
#include "boost/json/impl/object.hpp" // for object::at, object::begin
#include "boost/json/string.hpp" // for string
#include "boost/json/string_view.hpp" // for string_view
#include "caosdb/authentication.h" // for PlainPasswordAuthentic...
#include "caosdb/connection.h" // for TlsConnectionConfig
#include "caosdb/constants.h" // for LIBCAOSDB_CONFIGURATIO...
#include "caosdb/exceptions.h" // for ConfigurationError
namespace caosdb::configuration {
using boost::filesystem::exists;
using boost::filesystem::path;
using boost::json::object;
using boost::json::value;
using caosdb::authentication::Authenticator;
using caosdb::authentication::PlainPasswordAuthenticator;
using caosdb::connection::CertificateProvider;
using caosdb::connection::ConnectionConfig;
using caosdb::connection::InsecureConnectionConfig;
using caosdb::connection::PemFileCertificateProvider;
using caosdb::connection::TlsConnectionConfig;
using caosdb::exceptions::ConfigurationError;
using caosdb::utility::get_home_directory;
using caosdb::utility::load_json_file;
auto ConnectionConfigurationHelper::CreateCertificateProvider(
const object &from) const -> std::unique_ptr<CertificateProvider> {
std::unique_ptr<CertificateProvider> certificate_provider;
if (from.contains("server_certificate_path")) {
const value &path_str = from.at("server_certificate_path");
assert(path_str.is_string() == true);
certificate_provider = std::make_unique<PemFileCertificateProvider>(
std::string(path_str.as_string().c_str()));
}
return certificate_provider;
};
auto ConnectionConfigurationHelper::CreateAuthenticator(
const object &from) const -> std::unique_ptr<Authenticator> {
std::unique_ptr<Authenticator> authenticator;
if (from.contains("authentication")) {
assert(from.at("authentication").is_object());
auto authentication = from.at("authentication").as_object();
auto type = std::string("plain");
if (authentication.contains("type")) {
assert(authentication.at("type").is_string());
type = std::string(authentication.at("type").as_string().c_str());
}
if (type == "plain") {
assert(authentication.contains("username"));
auto username = authentication.at("username");
assert(username.is_string());
assert(authentication.contains("password"));
auto password = authentication.at("password");
assert(password.is_string());
authenticator = std::make_unique<PlainPasswordAuthenticator>(
std::string(username.as_string().c_str()),
std::string(password.as_string().c_str()));
} else {
throw ConfigurationError("Unknow authentication type: '" + type + "'.");
}
}
return authenticator;
};
auto ConnectionConfigurationHelper::CreateConnectionConfiguration(
const bool tls, const std::string &host, const int port,
const CertificateProvider *certificate_provider,
const Authenticator *authenticator) const
-> std::unique_ptr<ConnectionConfig> {
if (tls) {
if (certificate_provider != nullptr && authenticator != nullptr) {
// authenticated and special certificate
return std::make_unique<TlsConnectionConfig>(
host, port, *certificate_provider, *authenticator);
} else if (certificate_provider != nullptr) {
// unauthenticated, special certificate
return std::make_unique<TlsConnectionConfig>(host, port,
*certificate_provider);
} else if (authenticator != nullptr) {
// authenticated, no special certificate
return std::make_unique<TlsConnectionConfig>(host, port, *authenticator);
}
// unauthenticated, no special certificate
return std::make_unique<TlsConnectionConfig>(host, port);
} else {
return std::make_unique<InsecureConnectionConfig>(host, port);
}
};
auto ConnectionConfigurationHelper::IsTls(const object &from) const -> bool {
bool tls = true;
if (from.contains("tls")) {
auto tls_switch = from.at("tls");
assert(tls_switch.is_bool());
tls = tls_switch.as_bool();
}
return tls;
};
auto ConnectionConfigurationHelper::CreateConnectionConfiguration(
const object &from) const -> std::unique_ptr<ConnectionConfig> {
assert(from.contains("host"));
const auto &host = from.at("host");
assert(host.is_string());
assert(from.contains("port"));
const auto &port = from.at("port");
assert(port.is_int64());
auto tls = IsTls(from);
auto certificate_provider = CreateCertificateProvider(from);
auto authenticator = CreateAuthenticator(from);
return CreateConnectionConfiguration(
tls, std::string(host.as_string().c_str()),
static_cast<int>(port.as_int64()), certificate_provider.get(),
authenticator.get());
};
auto ConfigurationManager::mReset() -> void {
mClear();
InitializeDefaults();
};
auto ConfigurationManager::mClear() -> void {
json_configuration = value(nullptr);
ConnectionManager::Reset();
}
auto ConfigurationManager::mLoadSingleJSONConfiguration(const path &json_file)
-> void {
if (!json_configuration.is_null()) {
throw ConfigurationError("This CaosDB client has already been configured.");
}
if (!exists(json_file)) {
throw ConfigurationError("Configuration file does not exist.");
}
json_configuration = load_json_file(json_file);
// TODO(far future) validate against json-schema
};
auto ConfigurationManager::mGetConnectionConfiguration(
const std::string &name) const -> std::unique_ptr<ConnectionConfig> {
auto connection_json = GetConnection(name);
return connection_configuration_helper.CreateConnectionConfiguration(
connection_json);
};
auto ConfigurationManager::mGetDefaultConnectionName() const -> std::string {
auto connections = GetConnections();
if (connections.contains("default")) {
auto default_connection = connections.at("default");
if (default_connection.is_object()) {
// the name is actually "default"
return std::string("default");
} else {
assert(default_connection.is_string());
auto default_connection_name = default_connection.as_string();
// return the string value of connections.default
return std::string(default_connection_name.c_str());
}
}
if (connections.size() == 1) {
// return the key of the first and only sub-element of connections.
return connections.begin()->key().to_string();
}
throw ConfigurationError("Could not determine the default connection.");
};
auto ConfigurationManager::GetConfiguration() const -> const object & {
if (json_configuration.is_null()) {
throw ConfigurationError("This CaosDB client has not been configured.");
}
assert(json_configuration.is_object());
return json_configuration.as_object();
};
auto ConfigurationManager::GetConnections() const -> const object & {
const auto &config = GetConfiguration();
if (!config.contains("connections")) {
throw ConfigurationError(
"This CaosDB client hasn't any configured connections.");
}
const auto &connections_value = config.at("connections");
if (connections_value.is_null()) {
throw ConfigurationError(
"This CaosDB client hasn't any configured connections.");
}
assert(connections_value.is_object());
const auto &connections_object = connections_value.as_object();
if (connections_object.empty()) {
throw ConfigurationError(
"This CaosDB client hasn't any configured connections.");
}
return connections_object;
};
auto ConfigurationManager::GetConnection(const std::string &name) const
-> const object & {
const auto &connections = GetConnections();
if (connections.contains(name)) {
const auto &result_connection = connections.at(name);
assert(result_connection.is_object());
return result_connection.as_object();
}
throw ConfigurationError("The connection '" + name +
"' has not been defined.");
};
auto ConfigurationManager::InitializeDefaults() -> void {
// find the configuration file...
std::unique_ptr<path> configuration_file_path;
for (const std::string &configuration_file :
caosdb::LIBCAOSDB_CONFIGURATION_FILES_PRECEDENCE) {
if (configuration_file == "$CAOSDB_CLIENT_CONFIGURATION") {
// user specified a file via the environment variable
const auto *from_env_var = getenv("CAOSDB_CLIENT_CONFIGURATION");
if (from_env_var != nullptr) {
configuration_file_path = std::make_unique<path>(from_env_var);
if (exists(*configuration_file_path)) {
break;
} else {
configuration_file_path = nullptr;
// TODO(tf) log warning: "Configuration file under
// $CAOSDB_CLIENT_CONFIGURATION does not exist.
}
}
} else {
// check standard locations
configuration_file_path = std::make_unique<path>();
const path raw(configuration_file);
// resolve home directory
for (auto segment = raw.begin(); segment != raw.end(); ++segment) {
if (segment->string() == "$HOME") {
path expanded_home(get_home_directory());
*configuration_file_path /= expanded_home;
} else {
*configuration_file_path /= *segment;
}
}
if (exists(*configuration_file_path)) {
break;
} else {
configuration_file_path = nullptr;
}
}
}
// ... and use the configuration file
if (configuration_file_path != nullptr) {
// TODO(tf): log which file has been used.
mLoadSingleJSONConfiguration(*configuration_file_path);
} else {
// TODO(tf): log warning: no configuration files has been found
}
}
} // namespace caosdb::configuration
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <string> // for operator+, char_tr... #include <string> // for operator+, char_tr...
#include <memory> #include <memory>
#include "caosdb/authentication.h" // for Authenticator #include "caosdb/authentication.h" // for Authenticator
#include "caosdb/configuration.h"
#include "caosdb/exceptions.h" // for AuthenticationError #include "caosdb/exceptions.h" // for AuthenticationError
#include "caosdb/info/v1alpha1/main.grpc.pb.h" // for GeneralInfoService #include "caosdb/info/v1alpha1/main.grpc.pb.h" // for GeneralInfoService
#include "caosdb/info/v1alpha1/main.pb.h" // for GetVersionInfoResp... #include "caosdb/info/v1alpha1/main.pb.h" // for GetVersionInfoResp...
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
namespace caosdb::connection { namespace caosdb::connection {
using caosdb::authentication::Authenticator; using caosdb::authentication::Authenticator;
using caosdb::configuration::ConfigurationManager;
using caosdb::entity::v1alpha1::EntityTransactionService; using caosdb::entity::v1alpha1::EntityTransactionService;
using caosdb::exceptions::AuthenticationError; using caosdb::exceptions::AuthenticationError;
using caosdb::exceptions::ConnectionError; using caosdb::exceptions::ConnectionError;
...@@ -54,19 +56,20 @@ using grpc::SslCredentialsOptions; ...@@ -54,19 +56,20 @@ using grpc::SslCredentialsOptions;
PemFileCertificateProvider::PemFileCertificateProvider( PemFileCertificateProvider::PemFileCertificateProvider(
const std::string &path) { const std::string &path) {
this->cacert = load_string_file(path); this->certificate_provider = load_string_file(path);
} }
auto PemFileCertificateProvider::GetCertificatePem() const -> std::string { auto PemFileCertificateProvider::GetCertificatePem() const -> std::string {
return this->cacert; return this->certificate_provider;
} }
PemCertificateProvider::PemCertificateProvider(const std::string &cacert) { PemCertificateProvider::PemCertificateProvider(
this->cacert = cacert; const std::string &certificate_provider) {
this->certificate_provider = certificate_provider;
} }
auto PemCertificateProvider::GetCertificatePem() const -> std::string { auto PemCertificateProvider::GetCertificatePem() const -> std::string {
return this->cacert; return this->certificate_provider;
} }
ConnectionConfig::ConnectionConfig(const std::string &host, int port) { ConnectionConfig::ConnectionConfig(const std::string &host, int port) {
...@@ -107,10 +110,11 @@ TlsConnectionConfig::TlsConnectionConfig(const std::string &host, int port) ...@@ -107,10 +110,11 @@ TlsConnectionConfig::TlsConnectionConfig(const std::string &host, int port)
} }
TlsConnectionConfig::TlsConnectionConfig( TlsConnectionConfig::TlsConnectionConfig(
const std::string &host, int port, const CertificateificateProvider &cacert) const std::string &host, int port,
const CertificateProvider &certificate_provider)
: ConnectionConfig(host, port) { : ConnectionConfig(host, port) {
SslCredentialsOptions options; SslCredentialsOptions options;
options.pem_root_certs = cacert.GetCertificatePem(); options.pem_root_certs = certificate_provider.GetCertificatePem();
this->credentials = SslCredentials(options); this->credentials = SslCredentials(options);
} }
...@@ -124,12 +128,13 @@ TlsConnectionConfig::TlsConnectionConfig(const std::string &host, int port, ...@@ -124,12 +128,13 @@ TlsConnectionConfig::TlsConnectionConfig(const std::string &host, int port,
} }
TlsConnectionConfig::TlsConnectionConfig( TlsConnectionConfig::TlsConnectionConfig(
const std::string &host, int port, const CertificateificateProvider &cacert, const std::string &host, int port,
const CertificateProvider &certificate_provider,
const Authenticator &authenticator) const Authenticator &authenticator)
: ConnectionConfig(host, port) { : ConnectionConfig(host, port) {
SslCredentialsOptions options; SslCredentialsOptions options;
options.pem_root_certs = cacert.GetCertificatePem(); options.pem_root_certs = certificate_provider.GetCertificatePem();
this->credentials = grpc::CompositeChannelCredentials( this->credentials = grpc::CompositeChannelCredentials(
SslCredentials(options), authenticator.GetCallCredentials()); SslCredentials(options), authenticator.GetCallCredentials());
} }
...@@ -141,7 +146,8 @@ auto TlsConnectionConfig::GetChannelCredentials() const ...@@ -141,7 +146,8 @@ auto TlsConnectionConfig::GetChannelCredentials() const
auto TlsConnectionConfig::ToString() const -> std::string { auto TlsConnectionConfig::ToString() const -> std::string {
return "TlsConnectionConfig(" + this->GetHost() + "," + return "TlsConnectionConfig(" + this->GetHost() + "," +
std::to_string(this->GetPort()) + "," + this->cacert + ")"; std::to_string(this->GetPort()) + "," + this->certificate_provider +
")";
} }
Connection::Connection(const ConnectionConfig &config) { Connection::Connection(const ConnectionConfig &config) {
...@@ -188,4 +194,36 @@ auto operator<<(std::ostream &out, const Connection & /*connection*/) ...@@ -188,4 +194,36 @@ auto operator<<(std::ostream &out, const Connection & /*connection*/)
return std::make_unique<Transaction>(service_stub); return std::make_unique<Transaction>(service_stub);
}; };
auto ConnectionManager::mHasConnection(const std::string &name) const -> bool {
auto it = connections.find(name);
return it != connections.end();
}
auto ConnectionManager::mGetConnection(const std::string &name) const
-> const std::shared_ptr<Connection> & {
if (!HasConnection(name)) {
try {
auto connection = ConfigurationManager::GetConnectionConfiguration(name);
connections[name] = std::make_shared<Connection>(*connection.release());
} catch (const caosdb::exceptions::ConfigurationError &exc) {
throw caosdb::exceptions::UnknownConnectionError("No connection named '" +
name + "' present.");
}
}
return this->connections.at(name);
}
auto ConnectionManager::mGetDefaultConnection() const
-> const std::shared_ptr<Connection> & {
if (!HasConnection(default_connection_name)) {
default_connection_name = ConfigurationManager::GetDefaultConnectionName();
auto default_connection =
ConfigurationManager::GetDefaultConnectionConfiguration();
connections[default_connection_name] =
std::make_shared<Connection>(*default_connection.release());
}
return connections.at(default_connection_name);
}
} // namespace caosdb::connection } // namespace caosdb::connection
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#include <cassert>
#include "caosdb/constants.h" #include "caosdb/constants.h"
#include "caosdb/utility.h" #include "caosdb/utility.h"
#include "caosdb/constants.h" #include "caosdb/constants.h"
...@@ -50,7 +51,7 @@ int caosdb_connection_create_pem_file_certificate_provider( ...@@ -50,7 +51,7 @@ int caosdb_connection_create_pem_file_certificate_provider(
int caosdb_connection_delete_certificate_provider( int caosdb_connection_delete_certificate_provider(
caosdb_connection_certificate_provider *provider) { caosdb_connection_certificate_provider *provider) {
delete static_cast<caosdb::connection::CertificateificateProvider *>( delete static_cast<caosdb::connection::CertificateProvider *>(
provider->wrapped_certificate_provider); provider->wrapped_certificate_provider);
return 0; return 0;
} }
...@@ -79,7 +80,7 @@ int caosdb_connection_create_tls_connection_configuration( ...@@ -79,7 +80,7 @@ int caosdb_connection_create_tls_connection_configuration(
auto host_str = std::string(host); auto host_str = std::string(host);
if (authenticator != nullptr && provider != nullptr) { if (authenticator != nullptr && provider != nullptr) {
auto wrapped_provider = auto wrapped_provider =
static_cast<caosdb::connection::CertificateificateProvider *>( static_cast<caosdb::connection::CertificateProvider *>(
provider->wrapped_certificate_provider); provider->wrapped_certificate_provider);
auto wrapped_authenticator = auto wrapped_authenticator =
static_cast<caosdb::authentication::Authenticator *>( static_cast<caosdb::authentication::Authenticator *>(
...@@ -96,7 +97,7 @@ int caosdb_connection_create_tls_connection_configuration( ...@@ -96,7 +97,7 @@ int caosdb_connection_create_tls_connection_configuration(
*wrapped_authenticator); *wrapped_authenticator);
} else if (provider != nullptr) { } else if (provider != nullptr) {
auto wrapped_provider = auto wrapped_provider =
static_cast<caosdb::connection::CertificateificateProvider *>( static_cast<caosdb::connection::CertificateProvider *>(
provider->wrapped_certificate_provider); provider->wrapped_certificate_provider);
out->wrapped_connection_configuration = out->wrapped_connection_configuration =
new caosdb::connection::TlsConnectionConfig(host_str, port, new caosdb::connection::TlsConnectionConfig(host_str, port,
...@@ -165,4 +166,19 @@ int caosdb_connection_get_version_info( ...@@ -165,4 +166,19 @@ int caosdb_connection_get_version_info(
return 0; return 0;
} }
int caosdb_connection_connection_manager_get_default_connection(
caosdb_connection_connection *out) {
out->wrapped_connection =
caosdb::connection::ConnectionManager::GetDefaultConnection().get();
return 0;
}
int caosdb_connection_connection_manager_get_connection(
caosdb_connection_connection *out, const char *name) {
out->wrapped_connection =
caosdb::connection::ConnectionManager::GetConnection(std::string(name))
.get();
return 0;
}
} }
...@@ -21,16 +21,14 @@ ...@@ -21,16 +21,14 @@
*/ */
// A simple caosdb client // A simple caosdb client
#include <iostream> #include <iostream> // for operator<<, basic_ostream, basic_ost...
#include <memory> #include <memory> // for unique_ptr, allocator, __shared_ptr_...
#include <string> #include <string> // for operator<<, char_traits
#include "caosdb/constants.h" #include "caosdb/connection.h" // for Connection, ConnectionManager
#include "caosdb/connection.h" #include "caosdb/constants.h" // for LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_V...
#include "caosdb/authentication.h" #include "caosdb/entity.h" // for Entity
#include "caosdb/utility.h" #include "caosdb/info.h" // for VersionInfo
#include "caosdb/info.h" #include "caosdb/transaction.h" // for Transaction, UniqueResult, ResultSet
#include "caosdb/entity.h" // for Entity, EntityID
#include "caosdb/transaction.h" // for Transaction, UniqueResult
auto main() -> int { auto main() -> int {
std::cout << "CaosDB C++ client (libcaosdb " std::cout << "CaosDB C++ client (libcaosdb "
...@@ -40,34 +38,18 @@ auto main() -> int { ...@@ -40,34 +38,18 @@ auto main() -> int {
<< "We don't miss the H of caos.\n" << "We don't miss the H of caos.\n"
<< std::endl; << std::endl;
const auto pem_file = const auto &connection =
caosdb::utility::get_env_var("CAOSDB_SERVER_CERT", std::string()); caosdb::connection::ConnectionManager::GetDefaultConnection();
const auto *const host =
caosdb::utility::get_env_var("CAOSDB_SERVER_HOST", "localhost");
const auto *const port_str =
caosdb::utility::get_env_var("CAOSDB_SERVER_GRPC_PORT_HTTPS", "8443");
const auto port = std::stoi(port_str);
const auto *const user = caosdb::utility::get_env_var("CAOSDB_USER", "admin");
const auto *const password =
caosdb::utility::get_env_var("CAOSDB_PASSWORD", "caosdb");
// setup the connection
auto auth =
caosdb::authentication::PlainPasswordAuthenticator(user, password);
auto cacert = caosdb::connection::PemFileCertificateProvider(pem_file);
auto config =
caosdb::connection::TlsConnectionConfig(host, port, cacert, auth);
caosdb::connection::Connection connection(config);
// get version info of the server // get version info of the server
const auto &v_info = connection.GetVersionInfo(); const auto &v_info = connection->GetVersionInfo();
std::cout << "Server Version: " << v_info->GetMajor() << "." std::cout << "Server Version: " << v_info->GetMajor() << "."
<< v_info->GetMinor() << "." << v_info->GetPatch() << "-" << v_info->GetMinor() << "." << v_info->GetPatch() << "-"
<< v_info->GetPreRelease() << "-" << v_info->GetBuild() << v_info->GetPreRelease() << "-" << v_info->GetBuild()
<< std::endl; << std::endl;
// retrieve an entity // retrieve an entity
auto transaction(connection.CreateTransaction()); auto transaction(connection->CreateTransaction());
transaction->RetrieveById("20"); transaction->RetrieveById("20");
transaction->Execute(); transaction->Execute();
const auto &result_set = const auto &result_set =
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
# append all the test cases here (file name without the ".cpp" suffix) # append all the test cases here (file name without the ".cpp" suffix)
set(test_cases set(test_cases
test_configuration
test_connection test_connection
test_info test_info
test_transaction test_transaction
......
...@@ -42,6 +42,18 @@ ...@@ -42,6 +42,18 @@
throw; \ throw; \
}, \ }, \
exeption_type) exeption_type)
#define EXPECT_NULL(statement) \
if (statement != nullptr) { \
FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
}
#define ASSERT_NULL(statement) \
if (statement != nullptr) { \
ADD_FAIL() << "Should be a nullptr"; \
} else { \
SUCCEED(); \
}
#endif #endif
const std::string TEST_DATA_DIR = "@TEST_DATA_DIR@"; const std::string TEST_DATA_DIR = "@TEST_DATA_DIR@";
...@@ -24,10 +24,40 @@ ...@@ -24,10 +24,40 @@
#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl #include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl
#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST #include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST
#include <string> // for allocator #include <string> // for allocator
#include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE, TEST_DATA_DIR
#include "ccaosdb.h" // for caosdb_utility_get_env_var #include "ccaosdb.h" // for caosdb_utility_get_env_var
#include "caosdb/configuration.h"
TEST(test_ccaosdb, test_get_env_var) { class test_ccaosdb : public ::testing::Test {
protected:
void SetUp() override {
caosdb::configuration::ConfigurationManager::Clear();
caosdb::configuration::ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_caosdb_client.json");
}
void TearDown() override {
caosdb::configuration::ConfigurationManager::Clear();
}
};
TEST_F(test_ccaosdb, test_get_env_var) {
const char *const some_var = const char *const some_var =
caosdb_utility_get_env_var("SOME_ENV_VAR", "fall-back"); caosdb_utility_get_env_var("SOME_ENV_VAR", "fall-back");
EXPECT_EQ("fall-back", some_var); EXPECT_EQ("fall-back", some_var);
} }
TEST_F(test_ccaosdb, test_get_default_connection) {
caosdb_connection_connection out;
caosdb_connection_connection_manager_get_default_connection(&out);
EXPECT_TRUE(out.wrapped_connection);
}
TEST_F(test_ccaosdb, test_get_connection) {
caosdb_connection_connection out;
caosdb_connection_connection_manager_get_connection(&out,
"local-caosdb-admin");
EXPECT_TRUE(out.wrapped_connection);
}
/*
*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include <gtest/gtest-message.h> // for Message
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver
#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, TEST
#include <string> // for operator+, allocator, string
#include "caosdb/configuration.h" // for ConfigurationManager, Configurati...
#include "caosdb/exceptions.h" // for ConfigurationError
#include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE, TEST_DATA_DIR
namespace caosdb::configuration {
class test_configuration : public ::testing::Test {
protected:
void SetUp() override { ConfigurationManager::Clear(); }
void TearDown() override { ConfigurationManager::Clear(); }
};
TEST_F(test_configuration, load_json) {
ConfigurationManager::LoadSingleJSONConfiguration(TEST_DATA_DIR +
"/test_caosdb_client.json");
EXPECT_THROW_MESSAGE(
ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "This CaosDB client has already been configured.");
ConfigurationManager::Clear();
EXPECT_THROW_MESSAGE(
ConfigurationManager::LoadSingleJSONConfiguration("anything"),
ConfigurationError, "Configuration file does not exist.");
ConfigurationManager::Clear();
}
TEST_F(test_configuration, get_default_connection_configuration_error) {
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
"This CaosDB client has not been configured.");
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections1.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections2.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_broken_caosdb_client_no_connections3.json");
EXPECT_THROW_MESSAGE(ConfigurationManager::GetDefaultConnectionName(),
ConfigurationError,
"This CaosDB client hasn't any configured connections.");
ConfigurationManager::Clear();
}
} // namespace caosdb::configuration
...@@ -21,14 +21,29 @@ ...@@ -21,14 +21,29 @@
*/ */
#include <gtest/gtest-message.h> // for Message #include <gtest/gtest-message.h> // for Message
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiRes... #include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver
#include <memory> // for allocator, operator!=, shar... #include <memory> // for allocator, operator!=, shared_ptr
#include "caosdb/connection.h" // for PemCertificateProvider, Insecure... #include <string> // for operator+, string
#include "gtest/gtest_pred_impl.h" // for Test, AssertionResult, EXPE... #include "caosdb/configuration.h" // for ConfigurationManager
#include "caosdb/connection.h" // for ConnectionManager, InsecureConnec...
#include "caosdb/exceptions.h" // for UnknownConnectionError
#include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE, TEST_DATA_DIR
#include "gtest/gtest_pred_impl.h" // for Test, AssertionResult, TestInfo
namespace caosdb::connection { namespace caosdb::connection {
using caosdb::configuration::ConfigurationManager;
TEST(test_connection, configure_insecure_localhost_8080) { class test_connection : public ::testing::Test {
protected:
void SetUp() override {
ConfigurationManager::Clear();
ConfigurationManager::LoadSingleJSONConfiguration(
TEST_DATA_DIR + "/test_caosdb_client.json");
};
void TearDown() override { ConfigurationManager::Clear(); };
};
TEST_F(test_connection, configure_insecure_localhost_8080) {
InsecureConnectionConfig config("localhost", 8000); InsecureConnectionConfig config("localhost", 8000);
EXPECT_EQ("localhost", config.GetHost()); EXPECT_EQ("localhost", config.GetHost());
...@@ -37,7 +52,7 @@ TEST(test_connection, configure_insecure_localhost_8080) { ...@@ -37,7 +52,7 @@ TEST(test_connection, configure_insecure_localhost_8080) {
EXPECT_TRUE(icc != nullptr); EXPECT_TRUE(icc != nullptr);
} }
TEST(test_connection, configure_ssl_localhost_8080) { TEST_F(test_connection, configure_ssl_localhost_8080) {
auto cacert = PemCertificateProvider("ca chain"); auto cacert = PemCertificateProvider("ca chain");
TlsConnectionConfig config("localhost", 44300, cacert); TlsConnectionConfig config("localhost", 44300, cacert);
...@@ -47,4 +62,20 @@ TEST(test_connection, configure_ssl_localhost_8080) { ...@@ -47,4 +62,20 @@ TEST(test_connection, configure_ssl_localhost_8080) {
EXPECT_TRUE(sslcc != nullptr); EXPECT_TRUE(sslcc != nullptr);
} }
TEST_F(test_connection, connection_manager_unknown_connection) {
EXPECT_THROW_MESSAGE(ConnectionManager::GetConnection("test"),
caosdb::exceptions::UnknownConnectionError,
"No connection named 'test' present.");
}
TEST_F(test_connection, connection_manager_get_default_connection) {
auto connection = ConnectionManager::GetDefaultConnection();
EXPECT_EQ(connection, ConnectionManager::GetConnection("local-caosdb"));
}
TEST_F(test_connection, connection_manager_get_connection) {
EXPECT_TRUE(ConnectionManager::GetConnection("local-caosdb-admin"));
}
} // namespace caosdb::connection } // namespace caosdb::connection
{
}
{
"connections": null
}
{
"connections": {
}
}
{
"connections": {
"default": "local-caosdb",
"local-caosdb-admin": {
"host": "localhost",
"port": 8443,
"server_certificate_path": "some/path/cacert.pem",
"authentication": {
"type": "plain",
"username": "admin",
"password": "caosdb"
}
},
"local-caosdb": {
"host": "localhost",
"port": 8443,
"server_certificate_path": "some/path/cacert.pem",
"authentication": {
"type": "plain",
"username": "me",
"password": "secret!"
}
}
},
"extension": {
"this is my": "special option"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment