#ifndef __VEREIGN_GRPC_SERVER_API_HH #define __VEREIGN_GRPC_SERVER_API_HH #include <thread> #include <grpcpp/server.h> #include <boost/asio/io_context.hpp> #include <boost/asio/ssl/context.hpp> #include <boost/asio/executor_work_guard.hpp> namespace vereign { namespace restapi { class Client; class ClientSession; } namespace grpc { namespace asio = boost::asio; /** * Server is a grpc server that provides the Vereign services. * * It bootstraps the grpc server, http client, http client session and * Vereign services. */ class Server { public: /** * Constructs and bootstraps the server. * * @param listenAddress gRPC listen address, for example "localhost:". * @param vereignHost Vereign restapi host. * @param vereignPort Vereign restapi port - https, 443... */ explicit Server( const std::string& listenAddress, const std::string& vereignHost, const std::string& vereignPort, // FIXME: the public key must come from a storage const std::string& publicKey ); /** * Shutdowns the server. * * @see Server::Shutdown */ ~Server(); // Disable copying Server(const Server&) = delete; Server& operator=(const Server&) = delete; /** * Shutdown the server. * * It will cancel all pending http requests to the Vereign restapi. * Blocks for all pending gRPC handlers to finish. */ void Shutdown(); /** * Returns the port that the gRPC server listens to. * * This is useful if you construct the server with ephemeral port. * Then this method will return the port that the OS assigned to the gRPC * socket. */ int SelectedPort() const; private: int selected_port_; asio::io_context ioc_; asio::executor_work_guard<asio::io_context::executor_type> work_guard_; asio::ssl::context ssl_context_; std::unique_ptr<vereign::restapi::Client> client_; std::unique_ptr<vereign::restapi::ClientSession> client_session_; std::vector<std::unique_ptr<::grpc::Service>> services_; std::unique_ptr<::grpc::Server> server_; std::thread server_thread_; std::thread service_thread_; }; } } #endif