Status Config::update(const std::map<std::string, std::string>& config) { // A config plugin may call update from an extension. This will update // the config instance within the extension process and the update must be // reflected in the core. if (Registry::external()) { for (const auto& source : config) { PluginRequest request = { {"action", "update"}, {"source", source.first}, {"data", source.second}, }; // A "update" registry item within core should call the core's update // method. The config plugin call action handling must also know to // update. Registry::call("config", "update", request); } } // Request a unique write lock when updating config. boost::unique_lock<boost::shared_mutex> unique_lock(getInstance().mutex_); ConfigData conf; for (const auto& source : config) { if (Registry::external()) { VLOG(1) << "Updating extension config source: " << source.first; } else { VLOG(1) << "Updating config source: " << source.first; } getInstance().raw_[source.first] = source.second; } // Now merge all sources together. for (const auto& source : getInstance().raw_) { mergeConfig(source.second, conf); } getInstance().data_ = conf; return Status(0, "OK"); }
Status Config::update(const std::map<std::string, std::string>& config) { // A config plugin may call update from an extension. This will update // the config instance within the extension process and the update must be // reflected in the core. if (Registry::external()) { for (const auto& source : config) { PluginRequest request = { {"action", "update"}, {"source", source.first}, {"data", source.second}, }; // A "update" registry item within core should call the core's update // method. The config plugin call action handling must also know to // update. Registry::call("config", "update", request); } } // Request a unique write lock when updating config. { boost::unique_lock<boost::shared_mutex> unique_lock(getInstance().mutex_); for (const auto& source : config) { if (Registry::external()) { VLOG(1) << "Updating extension config with source: " << source.first; } else { VLOG(1) << "Updating config with source: " << source.first; } getInstance().raw_[source.first] = source.second; } // Now merge all sources together. ConfigData conf; for (const auto& source : getInstance().raw_) { auto status = mergeConfig(source.second, conf); if (getInstance().force_merge_success_ && !status.ok()) { return Status(1, status.what()); } } // Call each parser with the optionally-empty, requested, top level keys. getInstance().data_ = std::move(conf); } for (const auto& plugin : Registry::all("config_parser")) { auto parser = std::static_pointer_cast<ConfigParserPlugin>(plugin.second); if (parser == nullptr || parser.get() == nullptr) { continue; } // For each key requested by the parser, add a property tree reference. std::map<std::string, ConfigTree> parser_config; for (const auto& key : parser->keys()) { if (getInstance().data_.all_data.count(key) > 0) { parser_config[key] = getInstance().data_.all_data.get_child(key); } else { parser_config[key] = pt::ptree(); } } // The config parser plugin will receive a copy of each property tree for // each top-level-config key. The parser may choose to update the config's // internal state by requesting and modifying a ConfigDataInstance. parser->update(parser_config); } return Status(0, "OK"); }