bool loadConfig(const QString & configFile) { // make sure the resources are loaded (they may be left out after static linking) Q_INIT_RESOURCE(resource); QJsonParseError error; //////////////////////////////////////////////////////////// // read and set the json schema from the resource //////////////////////////////////////////////////////////// QFile schemaData(":/hyperion-schema"); if (!schemaData.open(QIODevice::ReadOnly)) { std::stringstream error; error << "Schema not found: " << schemaData.errorString().toStdString(); throw std::runtime_error(error.str()); } QByteArray schema = schemaData.readAll(); QJsonDocument schemaJson = QJsonDocument::fromJson(schema, &error); if (error.error != QJsonParseError::NoError) { // report to the user the failure and their locations in the document. int errorLine(0), errorColumn(0); for( int i=0, count=qMin( error.offset,schema.size()); i<count; ++i ) { ++errorColumn; if(schema.at(i) == '\n' ) { errorColumn = 0; ++errorLine; } } std::stringstream sstream; sstream << "Schema error: " << error.errorString().toStdString() << " at Line: " << errorLine << ", Column: " << errorColumn; throw std::runtime_error(sstream.str()); } QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson.object()); //////////////////////////////////////////////////////////// // read and validate the configuration file from the command line //////////////////////////////////////////////////////////// const QJsonObject jsonConfig = QJsonFactory::readJson(configFile); if (!schemaChecker.validate(jsonConfig)) { for (std::list<std::string>::const_iterator i = schemaChecker.getMessages().begin(); i != schemaChecker.getMessages().end(); ++i) { std::cout << *i << std::endl; } std::cout << "FAILED" << std::endl; exit(1); return false; } return true; }
void CgiHandler::cmd_cfg_set() { _reply->addHeader ("Content-Type", "text/plain"); if ( _args.at(0) == "cfg_set" ) { QtHttpPostData data = _request->getPostData(); QJsonParseError error; if (data.contains("cfg")) { QJsonDocument hyperionConfig = QJsonDocument::fromJson(QByteArray::fromPercentEncoding(data["cfg"]), &error); if (error.error == QJsonParseError::NoError) { QJsonObject hyperionConfigJsonObj = hyperionConfig.object(); try { // make sure the resources are loaded (they may be left out after static linking) Q_INIT_RESOURCE(resource); QString schemaFile = ":/hyperion-schema"; QJsonObject schemaJson; try { schemaJson = QJsonFactory::readSchema(schemaFile); } catch(const std::runtime_error& error) { throw std::runtime_error(error.what()); } QJsonSchemaChecker schemaChecker; schemaChecker.setSchema(schemaJson); QPair<bool, bool> validate = schemaChecker.validate(hyperionConfigJsonObj); if (validate.first && validate.second) { QJsonFactory::writeJson(_hyperion->getConfigFileName(), hyperionConfigJsonObj); } else if (!validate.first && validate.second) { Warning(_log,"Errors have been found in the configuration file. Automatic correction is applied"); QStringList schemaErrors = schemaChecker.getMessages(); foreach (auto & schemaError, schemaErrors) Info(_log, schemaError.toUtf8().constData()); hyperionConfigJsonObj = schemaChecker.getAutoCorrectedConfig(hyperionConfigJsonObj); if (!QJsonFactory::writeJson(_hyperion->getConfigFileName(), hyperionConfigJsonObj)) throw std::runtime_error("ERROR: can not save configuration file, aborting "); } else //Error in Schema { QString errorMsg = "ERROR: Json validation failed: \n"; QStringList schemaErrors = schemaChecker.getMessages(); foreach (auto & schemaError, schemaErrors) { Error(_log, "config write validation: %s", QSTRING_CSTR(schemaError)); errorMsg += schemaError + "\n"; } throw std::runtime_error(errorMsg.toStdString()); }