Skip to content
Snippets Groups Projects
Select Git revision
  • aa12b35fadf798b6c26a06e97cfab0815b0c7485
  • main default protected
  • f-sss4grpc
  • dev
  • 108-implement-rpc-call-for-server-side-scripting
  • f-windows-conan-create
  • f-to-string
  • f-update-requirements
  • f-related-projects
  • f-role
  • f-remote-path
  • f-rel-path
  • f-consol-message
  • v0.3.0
  • v0.2.2
  • v0.2.1
  • v0.2.0
  • v0.1.2
  • v0.1.1
  • v0.1
  • v0.0.19
  • v0.0.18
  • v0.0.16
  • v0.0.15
  • v0.0.10
  • v0.0.9
  • v0.0.8
  • v0.0.7
  • v0.0.6
  • v0.0.5
  • v0.0.4
  • v0.0.3
  • v0.0.2
33 results

connection.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    connection.h 7.50 KiB
    /*
     * 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/>.
     *
     */
    
    #ifndef CAOSDB_CONNECTION_H
    #define CAOSDB_CONNECTION_H
    /**
     * @file caosdb/connection.h
     * @author Timm Fitschen
     * @date 2021-05-18
     * @brief Configuration and setup of the connection.
     */
    #ifdef BUILD_ACM
    #include "caosdb/acm/user.h"                  // for User
    #include "caosdb/acm/v1alpha1/main.grpc.pb.h" // for AccessControlMan...
    #endif
    #include "caosdb/authentication.h"         // for Authenticator
    #include "caosdb/configuration.h"          // for ConnectionConfigura...
    #include "caosdb/entity/v1/main.grpc.pb.h" // for EntityTransactionSe...
    #include "caosdb/info.h"                   // for VersionInfo
    #include "caosdb/info/v1/main.grpc.pb.h"   // for GeneralInfoService:...
    #include "caosdb/transaction.h"            // for Transaction
    #include "caosdb/transaction_status.h"     // for TransactionStatus
    #include <filesystem>                      // for path
    #include <grpcpp/channel.h>                // for Channel
    #include <map>                             // for map
    #include <memory>                          // for shared_ptr, unique_ptr
    #include <string>                          // for string, basic_string
    #ifdef BUILD_ACM
    #include <vector> // for vector
    #endif
    
    namespace caosdb::connection {
    #ifdef BUILD_ACM
    using caosdb::acm::User;
    using caosdb::acm::v1alpha1::AccessControlManagementService;
    #endif
    using caosdb::authentication::Authenticator;
    using caosdb::configuration::ConnectionConfiguration;
    using caosdb::entity::v1::EntityTransactionService;
    using caosdb::entity::v1::FileTransmissionService;
    using caosdb::info::VersionInfo;
    using caosdb::info::v1::GeneralInfoService;
    using caosdb::transaction::Transaction;
    using caosdb::transaction::TransactionStatus;
    using std::filesystem::path;
    
    /**
     * @brief A reusable connection to a CaosDBServer.
     */
    class Connection {
    public:
      explicit Connection(const ConnectionConfiguration &configuration);
    
      /**
       * 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();
      };
    
      /**
       * Create a new transaction object which uses this connection and return it.
       */
      [[nodiscard]] auto CreateTransaction() const -> std::unique_ptr<Transaction>;
    
    #ifdef BUILD_ACM
      /**
       * Retrieve a single user.
       */
      // TODO(tf) find a way to deal with this:
      // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
      [[nodiscard]] auto RetrieveSingleUser(const std::string &realm, const std::string &name) const
        -> User;
    
      /**
       * Create a new user.
       */
      auto CreateSingleUser(const User &user) const -> void;
    
      /**
       * Delete an existing user.
       */
      // TODO(tf) find a way to deal with this:
      // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
      auto DeleteSingleUser(const std::string &realm, const std::string &name) const -> void;
    
      /**
       * List known users.
       */
      auto ListUsers() const -> std::vector<User>;
    #endif
    
    private:
      /// 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;
      /// Service for file transmission (download and upload). We use a shared
      /// pointer because Transaction instances also own this service stub.
      std::shared_ptr<FileTransmissionService::Stub> file_transmission_service;
    #ifdef BUILD_ACM
      /// Service for Access Controll Management (Role, Useraccounts, Permissions).
      /// We use a unique pointer because only this connection owns and uses this
      /// service.
      std::unique_ptr<AccessControlManagementService::Stub> access_controll_management_service;
    #endif
    };
    
    /**
     * Lazily creates and caches reusable connection instances. Singleton.
     *
     * This class delegates the configuration of new connections to the global
     * ConfigurationManager.
     *
     * A reset of the ConfigurationManager also resets the ConnectionManager.
     *
     * @brief Lazily creates and caches reusable connection instances.
     */
    class ConnectionManager {
    private:
      mutable std::map<std::string, std::shared_ptr<Connection>> connections;
      mutable std::string default_connection_name;
      inline ConnectionManager(){};
    
      auto mHasConnection(const std::string &name) const -> bool;
    
      auto mGetConnection(const std::string &name) const -> const std::shared_ptr<Connection> &;
    
      auto mGetDefaultConnection() const -> const std::shared_ptr<Connection> &;
    
      inline auto mReset() -> void {
        connections.clear();
        default_connection_name = std::string();
      }
    
    public:
      static ConnectionManager &GetInstance() {
        static ConnectionManager instance;
        return instance;
      };
    
      inline static auto HasConnection(const std::string &name) -> bool {
        return ConnectionManager::GetInstance().mHasConnection(name);
      };
    
      inline static auto GetConnection(const std::string &name) -> const std::shared_ptr<Connection> & {
        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();
      };
    
      inline static auto Reset() -> void { return ConnectionManager::GetInstance().mReset(); };
    
      ConnectionManager(ConnectionManager const &) = delete;
      void operator=(ConnectionManager const &) = delete;
    };
    
    } // namespace caosdb::connection
    #endif