Example #1
0
Status Config::genPack(const std::string& name,
                       const std::string& source,
                       const std::string& target) {
  // 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", name}, {"value", target}};
  Registry::call("config", request, response);

  if (response.size() == 0 || response[0].count(name) == 0) {
    return Status(1, "Invalid plugin response");
  }

  try {
    pt::ptree pack_tree;
    std::stringstream pack_stream;
    pack_stream << response[0][name];
    pt::read_json(pack_stream, pack_tree);
    addPack(name, source, pack_tree);
  } catch (const pt::json_parser::json_parser_error& /* e */) {
    LOG(WARNING) << "Error parsing the pack JSON: " << name;
  }
  return Status(0);
}
Example #2
0
TEST_F(PacksTests, test_discovery_cache) {
  auto c = Config();
  c.addPack("kernel", "", getPackWithValidDiscovery());
  size_t query_count = 0;
  for (size_t i = 0; i < 5; i++) {
    c.scheduledQueries(
        ([&query_count](const std::string& name, const ScheduledQuery& query) {
          query_count++;
         }));
  }
  EXPECT_EQ(query_count, 5U);

  size_t pack_count = 0U;
  c.packs(([&pack_count](Pack& p) {
    pack_count++;
    EXPECT_EQ(p.getStats().total, 5);
    EXPECT_EQ(p.getStats().hits, 4);
    EXPECT_EQ(p.getStats().misses, 1);
  }));

  EXPECT_EQ(pack_count, 1U);
}
Example #3
0
TEST_F(PacksTests, test_discovery_cache) {
  auto c = Config();
  // This pack and discovery query are valid, expect the SQL to execute.
  c.addPack("valid_discovery_pack", "", getPackWithValidDiscovery());
  size_t query_count = 0U;
  size_t query_attemts = 5U;
  for (size_t i = 0; i < query_attemts; i++) {
    c.scheduledQueries(
        ([&query_count](const std::string& name, const ScheduledQuery& query) {
          query_count++;
         }));
  }
  EXPECT_EQ(query_count, query_attemts);

  size_t pack_count = 0U;
  c.packs(([&pack_count, query_attemts](Pack& p) {
    pack_count++;
    EXPECT_EQ(p.getStats().total, query_attemts);
    EXPECT_EQ(p.getStats().hits, query_attemts - 1);
    EXPECT_EQ(p.getStats().misses, 1U);
  }));

  EXPECT_EQ(pack_count, 1U);
}
Example #4
0
DefinitionManager::DefinitionManager(QWidget *parent) :
    QWidget(parent),
    isUpdating(false),
    dimensionManager(DimensionIdentifier::Instance()),
    blockManager(BlockIdentifier::Instance()),
    biomeManager(BiomeIdentifier::Instance()),
    entityManager(EntityIdentifier::Instance()),
    flatteningConverter(FlatteningConverter::Instance())
{
  setWindowFlags(Qt::Window);
  setWindowTitle(tr("Definitions"));

  QVBoxLayout *layout = new QVBoxLayout;
  QStringList labels;
  labels << tr("Name") << tr("Version") << tr("Type");
  table = new QTableWidget(0, 3);
  table->setHorizontalHeaderLabels(labels);
  table->horizontalHeader()->setSectionResizeMode(
      QHeaderView::ResizeToContents);
  table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  table->horizontalHeader()->setHighlightSections(false);
  table->verticalHeader()->hide();
  table->setShowGrid(false);
  table->setSelectionBehavior(QAbstractItemView::SelectRows);
  layout->addWidget(table, 1);

  QWidget *buttonBar = new QWidget;
  QHBoxLayout *buttons = new QHBoxLayout;
  QPushButton *add = new QPushButton(tr("Add Pack..."));
  connect(add, SIGNAL(clicked()),
          this, SLOT(addPack()));
  buttons->addWidget(add);
  QPushButton *remove = new QPushButton(tr("Remove Pack"));
  connect(remove, SIGNAL(clicked()),
          this, SLOT(removePack()));
  connect(this, SIGNAL(packSelected(bool)),
          remove, SLOT(setEnabled(bool)));
  buttons->addWidget(remove);
  QPushButton *save = new QPushButton(tr("Export Pack..."));
  connect(save, SIGNAL(clicked()),
          this, SLOT(exportPack()));
  connect(this, SIGNAL(packSelected(bool)),
          save, SLOT(setEnabled(bool)));
  buttons->addWidget(save);
  buttonBar->setLayout(buttons);
  layout->addWidget(buttonBar, 0);

  emit packSelected(false);
  setLayout(layout);

  QSettings settings;
  sorted = settings.value("packs").toList();

  // clean old hashed files without extra seed
  QString destdir = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
  const QStringList old_hashed_list { "1050220429", "1241760321", "1443276275", "1798448990", "2422344665" };
  for ( const auto& old_hashed_file : old_hashed_list  ) {
    QString old_path = destdir + "/" + old_hashed_file + ".json";
    QFile::remove(old_path);
    sorted.removeOne(old_path);
  }

  // copy over built-in definitions if necessary
  QDir dir;
  dir.mkpath(destdir);
  QDirIterator it(":/definitions", QDir::Files | QDir::Readable);
  while (it.hasNext()) {
    it.next();
    installJson(it.filePath(), false, false);
  }
  settings.setValue("packs", sorted);
  // we load the definitions backwards for priority.
  for (int i = sorted.length() - 1; i >= 0; i--)
    loadDefinition(sorted[i].toString());

  // hook up table selection signal
  connect(table,
          SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)),
          this, SLOT(selectedPack(QTableWidgetItem*, QTableWidgetItem*)));
  // fill out table
  refresh();
}
Example #5
0
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");
}
Example #6
0
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);

  // 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()) {
        addPack(pack.first, name, pack.second);
      } else {
        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;
        }
      }
    }
  }

  // Iterate each parser.
  for (const auto& plugin : Registry::all("config_parser")) {
    std::shared_ptr<ConfigParserPlugin> parser = nullptr;
    try {
      parser = std::dynamic_pointer_cast<ConfigParserPlugin>(plugin.second);
    } catch (const std::bad_cast& e) {
      LOG(ERROR) << "Error casting config parser plugin: " << plugin.first;
    }
    if (parser == nullptr || parser.get() == nullptr) {
      continue;
    }

    // For each key requested by the parser, add a property tree reference.
    std::map<std::string, pt::ptree> parser_config;
    for (const auto& key : parser->keys()) {
      if (tree.count(key) > 0) {
        parser_config[key] = tree.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
    parser->update(name, parser_config);
  }
  return Status(0, "OK");
}
Example #7
0
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");
}
DefinitionManager::DefinitionManager(QWidget *parent) : QWidget(parent)
{
	setWindowFlags(Qt::Window);
	setWindowTitle(tr("Definitions"));

	QVBoxLayout *layout=new QVBoxLayout;
	QStringList labels;
	labels<<tr("Name")<<tr("Version")<<tr("Type"); //<<tr("Active");
	table=new QTableWidget(0,3);
	table->setHorizontalHeaderLabels(labels);
	table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
	table->horizontalHeader()->setSectionResizeMode(0,QHeaderView::Stretch);
	table->horizontalHeader()->setHighlightSections(false);
	table->verticalHeader()->hide();
	table->setShowGrid(false);
	table->setSelectionBehavior(QAbstractItemView::SelectRows);
	layout->addWidget(table,1);

	QWidget *buttonBar=new QWidget;
	QHBoxLayout *buttons=new QHBoxLayout;
	QPushButton *add=new QPushButton(tr("Add Pack..."));
	connect(add,SIGNAL(clicked()),
			this,SLOT(addPack()));
	buttons->addWidget(add);
	QPushButton *remove=new QPushButton(tr("Remove Pack"));
	connect(remove,SIGNAL(clicked()),
			this,SLOT(removePack()));
	connect(this,SIGNAL(packSelected(bool)),
			remove,SLOT(setEnabled(bool)));
	buttons->addWidget(remove);
	QPushButton *save=new QPushButton(tr("Export Pack..."));
	connect(save,SIGNAL(clicked()),
			this,SLOT(exportPack()));
	connect(this,SIGNAL(packSelected(bool)),
			save,SLOT(setEnabled(bool)));
	buttons->addWidget(save);
	buttonBar->setLayout(buttons);
	layout->addWidget(buttonBar,0);

	emit packSelected(false);
	setLayout(layout);

	dimensionList = new Dimensions;
	blocks=new BlockIdentifier;
	biomes=new BiomeIdentifier;

	QSettings settings;
	sorted=settings.value("packs").toList();
	lastUpdated=settings.value("packupdates").toHash();

	//copy over built-in definitions if necessary
	QString defdir=QStandardPaths::writableLocation(QStandardPaths::DataLocation);
	QDir dir;
	dir.mkpath(defdir);
	QDirIterator it(":/definitions",QDir::Files|QDir::Readable);
	while (it.hasNext())
	{
		it.next();
		installJson(it.filePath(),false,false);
	}
	settings.setValue("packs",sorted);
	// we load the definitions backwards for priority.
	for (int i=sorted.length()-1;i>=0;i--)
		loadDefinition(sorted[i].toString());

	//hook up table selection signal
	connect(table,SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)),
			this, SLOT(selectedPack(QTableWidgetItem*,QTableWidgetItem*)));
	//fill out table
	refresh();
}