JSON Auto correction + hyperion schema split for better readability (#452)

* revoke schema split

* add "getAutoCorrectedConfig" function

* revoke schema split

* revoke schema split

* revoke schema split

* Prevent compiler error if none grabber is available

* revoke schema split

* add "getAutoCorrectedConfig" function

* revoke schema split

* remove "configMigrator"

* remove "configMigrator"

* Change TestConfigFile to show how the autocorrection works

* revoke schema split

* revoke schema split

* remove "ConfigMigrator"

* remove "ConfigMigrator"

* remove "ConfigMigratorBase"

* remove "ConfigMigratorBase"

* Add QJsonUtils.h

* added ability "ignore-required"

It has been added the ability to correct the configuration without having to pay attention to the keyword "required" in the hyperion schema

* Allow Comments in Hyperion Schema

* add ability to ignore the "required" keyword in hyperion schema

* add ability to ignore the "required" keyword in hyperion schema

* add ability to ignore the "required" keyword in hyperion schema

* //Allow Comments in Hyperion Schema

* Update jsonschema.py to version 0.8.0 to support ...

references in json schema

* add RefResolver from jsonschema.py to resolve

references in hyperion schema

* remove dupe code

* split the hyperion schema in separatly files

For better readability

* add function "resolveReferences" to resolve

references in hyperion schema.

* remove CURRENT_CONFIG_VERSION

* remove CURRENT_CONFIG_VERSION

* split the hyperion schema in separatly files

For better readability

* Create schema-backgroundEffect.json

* Add the rest of the Hyperion schema via upload

* Remove Comments in config file

* Add return variable to function writeJson().

fix function resolveReferences().
edit function load() to handle QPair result from schemaChecker.

* edit function validate() to return QPair variable

* fit function loadEffectDefinition()

* fit function checkJson()

*  Expand error check by dividing

"_error" variable in "_error" and "_schemaError".
Replace variable "bool" in validate() in QPair

* Extend function "cmd_cfg_set" to handle auto correction

* Extend function "loadConfig" to handle auto correction

* fix function loadConfig()
This commit is contained in:
Paulchen Panther
2017-07-30 13:32:10 +02:00
committed by brindosch
parent 622a171808
commit 5bd020a570
45 changed files with 2356 additions and 2254 deletions

View File

@@ -8,10 +8,6 @@ QT5_WRAP_CPP(Hyperiond_HEADERS_MOC ${Hyperiond_QT_HEADERS})
add_executable(hyperiond
${Hyperiond_QT_HEADERS}
${Hyperiond_HEADERS_MOC}
configMigratorBase.cpp
configMigratorBase.h
configMigrator.cpp
configMigrator.h
hyperiond.cpp
main.cpp
)

View File

@@ -1,34 +0,0 @@
#include "configMigrator.h"
ConfigMigrator::ConfigMigrator()
{
}
ConfigMigrator::~ConfigMigrator()
{
}
bool ConfigMigrator::migrate(QString configFile, int fromVersion,int toVersion)
{
Debug(_log, "migrate config %s from version %d to %d.", configFile.toLocal8Bit().constData(), fromVersion, toVersion);
for (int v=fromVersion; v<toVersion; v++)
{
switch(v)
{
case 1: migrateFrom1(); break;
default:
throw std::runtime_error("ERROR: config migration - unknown version");
}
}
return true;
}
void ConfigMigrator::migrateFrom1()
{
throw std::runtime_error("ERROR: config migration not implemented");
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include "configMigratorBase.h"
#include <QString>
///
/// class that contains migration code
/// helper code goeas to base class
class ConfigMigrator : public ConfigMigratorBase
{
public:
ConfigMigrator();
~ConfigMigrator();
bool migrate(QString configFile, int fromVersion,int toVersion);
private:
void migrateFrom1();
};

View File

@@ -1,11 +0,0 @@
#include "configMigratorBase.h"
ConfigMigratorBase::ConfigMigratorBase()
: _log(Logger::getInstance("ConfigMigrator"))
{
}
ConfigMigratorBase::~ConfigMigratorBase()
{
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <utils/Logger.h>
#include <QString>
class ConfigMigratorBase
{
public:
ConfigMigratorBase();
~ConfigMigratorBase();
protected:
Logger * _log;
};

View File

@@ -12,6 +12,7 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QPair>
#include <cstdint>
#include <limits>
@@ -31,7 +32,6 @@
#include <udplistener/UDPListener.h>
#include "hyperiond.h"
#include "configMigrator.h"
HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
: QObject(parent)
@@ -52,7 +52,7 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
, _hyperion(nullptr)
, _stats(nullptr)
{
loadConfig(configFile, CURRENT_CONFIG_VERSION );
loadConfig(configFile);
if (Logger::getLogLevel() == Logger::WARNING)
{
@@ -135,16 +135,16 @@ void HyperionDaemon::run()
connect(_hyperion,SIGNAL(closing()),this,SLOT(freeObjects()));
}
int HyperionDaemon::tryLoadConfig(const QString & configFile, const int schemaVersion)
void HyperionDaemon::loadConfig(const QString & configFile)
{
Info(_log, "Selected configuration file: %s", configFile.toUtf8().constData());
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE(resource);
// read the json schema from the resource
QString schemaFile = ":/hyperion-schema";
if (schemaVersion > 0)
schemaFile += "-" + QString::number(schemaVersion);
QJsonObject schemaJson;
try
{
@@ -159,45 +159,25 @@ int HyperionDaemon::tryLoadConfig(const QString & configFile, const int schemaVe
schemaChecker.setSchema(schemaJson);
_qconfig = QJsonFactory::readConfig(configFile);
if (!schemaChecker.validate(_qconfig))
QPair<bool, bool> validate = schemaChecker.validate(_qconfig);
if (!validate.first && validate.second)
{
Warning(_log,"Errors have been found in the configuration file. Automatic correction is applied");
_qconfig = schemaChecker.getAutoCorrectedConfig(_qconfig);
if (!QJsonFactory::writeJson(configFile, _qconfig))
throw std::runtime_error("ERROR: can not save configuration file, aborting ");
}
else if (validate.first && !validate.second) //Error in Schema
{
QStringList schemaErrors = schemaChecker.getMessages();
foreach (auto & schemaError, schemaErrors)
{
std::cout << schemaError.toStdString() << std::endl;
}
throw std::runtime_error("ERROR: Json validation failed");
}
const QJsonObject & generalConfig = _qconfig["general"].toObject();
return generalConfig["configVersion"].toInt(-1);
}
void HyperionDaemon::loadConfig(const QString & configFile, const int neededConfigVersion)
{
Info(_log, "Selected configuration file: %s", configFile.toUtf8().constData());
int configVersionId = tryLoadConfig(configFile,0);
// no config id found, assume legacy hyperion
if (configVersionId < 0)
{
Debug(_log, "config file has no version, assume old hyperion.");
configVersionId = tryLoadConfig(configFile,1);
}
Debug(_log, "config version: %d", configVersionId);
configVersionId = tryLoadConfig(configFile, configVersionId);
if (neededConfigVersion == configVersionId)
{
return;
}
// migrate configVersionId
ConfigMigrator migrator;
migrator.migrate(configFile, configVersionId, neededConfigVersion);
}

View File

@@ -54,9 +54,8 @@ class HyperionDaemon : public QObject
public:
HyperionDaemon(QString configFile, QObject *parent=nullptr);
~HyperionDaemon();
int tryLoadConfig(const QString & configFile, const int schemaVersion);
void loadConfig(const QString & configFile, const int neededConfigVersion);
void loadConfig(const QString & configFile);
void run();
void startInitialEffect();