// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the Apache 2.0 License. #pragma once #include "ccf/historical_queries_interface.h" #include "ccf/indexing/indexer_interface.h" #include "ccf/node_subsystem_interface.h" namespace ccfapp { struct AbstractNodeContext { protected: std::map> subsystems; void install_subsystem( const std::shared_ptr& subsystem, const std::string& name) { if (subsystem == nullptr) { return; } const auto it = subsystems.find(name); if (it != subsystems.end()) { throw std::logic_error( fmt::format("Already registered subsystem {}", name)); } subsystems.emplace_hint(it, name, subsystem); } template std::shared_ptr get_subsystem(const std::string& name) const { const auto it = subsystems.find(name); if (it != subsystems.end()) { // NB: May still be nullptr, if it->second.get() is not a T* return std::dynamic_pointer_cast(it->second); } return nullptr; } public: virtual ~AbstractNodeContext() = default; template void install_subsystem(const std::shared_ptr& subsystem) { install_subsystem(subsystem, T::get_subsystem_name()); } template std::shared_ptr get_subsystem() const { return get_subsystem(T::get_subsystem_name()); } virtual ccf::NodeId get_node_id() const { return {}; } virtual crypto::Pem get_self_signed_certificate() const { return {}; } ccf::historical::AbstractStateCache& get_historical_state() { auto historical_state_cache = get_subsystem(); if (historical_state_cache == nullptr) { throw std::logic_error( "Calling get_historical_state before subsystem is installed"); } return *historical_state_cache; } ccf::indexing::IndexingStrategies& get_indexing_strategies() { auto indexer = get_subsystem(); if (indexer == nullptr) { throw std::logic_error( "Calling get_indexing_strategies before subsystem is installed"); } return *indexer; } }; }