Commit ba82dd36 authored by Ciarán Ó Rourke's avatar Ciarán Ó Rourke
Browse files

Support command line parsing and configuration files

Change log:
* src/utils directory for configuration, logging, etc
* Config class for handling configuration (command line parsing, etc)
* include Catch2 and CLI11 as system files so clang-tidy will ignore
  them
* support basic command line options:
      - hostname (positional, required)
      - number of threads
      - http_port
      - https_port
* add configuration to fiphoboserver executable main function
* return on exception for incompatible hostname
* return after parsing command line arguments if arguments are bad
  or --help is supplied
* don't pass command line arguments to folly
* Config returns struct of command line options
* accept configuration options from config file
* option to write current configuration to file
* integration tests: reflect changes to fiphoboserver executable
parent 2069f5b6
Pipeline #1432 passed with stages
in 6 minutes and 54 seconds
......@@ -18,6 +18,11 @@ option(
add_subdirectory(src)
target_include_directories(
server SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
)
if(CUSTOM_DOCU_PATH)
add_subdirectory(doc)
endif(CUSTOM_DOCU_PATH)
......
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,8 @@ add_executable(
fiphoboserver
main.cc
utils/config.cc
)
target_compile_features(fiphoboserver PUBLIC cxx_std_14)
......@@ -26,4 +28,4 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/../test/users.txt
/tmp/users.txt
)
\ No newline at end of file
)
......@@ -13,41 +13,46 @@
#include <proxygen/httpserver/HTTPServer.h>
#include <proxygen/httpserver/RequestHandlerFactory.h>
#include "fiphoboserver_exception.h"
#include "server/handler_factory.h"
#include "utils/config.h"
using folly::SocketAddress;
using Protocol = proxygen::HTTPServer::Protocol;
DEFINE_int32(http_port, 11000, "Port to listen on with HTTP protocol");
DEFINE_int32(h2_port, 11002, "Port to listen on with HTTP/2 protocol");
DEFINE_string(ip, "localhost", "IP/Hostname to bind to");
DEFINE_int32(
threads,
0,
"Number of threads to listen on. Numbers <= 0 "
"will use the number of cores on this machine.");
int main(int argc, char* argv[])
{
folly::init(&argc, &argv, true);
int folly_argc = 1;
folly::init(&folly_argc, &argv, false);
fiphoboserver::util::Config config;
fiphoboserver::util::cli_options parse_result;
std::vector<proxygen::HTTPServer::IPConfig> IPs // NOLINT
= {
{SocketAddress(FLAGS_ip, FLAGS_http_port, true), Protocol::HTTP},
{SocketAddress(FLAGS_ip, FLAGS_h2_port, true), Protocol::HTTP2},
};
try {
parse_result = config.parse(argc, argv);
}
catch (const fiphoboserver::FIPhoboServerException& ex) {
return 0;
}
if (FLAGS_threads <= 0) {
FLAGS_threads = sysconf(_SC_NPROCESSORS_ONLN);
CHECK_GT(FLAGS_threads, 0);
std::vector<proxygen::HTTPServer::IPConfig> IPs; // NOLINT
try {
IPs = {
{SocketAddress(parse_result.ip, parse_result.http_port, true),
Protocol::HTTP},
{SocketAddress(parse_result.ip, parse_result.http2_port, true),
Protocol::HTTP2},
};
}
catch (const std::system_error& ex) {
std::cerr << "fiphoboserver: " << ex.what() << '\n';
return 1;
}
proxygen::HTTPServerOptions options;
options.threads = static_cast<size_t>(FLAGS_threads);
options.idleTimeout = std::chrono::milliseconds(60000);
options.shutdownOn = {SIGINT, SIGTERM};
options.threads = static_cast<size_t>(parse_result.thread_count);
options.idleTimeout = std::chrono::milliseconds(60000);
options.shutdownOn = {SIGINT, SIGTERM};
options.enableContentCompression = false;
options.handlerFactories = proxygen::RequestHandlerChain()
.addThen<fiphoboserver::HandlerFactory>()
......@@ -55,7 +60,7 @@ int main(int argc, char* argv[])
options.h2cEnabled = true;
auto disk_io_thread_pool = std::make_shared<folly::CPUThreadPoolExecutor>(
FLAGS_threads,
parse_result.thread_count,
std::make_shared<folly::NamedThreadFactory>("FIFOIOThread"));
folly::setCPUExecutor(disk_io_thread_pool);
......
#include "config.h"
#include "../fiphoboserver_exception.h"
#include <fstream>
#include <unistd.h>
namespace fiphoboserver {
namespace util {
cli_options Config::parse(int argc, char* argv[])
{
define_options();
try {
m_parser.parse(argc, argv);
}
catch (const CLI::ParseError& e) {
m_parser.exit(e);
throw FIPhoboServerException(
"Returning after command line parsing. --help or invalid argument(s)");
}
return handle_arguments();
}
void Config::define_options()
{
m_parser.add_option("hostname,--hostname", m_ip, "IP/Hostname to bind to")
->required();
m_parser.add_option(
"--http", m_http_port, "port to listen on with HTTP protocol");
m_parser.add_option(
"--http2", m_http2_port, "port to listen on with HTTP2 protocol");
m_parser.add_option(
"-t,--threads", m_thread_count, "number of threads to listen on");
m_parser.set_config("--config");
m_parser.add_option(
"-w,--write-config", m_config_filename,
"write configuration options to file");
}
cli_options Config::handle_arguments()
{
if (m_thread_count <= 0) {
m_thread_count = sysconf(_SC_NPROCESSORS_ONLN);
}
if (!m_config_filename.empty()) {
std::ofstream file(m_config_filename);
file << m_parser.config_to_str();
file.close();
}
return {m_http_port, m_http2_port, m_ip, m_thread_count};
}
} // namespace util
} // namespace fiphoboserver
#include <CLI/CLI11.hpp>
#include <string>
#include <variant>
namespace fiphoboserver {
///
/// @brief namespace for utility classes
///
namespace util {
///
/// @brief struct for conveniently passing command line options to main program
///
struct cli_options {
int http_port;
int http2_port;
std::string ip;
int thread_count;
};
///
/// @brief class for handling command line arguments and configuration files
///
class Config {
public:
///
/// @brief default constructor
///
Config() :
m_parser(
"FIPhoboServer, a server for interfacing with backend long-term storage solutions.\n")
{
}
///
/// @brief default destructor
///
~Config() {}
///
/// @brief parse command line arguments
///
/// @param argc number of command line arguments
///
/// @param argv array of command line arguments
///
/// @returns struct of command line options or error code
///
cli_options parse(int argc, char* argv[]);
///
/// @brief get the HTTP port
///
/// @returns the HTTP port
///
const int http_port() const { return m_http_port; }
///
/// @brief get the HTTP2 port
///
/// @returns the HTTP2 port
///
const int http2_port() const { return m_http2_port; }
///
/// @brief get the IP/Hostname
///
/// @returns the IP/Hostname
///
const std::string ip() const { return m_ip; }
///
/// @brief get the number of threads
///
/// @returns the number of threads
///
const int threads() const { return m_thread_count; }
private:
///
/// @brief define the supported command line options
///
void define_options();
///
/// @brief perform any required adjustments to options
///
/// @returns struct of command line options or error code
///
cli_options handle_arguments();
///
/// @brief CLI11 class to handle parsing
///
CLI::App m_parser;
///
/// @brief port to listen on with HTTP protocol
///
int m_http_port = 11000;
///
/// @brief port to listen on with HTTP2 protocol
///
//
int m_http2_port = 11002;
///
/// @brief IP/Hostname to bind to
///
std::string m_ip;
///
/// @brief Number of threads to listen on
/// * default 0 uses the number of available cores
///
int m_thread_count = 0;
///
/// @brief filename to write configuration options to
///
std::string m_config_filename;
};
} // namespace util
} // namespace fiphoboserver
......@@ -15,7 +15,7 @@ class Server_test_case(unittest.TestCase):
def setUpClass(cls):
cls.bucket_name = "ichec.phobos.7a3d12c6-632b-4291-b87e-07badca60cd0"
cls.client = s3_client.S3_client('http://localhost:11000/')
cls.server = subprocess.Popen('../../build/fiphoboserver',
cls.server = subprocess.Popen('../../build/fiphoboserver localhost',
shell=True,
preexec_fn=os.setsid)
cls.put_file_name = 'data/EmperorWu.txt'
......
#define CATCH_CONFIG_MAIN // NOLINT
#include "catch2/catch.hpp"
#include <catch2/catch.hpp>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment