Skip to content
Snippets Groups Projects
Select Git revision
  • 8cfbdae9fe7ddf279df527a31d9f0e067bf26dc7
  • 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

configuration.h

Blame
    • Joscha Schmiedt's avatar
      fbbef962
      Move static singletons to namespace level · fbbef962
      Joscha Schmiedt authored
      The singleton instances of ConfigurationManager and ConnectionManager
      were stored as static variables in the static GetInstance methods.
      
      This causes weird errors on Windows where the singleton instance is not
      initialized in time and remains empty. This could be due to
      undefined behavior?
      
      Moving them to the namespace level fixes the unit test errors.
      fbbef962
      History
      Move static singletons to namespace level
      Joscha Schmiedt authored
      The singleton instances of ConfigurationManager and ConnectionManager
      were stored as static variables in the static GetInstance methods.
      
      This causes weird errors on Windows where the singleton instance is not
      initialized in time and remains empty. This could be due to
      undefined behavior?
      
      Moving them to the namespace level fixes the unit test errors.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    configuration.h 6.94 KiB
    /*
     * This file is a part of the LinkAhead Project.
     *
     * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
     * Copyright (C) 2021-2024 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 LINKAHEAD_CONFIGURATION_H
    #define LINKAHEAD_CONFIGURATION_H
    
    #include "linkahead/authentication.h"       // for Authenticator, PlainPassw...
    #include "linkahead/certificate_provider.h" // for CertificateProvider, path
    #include "linkahead/exceptions.h"           // for ConfigurationError
    #include "linkahead/utility.h"              // for load_json_file
    #include <google/protobuf/arena.h>          // for Arena
    #include <google/protobuf/extension_set.h>  // for Arena
    #include <grpcpp/security/credentials.h>    // for ChannelCredentials
    #include <filesystem>                       // for path, exists
    #include <iosfwd>                           // for ostream
    #include <memory>                           // for shared_ptr, unique_ptr
    #include <string>                           // for string
    
    namespace linkahead::configuration {
    using google::protobuf::Arena;
    using grpc::ChannelCredentials;
    using linkahead::authentication::Authenticator;
    using linkahead::authentication::PlainPasswordAuthenticator;
    using linkahead::exceptions::ConfigurationError;
    using linkahead::utility::JsonValue;
    using linkahead::utility::load_json_file;
    using std::filesystem::exists;
    using std::filesystem::path;
    
    const std::string logger_name = "linkahead::configuration";
    
    /**
     * @brief Configuration of the LinkAhead connection.
     */
    class ConnectionConfiguration {
    private:
      std::string host;
      int port;
    
    public:
      ConnectionConfiguration(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;
    };
    
    class InsecureConnectionConfiguration : public ConnectionConfiguration {
    private:
      std::shared_ptr<ChannelCredentials> credentials;
    
    public:
      InsecureConnectionConfiguration(const std::string &host, int port);
      [[nodiscard]] auto GetChannelCredentials() const -> std::shared_ptr<ChannelCredentials> override;
      [[nodiscard]] auto ToString() const -> std::string override;
    };
    
    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;
    };
    
    /**
     * Reads the configuration file and keeps the configuration. Singleton.
     *
     * Currently, this class can only read a single configuration file. No merging
     * or overwriting is supported.
     */
    class ConfigurationManager {
    public:
      static ConfigurationManager &GetInstance();
      ;
    
      /**
       * See mReset.
       */
      inline static auto Reset() noexcept -> int { return GetInstance().mReset(); }
    
      /**
       * See mClear.
       */
      inline static auto Clear() noexcept -> int { return GetInstance().mClear(); }
    
      /**
       * See mLoadSingleJSONConfiguration.
       */
      inline static auto LoadSingleJSONConfiguration(const path &json_file) -> void {
        GetInstance().mLoadSingleJSONConfiguration(json_file);
      }
    
      /**
       * See mGetConnectionConfiguration.
       */
      inline static auto GetConnectionConfiguration(const std::string &name)
        -> std::unique_ptr<ConnectionConfiguration> {
        return GetInstance().mGetConnectionConfiguration(name);
      }
    
      /**
       * Return the ConnectionConfiguration for the default connection.
       */
      inline static auto GetDefaultConnectionConfiguration()
        -> std::unique_ptr<ConnectionConfiguration> {
        return GetInstance().mGetConnectionConfiguration(GetInstance().mGetDefaultConnectionName());
      }
    
      /**
       * See mGetDefaultConnectionName.
       */
      inline static auto GetDefaultConnectionName() -> std::string {
        return GetInstance().mGetDefaultConnectionName();
      }
    
      ConfigurationManager(ConfigurationManager const &) = delete;
      void operator=(ConfigurationManager const &) = delete;
    
      inline static auto GetArena() -> Arena * { return &GetInstance().arena; }
    
    private:
      Arena arena;
      JsonValue json_configuration;
      static ConfigurationManager mInstance;
    
      inline ConfigurationManager()
        : json_configuration(nullptr){
            // InitializeDefaults();
          };
    
      /**
       * Initialize this ConfigurationManager with the defaults.
       *
       * Currently, this means, that the ConfigurationManager attempts to load the
       * first existing file from the LIBLINKAHEAD_CONFIGURATION_FILES_PRECEDENCE list
       * of file locations.
       */
      auto InitializeDefaults() -> int;
    
      /**
       * Reset this ConfigurationManager.
       *
       * The current configuration is deleted and a new configuration is being
       * loaded via InitializeDefaults.
       */
      auto mReset() noexcept -> int;
    
      /**
       * Clear this ConfigurationManager.
       *
       * Afterwards, this ConfigurationManager is uninitilized.
       *
       * In contrast to mReset, this method only deletes the current configuration
       * but does not load a new one via InitializeDefaults.
       */
      auto mClear() noexcept -> int;
    
      /**
       * Load a configuration from a json file.
       */
      auto mLoadSingleJSONConfiguration(const path &json_file) -> void;
    
      /**
       * Return the ConnectionConfiguration for the connection of the given name.
       */
      auto mGetConnectionConfiguration(const std::string &name) const
        -> std::unique_ptr<ConnectionConfiguration>;
    
      /**
       * Return the ConnectionConfiguration for the default connection.
       */
      auto mGetDefaultConnectionName() const -> std::string;
    };
    
    } // namespace linkahead::configuration
    #endif