Scorum
application.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #pragma once
25 
29 
30 #include <graphene/net/node.hpp>
31 
32 #include <fc/api.hpp>
33 #include <fc/rpc/api_connection.hpp>
34 #include <fc/rpc/websocket_api.hpp>
35 
36 #include <boost/program_options.hpp>
37 
38 #define SCORUMD_CONFIG_FILE_NAME "config.ini"
39 
73 namespace scorum {
74 namespace chain {
75 struct genesis_state_type;
76 }
77 } // namespace scorum
78 
79 namespace scorum {
80 namespace app {
81 
82 namespace detail {
83 class application_impl;
84 }
85 
86 class abstract_plugin;
87 class plugin;
88 class application;
89 
90 class network_broadcast_api;
91 class login_api;
92 class database_api;
93 
95 
96 void print_program_options(std::ostream& stream, const boost::program_options::options_description& options);
97 
99 {
100 public:
101  application();
102  application(std::shared_ptr<chain::database> db);
103  ~application();
104 
105  void set_program_options(boost::program_options::options_description& command_line_options,
106  boost::program_options::options_description& configuration_file_options) const;
107  void initialize(const boost::program_options::variables_map& options);
108  void initialize_plugins(const boost::program_options::variables_map& options);
109  void startup();
110  void shutdown();
111  void startup_plugins();
112  void shutdown_plugins();
113 
114  std::vector<std::string> get_default_apis() const;
115  std::vector<std::string> get_default_plugins() const;
116 
117  bool is_read_only() const
118  {
119  return _read_only;
120  }
121 
122  template <typename PluginType> std::shared_ptr<PluginType> register_plugin()
123  {
124  auto plug = std::make_shared<PluginType>(this);
126  return plug;
127  }
128 
129  void register_abstract_plugin(std::shared_ptr<abstract_plugin> plug);
130  void enable_plugin(const std::string& name);
131  std::shared_ptr<abstract_plugin> get_plugin(const std::string& name) const;
132 
133  template <typename PluginType> std::shared_ptr<PluginType> get_plugin(const std::string& name) const
134  {
135  std::shared_ptr<abstract_plugin> abs_plugin = get_plugin(name);
136  std::shared_ptr<PluginType> result = std::dynamic_pointer_cast<PluginType>(abs_plugin);
137  FC_ASSERT(result != std::shared_ptr<PluginType>());
138  return result;
139  }
140 
141  graphene::net::node_ptr p2p_node();
142  std::shared_ptr<chain::database> chain_database() const;
143  // std::shared_ptr<graphene::db::object_database> pending_trx_database() const;
144 
145  void set_block_production(bool producing_blocks);
146  fc::optional<api_access_info> get_api_access_info(const std::string& username) const;
147  void set_api_access_info(const std::string& username, api_access_info&& permissions);
148 
152  void register_api_factory(const std::string& name, std::function<fc::api_ptr(const api_context&)> factory);
153 
157  template <typename Api> void register_api_factory(const std::string& name)
158  {
159  idump((name));
160 
161  register_api_factory(name, [](const api_context& ctx) -> fc::api_ptr {
162  // apparently the compiler is smart enough to downcast shared_ptr< api<Api> > to shared_ptr< api_base >
163  // automatically
164  // see http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast for example
165  std::shared_ptr<Api> api = std::make_shared<Api>(ctx);
166  api->on_api_startup();
167  return std::make_shared<fc::api<Api>>(api);
168  });
169  }
170 
174  fc::api_ptr create_api_by_name(const api_context& ctx);
175 
176  void get_max_block_age(int32_t& result);
177 
178  fc::api<network_broadcast_api>& get_write_node_net_api();
179 
180  fc::optional<std::string> _remote_endpoint;
181  fc::optional<fc::api<network_broadcast_api>> _remote_net_api;
182  fc::optional<fc::api<login_api>> _remote_login;
183  fc::http::websocket_connection_ptr _ws_ptr;
184  std::shared_ptr<fc::rpc::websocket_api_connection> _ws_apic;
185  fc::http::websocket_client _client;
186 
187 private:
188  const std::string print_config(const boost::program_options::variables_map& vm);
189 
190  std::shared_ptr<detail::application_impl> my;
191 
192  boost::program_options::options_description _cli_options;
193  boost::program_options::options_description _cfg_options;
194 
195  const std::shared_ptr<plugin> null_plugin;
196 
197  bool _read_only = false;
198 };
199 
200 template <class C, typename... Args>
201 boost::signals2::scoped_connection
202 connect_signal(boost::signals2::signal<void(Args...)>& sig, C& c, void (C::*f)(Args...))
203 {
204  std::weak_ptr<C> weak_c = c.shared_from_this();
205  return sig.connect([weak_c, f](Args... args) {
206  std::shared_ptr<C> shared_c = weak_c.lock();
207  if (!shared_c)
208  return;
209  ((*shared_c).*f)(args...);
210  });
211 }
212 
213 fc::path get_data_dir_path(const boost::program_options::variables_map& options);
214 
215 fc::path get_config_file_path(const boost::program_options::variables_map& options);
216 
217 void create_config_file_if_not_exist(const fc::path& config_ini_path,
218  const boost::program_options::options_description& cfg_options);
219 
220 } // namespace app
221 } // namespace scorum
std::vector< std::string > get_default_apis() const
void set_block_production(bool producing_blocks)
void enable_plugin(const std::string &name)
std::shared_ptr< chain::database > chain_database() const
std::shared_ptr< PluginType > get_plugin(const std::string &name) const
fc::optional< fc::api< network_broadcast_api > > _remote_net_api
void initialize(const boost::program_options::variables_map &options)
void register_api_factory(const std::string &name)
std::shared_ptr< PluginType > register_plugin()
fc::http::websocket_connection_ptr _ws_ptr
std::shared_ptr< abstract_plugin > get_plugin(const std::string &name) const
fc::optional< fc::api< login_api > > _remote_login
void set_program_options(boost::program_options::options_description &command_line_options, boost::program_options::options_description &configuration_file_options) const
graphene::net::node_ptr p2p_node()
void register_abstract_plugin(std::shared_ptr< abstract_plugin > plug)
fc::http::websocket_client _client
std::shared_ptr< fc::rpc::websocket_api_connection > _ws_apic
fc::api< network_broadcast_api > & get_write_node_net_api()
std::vector< std::string > get_default_plugins() const
fc::optional< api_access_info > get_api_access_info(const std::string &username) const
void register_api_factory(const std::string &name, std::function< fc::api_ptr(const api_context &)> factory)
fc::api_ptr create_api_by_name(const api_context &ctx)
void get_max_block_age(int32_t &result)
void set_api_access_info(const std::string &username, api_access_info &&permissions)
fc::optional< std::string > _remote_endpoint
void initialize_plugins(const boost::program_options::variables_map &options)
void print_program_options(std::ostream &stream, const boost::program_options::options_description &options)
boost::signals2::scoped_connection connect_signal(boost::signals2::signal< void(Args...)> &sig, C &c, void(C::*f)(Args...))
void print_application_version()
fc::path get_data_dir_path(const boost::program_options::variables_map &options)
void create_config_file_if_not_exist(const fc::path &config_ini_path, const boost::program_options::options_description &cfg_options)
fc::path get_config_file_path(const boost::program_options::variables_map &options)
Definition: asset.cpp:15