diff --git a/src/ClientManager.cpp b/src/ClientManager.cpp index 12669b7..4792222 100644 --- a/src/ClientManager.cpp +++ b/src/ClientManager.cpp @@ -208,8 +208,7 @@ ClientManager::addClientFromJSON(const json& description) { ] } }, - "config": {"type": "object"}, - "__if__": {"type": "string", "minLength":1} + "config": {"type": "object"} }, "required": ["name", "type"] } @@ -217,12 +216,6 @@ ClientManager::addClientFromJSON(const json& description) { static const JsonValidator validator{configSchema}; validator.validate(description, "ClientManager"); - if(description.contains("__if__")) { - bool b = Jx9Manager(self->m_jx9_manager).evaluateCondition( - description["__if__"].get_ref(), {}); - if(!b) return nullptr; - } - auto& name = description["name"].get_ref(); auto& type = description["type"].get_ref(); diff --git a/src/JsonUtil.hpp b/src/JsonUtil.hpp index 20ca4c2..f952454 100644 --- a/src/JsonUtil.hpp +++ b/src/JsonUtil.hpp @@ -6,10 +6,11 @@ #ifndef BEDROCK_JSON_UTIL_H #define BEDROCK_JSON_UTIL_H +#include +#include #include #include #include -#include namespace bedrock { @@ -84,6 +85,39 @@ static inline json expandSimplifiedJSON(const json& input) { return output; } +static inline json filterIfConditionsInJSON(const json& input, Jx9Manager jx9) { + json output; // null by default + if(input.is_array()) { + output = json::array(); + for(auto& item : input) { + auto filteredItem = filterIfConditionsInJSON(item, jx9); + if(filteredItem.is_null()) continue; + output.push_back(filterIfConditionsInJSON(item, jx9)); + } + } else if(input.is_object()) { + bool condition = true; + if(input.contains("__if__")) { + auto _if = input["__if__"]; + if(_if.is_boolean()) condition = _if.get(); + else if(_if.is_string()) + condition = jx9.evaluateCondition( + _if.get_ref(), + std::unordered_map()); + else + throw Exception("__if__ condition should be a string or a boolean"); + } + if(condition) { + output = json::object(); + for(auto& p : input.items()) { + output[p.key()] = filterIfConditionsInJSON(p.value(), jx9); + } + } + } else { + output = input; + } + return output; +} + } #endif diff --git a/src/Jx9Manager.cpp b/src/Jx9Manager.cpp index f8aa9cc..773ef0d 100644 --- a/src/Jx9Manager.cpp +++ b/src/Jx9Manager.cpp @@ -18,7 +18,8 @@ using nlohmann::json; // LCOV_EXCL_START -Jx9Manager::Jx9Manager() : self(std::make_shared()) {} +Jx9Manager::Jx9Manager() +: self(std::make_shared()) {} Jx9Manager::Jx9Manager(const Jx9Manager&) = default; @@ -71,15 +72,10 @@ std::string Jx9Manager::executeQuery( // installing MPI_COMM_WORLD json comm_world = nullptr; #ifdef ENABLE_MPI - int mpi_rank, mpi_size; - int mpi_initialized; - MPI_Initialized(&mpi_initialized); - if(mpi_initialized) { - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + if(self->m_mpi->enabled()) { comm_world = json::object(); - comm_world["rank"] = mpi_rank; - comm_world["size"] = mpi_size; + comm_world["rank"] = self->m_mpi->rank(); + comm_world["size"] = self->m_mpi->size(); } #endif jx9_value* jx9_comm_world = nullptr; diff --git a/src/Jx9ManagerImpl.hpp b/src/Jx9ManagerImpl.hpp index 5af2ace..709155e 100644 --- a/src/Jx9ManagerImpl.hpp +++ b/src/Jx9ManagerImpl.hpp @@ -13,6 +13,7 @@ #include #include #include +#include "MPI.hpp" namespace bedrock { @@ -24,8 +25,10 @@ class Jx9ManagerImpl { jx9* m_engine = nullptr; tl::mutex m_mtx; std::unordered_map m_global_variables; + std::shared_ptr m_mpi; - Jx9ManagerImpl() { + Jx9ManagerImpl() + : m_mpi(std::make_shared()) { spdlog::trace("Initializing Jx9 engine"); jx9_init(&m_engine); } diff --git a/src/MPI.hpp b/src/MPI.hpp index 6095522..68b9fb0 100644 --- a/src/MPI.hpp +++ b/src/MPI.hpp @@ -10,6 +10,7 @@ #ifdef ENABLE_MPI #include #endif +#include namespace bedrock { @@ -44,6 +45,34 @@ class MPI { } s_initialized_mpi = false; } +#endif + } + + bool enabled() const { +#ifdef ENABLE_MPI + return true; +#else + return false; +#endif + } + + int size() const { +#ifdef ENABLE_MPI + int s; + MPI_Comm_size(MPI_COMM_WORLD, &s); + return s; +#else + throw Exception("Cannot get size of MPI_COMM_WORLD in a non-MPI deployment"); +#endif + } + + int rank() const { +#ifdef ENABLE_MPI + int r; + MPI_Comm_rank(MPI_COMM_WORLD, &r); + return r; +#else + throw Exception("Cannot get rank of process in a non-MPI deployment"); #endif } }; diff --git a/src/ProviderManager.cpp b/src/ProviderManager.cpp index c54b3a0..175b9ae 100644 --- a/src/ProviderManager.cpp +++ b/src/ProviderManager.cpp @@ -187,8 +187,7 @@ ProviderManager::addProviderFromJSON(const json& description) { ] } }, - "config": {"type": "object"}, - "__if__": {"type": "string", "minLength":1} + "config": {"type": "object"} }, "required": ["name", "type"] } @@ -196,12 +195,6 @@ ProviderManager::addProviderFromJSON(const json& description) { static const JsonValidator validator{configSchema}; validator.validate(description, "ProviderManager"); - if(description.contains("__if__")) { - bool b = Jx9Manager(self->m_jx9_manager).evaluateCondition( - description["__if__"].get_ref(), {}); - if(!b) return nullptr; - } - auto& name = description["name"].get_ref(); auto& type = description["type"].get_ref(); auto provider_id = description.value("provider_id", std::numeric_limits::max()); diff --git a/src/Server.cpp b/src/Server.cpp index 38f9561..02b9e4f 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -73,6 +73,17 @@ Server::Server(const std::string& address, const std::string& configString, config = Toml2Json(tomlConfig); } + // Filter __if__ statements in configuration + config = filterIfConditionsInJSON(config, jx9Manager); + + // If the config is an array, it should have only one entry remaining after filtering + if(config.is_array()) { + if(config.size() != 1) { + throw Exception{"Configuration did not resolve to a single possibility"}; + } + config = config[0]; + } + // Extract margo section from the config spdlog::trace("Initializing MargoManager"); auto margoConfig = config["margo"].dump();