Skip to content
Snippets Groups Projects
Commit 34fc9ace authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Add json config to net

parent a156179e
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <ftl/net/listener.hpp> #include <ftl/net/listener.hpp>
#include <ftl/net/dispatcher.hpp> #include <ftl/net/dispatcher.hpp>
#include <ftl/uuid.hpp> #include <ftl/uuid.hpp>
#include <nlohmann/json.hpp>
#include <vector> #include <vector>
#include <string> #include <string>
#include <thread> #include <thread>
...@@ -23,12 +24,12 @@ namespace net { ...@@ -23,12 +24,12 @@ namespace net {
*/ */
class Universe { class Universe {
public: public:
Universe();
/** /**
* Constructor with a URI base. The base uri is used as a base to validate * Constructor with json config object. The config allows listening and
* resource identifiers. (it may be removed). This creates a new thread * peer connection to be set up automatically.
* to monitor network sockets.
*/ */
explicit Universe(const std::string &base); explicit Universe(nlohmann::json &config);
/** /**
* The destructor will terminate the network thread before completing. * The destructor will terminate the network thread before completing.
...@@ -93,7 +94,7 @@ class Universe { ...@@ -93,7 +94,7 @@ class Universe {
private: private:
bool active_; bool active_;
std::string base_; nlohmann::json config_;
std::thread thread_; std::thread thread_;
fd_set sfderror_; fd_set sfderror_;
fd_set sfdread_; fd_set sfdread_;
......
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map>
//#include <vector>
#include <fstream>
#include <ftl/net.hpp> #include <ftl/net.hpp>
#ifndef WIN32 #ifndef WIN32
...@@ -13,27 +16,82 @@ ...@@ -13,27 +16,82 @@
using std::string; using std::string;
using ftl::net::Universe; using ftl::net::Universe;
using json = nlohmann::json;
using std::ifstream;
using std::map;
static Universe *universe; static Universe *universe;
static volatile bool stop = false; static volatile bool stop = false;
void handle_options(const char ***argv, int *argc) { // Store loaded configuration
static json config;
/**
* Find and load a JSON configuration file
*/
static bool findConfiguration(const string &file) {
ifstream i;
if (file != "") i.open(file);
if (!i.is_open()) i.open("./config.json");
if (!i.is_open()) i.open(FTL_LOCAL_CONFIG_ROOT "/config.json");
if (!i.is_open()) i.open(FTL_GLOBAL_CONFIG_ROOT "/config.json");
if (!i.is_open()) return false;
i >> config;
return true;
}
/**
* Generate a map from command line option to value
*/
map<string, string> read_options(char ***argv, int *argc) {
map<string, string> opts;
while (*argc > 0) { while (*argc > 0) {
string cmd((*argv)[0]); string cmd((*argv)[0]);
if (cmd[0] != '-') break; if (cmd[0] != '-') break;
if (cmd.find("--peer=") == 0) { size_t p;
cmd = cmd.substr(cmd.find("=")+1); if ((p = cmd.find("=")) == string::npos) {
//std::cout << "Peer added " << cmd.substr(cmd.find("=")+1) << std::endl; opts[cmd.substr(2)] = "true";
universe->connect(cmd); } else {
} else if (cmd.find("--listen=") == 0) { opts[cmd.substr(2, p-2)] = cmd.substr(p+1);
cmd = cmd.substr(cmd.find("=")+1);
universe->listen(cmd);
} }
(*argc)--; (*argc)--;
(*argv)++; (*argv)++;
} }
return opts;
}
/**
* Put command line options into json config. If config element does not exist
* or is of a different type then report an error.
*/
static void process_options(const map<string, string> &opts) {
for (auto opt : opts) {
if (opt.first == "config") continue;
if (opt.first == "version") {
std::cout << "FTL Vision Node - v" << FTL_VERSION << std::endl;
std::cout << FTL_VERSION_LONG << std::endl;
exit(0);
}
try {
auto ptr = json::json_pointer("/"+opt.first);
// TODO(nick) Allow strings without quotes
auto v = json::parse(opt.second);
if (v.type() != config.at(ptr).type()) {
LOG(ERROR) << "Incorrect type for argument " << opt.first;
continue;
}
config.at(ptr) = v;
} catch(...) {
LOG(ERROR) << "Unrecognised option: " << opt.first;
}
}
} }
void handle_command(const char *l) { void handle_command(const char *l) {
...@@ -53,14 +111,18 @@ void handle_command(const char *l) { ...@@ -53,14 +111,18 @@ void handle_command(const char *l) {
} }
} }
int main(int argc, const char **argv) { int main(int argc, char **argv) {
argc--; argc--;
argv++; argv++;
universe = new Universe("ftl://cli");
// Process Arguments // Process Arguments
handle_options(&argv, &argc); auto options = read_options(&argv, &argc);
if (!findConfiguration(options["config"])) {
LOG(FATAL) << "Could not find any configuration!";
}
process_options(options);
universe = new Universe(config);
while (!stop) { while (!stop) {
#ifndef WIN32 #ifndef WIN32
......
...@@ -11,9 +11,25 @@ using std::thread; ...@@ -11,9 +11,25 @@ using std::thread;
using ftl::net::Peer; using ftl::net::Peer;
using ftl::net::Listener; using ftl::net::Listener;
using ftl::net::Universe; using ftl::net::Universe;
using nlohmann::json;
Universe::Universe(const string &base) : Universe::Universe() : active_(true), thread_(Universe::__start, this) {}
active_(true), base_(base), thread_(Universe::__start, this) {
Universe::Universe(nlohmann::json &config) :
active_(true), config_(config), thread_(Universe::__start, this) {
if (config["listen"].is_array()) {
for (auto &l : config["listen"]) {
listen(l);
}
} else if (config["listen"].is_string()) {
listen(config["listen"]);
}
if (config["peers"].is_array()) {
for (auto &p : config["peers"]) {
connect(p);
}
}
} }
Universe::~Universe() { Universe::~Universe() {
......
...@@ -13,8 +13,8 @@ using std::chrono::milliseconds; ...@@ -13,8 +13,8 @@ using std::chrono::milliseconds;
// --- Tests ------------------------------------------------------------------- // --- Tests -------------------------------------------------------------------
TEST_CASE("Universe::connect()", "[net]") { TEST_CASE("Universe::connect()", "[net]") {
Universe a("ftl://utu.fi"); Universe a;
Universe b("ftl://utu.fi"); Universe b;
a.listen("tcp://localhost:7077"); a.listen("tcp://localhost:7077");
...@@ -73,8 +73,8 @@ TEST_CASE("Universe::connect()", "[net]") { ...@@ -73,8 +73,8 @@ TEST_CASE("Universe::connect()", "[net]") {
} }
TEST_CASE("Universe::broadcast()", "[net]") { TEST_CASE("Universe::broadcast()", "[net]") {
Universe a("ftl://utu.fi"); Universe a;
Universe b("ftl://utu.fi"); Universe b;
a.listen("tcp://localhost:7077"); a.listen("tcp://localhost:7077");
...@@ -122,7 +122,7 @@ TEST_CASE("Universe::broadcast()", "[net]") { ...@@ -122,7 +122,7 @@ TEST_CASE("Universe::broadcast()", "[net]") {
} }
SECTION("one argument to two peers") { SECTION("one argument to two peers") {
Universe c("ftl://utu.fi"); Universe c;
b.connect("tcp://localhost:7077"); b.connect("tcp://localhost:7077");
c.connect("tcp://localhost:7077"); c.connect("tcp://localhost:7077");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment