Skip to content
Snippets Groups Projects

Better Error Handling and Logging

Merged Timm Fitschen requested to merge dev into main
All threads resolved!
Files
17
+ 53
83
@@ -27,116 +27,83 @@
* @date 2021-05-18
* @brief Configuration and setup of the connection.
*/
#include <iosfwd> // for ostream
#include <map> // for map
#include <memory> // for shared_ptr, unique_ptr
#include <string> // for string, basic_string
#include "boost/filesystem/path.hpp" // for path
#include "caosdb/authentication.h" // for Authenticator
#include "caosdb/configuration.h" // for ConnectionConfigura...
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe...
#include "caosdb/info.h" // for VersionInfo
#include "caosdb/info/v1alpha1/main.grpc.pb.h" // for GeneralInfoService:...
#include "caosdb/transaction.h" // for Transaction
#include "caosdb/transaction_status.h" // for TransactionStatus
#include "grpcpp/channel.h" // for Channel
#include "grpcpp/security/credentials.h" // for ChannelCredentials
namespace caosdb::connection {
using boost::filesystem::path;
using caosdb::authentication::Authenticator;
using caosdb::configuration::ConnectionConfiguration;
using caosdb::entity::v1alpha1::EntityTransactionService;
using caosdb::info::VersionInfo;
using caosdb::info::v1alpha1::GeneralInfoService;
using caosdb::transaction::Transaction;
using grpc::ChannelCredentials;
class CertificateProvider {
public:
[[nodiscard]] auto virtual GetCertificatePem() const -> std::string = 0;
virtual ~CertificateProvider() = default;
};
class PemFileCertificateProvider : public CertificateProvider {
private:
std::string certificate_provider;
public:
explicit PemFileCertificateProvider(const std::string &path);
[[nodiscard]] auto GetCertificatePem() const -> std::string override;
};
class PemCertificateProvider : public CertificateProvider {
private:
std::string certificate_provider;
public:
explicit PemCertificateProvider(const std::string &certificate_provider);
[[nodiscard]] auto GetCertificatePem() const -> std::string override;
};
using caosdb::transaction::TransactionStatus;
/**
* @brief Configuration of the CaosDB connection.
* @brief A reusable connection to a CaosDBServer.
*/
class ConnectionConfiguration {
private:
std::string host;
int port;
class Connection {
public:
ConnectionConfiguration(const std::string &host, int port);
virtual ~ConnectionConfiguration() = default;
friend auto operator<<(std::ostream &out,
const ConnectionConfiguration &configuration)
-> std::ostream &;
[[nodiscard]] auto virtual ToString() const -> std::string = 0;
[[nodiscard]] auto GetHost() const -> std::string;
[[nodiscard]] auto GetPort() const -> int;
[[nodiscard]] auto virtual GetChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> = 0;
};
explicit Connection(const ConnectionConfiguration &configuration);
class InsecureConnectionConfiguration : public ConnectionConfiguration {
private:
std::shared_ptr<ChannelCredentials> credentials;
/**
* Request the server's version and return the status of this request after
* termination..
*
* The version is stored in the connection object and may be retrieved via
* GetVersionInfo() if the request was successful.
*
* This method does not throw any exceptions. Errors are indicated in the
* return value instead.
*/
auto RetrieveVersionInfoNoExceptions() const noexcept -> TransactionStatus;
/**
* Request and return the server's version.
*
* If the request terminated unsuccessfully, a corresponding exception is
* being thrown.
*/
auto RetrieveVersionInfo() const -> const VersionInfo &;
/**
* Return the server's version.
*
* Clients need to call RetrieveVersionInfo() or
* RetrieveVersionInfoNoExceptions() before the version info is locally
* available. Otherwise a nullptr is being returned.
*/
[[nodiscard]] inline auto GetVersionInfo() const noexcept
-> const VersionInfo * {
return this->version_info.get();
};
public:
InsecureConnectionConfiguration(const std::string &host, int port);
[[nodiscard]] auto GetChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto ToString() const -> std::string override;
};
[[nodiscard]] auto CreateTransaction() const -> std::unique_ptr<Transaction>;
class TlsConnectionConfiguration : public ConnectionConfiguration {
private:
std::shared_ptr<ChannelCredentials> credentials;
std::string certificate_provider;
public:
TlsConnectionConfiguration(const std::string &host, int port);
TlsConnectionConfiguration(const std::string &host, int port,
const Authenticator &authenticator);
TlsConnectionConfiguration(const std::string &host, int port,
const CertificateProvider &certificate_provider);
TlsConnectionConfiguration(const std::string &host, int port,
const CertificateProvider &certificate_provider,
const Authenticator &authenticator);
[[nodiscard]] auto GetChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto ToString() const -> std::string override;
};
/**
* @brief A reusable connection to a CaosDBServer.
*/
class Connection {
/// GRPC-Channel (HTTP/2 Connection plus Authentication). We use a shared
/// pointer because Transaction instances also own the channel.
std::shared_ptr<grpc::Channel> channel;
/// Service for retrieving the server's version. We use a unique pointer
/// because only this connection owns and uses this service.
std::unique_ptr<GeneralInfoService::Stub> general_info_service;
/// The server's version. It's mutable because it is rather a cache than a
/// data member which is subject to change.
mutable std::unique_ptr<VersionInfo> version_info;
/// Service for entity transactions. We use a shared pointer because
/// Transaction instances also own this service stub.
std::shared_ptr<EntityTransactionService::Stub> entity_transaction_service;
public:
explicit Connection(const ConnectionConfiguration &configuration);
friend auto operator<<(std::ostream &out, const Connection &connection)
-> std::ostream &;
[[nodiscard]] auto GetVersionInfo() const -> std::unique_ptr<VersionInfo>;
[[nodiscard]] auto CreateTransaction() const -> std::unique_ptr<Transaction>;
};
/**
@@ -182,6 +149,9 @@ public:
return ConnectionManager::GetInstance().mGetConnection(name);
};
/**
* Get the connection marked by the "default" key in the configuration.
*/
inline static auto GetDefaultConnection()
-> const std::shared_ptr<Connection> & {
return ConnectionManager::GetInstance().mGetDefaultConnection();
Loading