Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
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");
}