void Config::addPack(const std::string& name, const std::string& source, const pt::ptree& tree) { RecursiveLock wlock(config_schedule_mutex_); try { schedule_->add(std::make_shared<Pack>(name, source, tree)); if (schedule_->last()->shouldPackExecute()) { applyParsers(source + FLAGS_pack_delimiter + name, tree, true); } } catch (const std::exception& e) { LOG(WARNING) << "Error adding pack: " << name << ": " << e.what(); } }
Status Config::updateSource(const std::string& source, const std::string& json) { // Compute a 'synthesized' hash using the content before it is parsed. hashSource(source, json); // Remove all packs from this source. schedule_->removeAll(source); // Remove all files from this source. removeFiles(source); // load the config (source.second) into a pt::ptree pt::ptree tree; try { auto clone = json; stripConfigComments(clone); std::stringstream json_stream; json_stream << clone; pt::read_json(json_stream, tree); } catch (const pt::json_parser::json_parser_error& /* e */) { return Status(1, "Error parsing the config JSON"); } // extract the "schedule" key and store it as the main pack if (tree.count("schedule") > 0 && !Registry::external()) { auto& schedule = tree.get_child("schedule"); pt::ptree main_pack; main_pack.add_child("queries", schedule); addPack("main", source, main_pack); } if (tree.count("scheduledQueries") > 0 && !Registry::external()) { auto& scheduled_queries = tree.get_child("scheduledQueries"); pt::ptree queries; for (const std::pair<std::string, pt::ptree>& query : scheduled_queries) { auto query_name = query.second.get<std::string>("name", ""); if (query_name.empty()) { return Status(1, "Error getting name from legacy scheduled query"); } queries.add_child(query_name, query.second); } pt::ptree legacy_pack; legacy_pack.add_child("queries", queries); addPack("legacy_main", source, legacy_pack); } // extract the "packs" key into additional pack objects if (tree.count("packs") > 0 && !Registry::external()) { auto& packs = tree.get_child("packs"); for (const auto& pack : packs) { auto value = packs.get<std::string>(pack.first, ""); if (value.empty()) { // The pack is a JSON object, treat the content as pack data. addPack(pack.first, source, pack.second); } else { genPack(pack.first, source, value); } } } applyParsers(source, tree, false); return Status(0, "OK"); }
Status Config::updateSource(const std::string& name, const std::string& json) { // Compute a 'synthesized' hash using the content before it is parsed. hashSource(name, json); // Remove all packs from this source. schedule_->removeAll(name); // Remove all files from this source. removeFiles(name); // load the config (source.second) into a pt::ptree pt::ptree tree; try { auto clone = json; stripConfigComments(clone); std::stringstream json_stream; json_stream << clone; pt::read_json(json_stream, tree); } catch (const pt::json_parser::json_parser_error& e) { return Status(1, "Error parsing the config JSON"); } // extract the "schedule" key and store it as the main pack if (tree.count("schedule") > 0 && !Registry::external()) { auto& schedule = tree.get_child("schedule"); pt::ptree main_pack; main_pack.add_child("queries", schedule); addPack("main", name, main_pack); } if (tree.count("scheduledQueries") > 0 && !Registry::external()) { auto& scheduled_queries = tree.get_child("scheduledQueries"); pt::ptree queries; for (const std::pair<std::string, pt::ptree>& query : scheduled_queries) { auto query_name = query.second.get<std::string>("name", ""); if (query_name.empty()) { return Status(1, "Error getting name from legacy scheduled query"); } queries.add_child(query_name, query.second); } pt::ptree legacy_pack; legacy_pack.add_child("queries", queries); addPack("legacy_main", name, legacy_pack); } // extract the "packs" key into additional pack objects if (tree.count("packs") > 0 && !Registry::external()) { auto& packs = tree.get_child("packs"); for (const auto& pack : packs) { auto value = packs.get<std::string>(pack.first, ""); if (value.empty()) { // The pack is a JSON object, treat the content as pack data. addPack(pack.first, name, pack.second); } else { // If the pack value is a string (and not a JSON object) then it is a // resource to be handled by the config plugin. PluginResponse response; PluginRequest request = { {"action", "genPack"}, {"name", pack.first}, {"value", value}}; Registry::call("config", request, response); if (response.size() == 0 || response[0].count(pack.first) == 0) { continue; } try { pt::ptree pack_tree; std::stringstream pack_stream; pack_stream << response[0][pack.first]; pt::read_json(pack_stream, pack_tree); addPack(pack.first, name, pack_tree); } catch (const pt::json_parser::json_parser_error& e) { LOG(WARNING) << "Error parsing the pack JSON: " << pack.first; } } } } applyParsers(name, tree, false); return Status(0, "OK"); }