mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Schema checking for all commands added
This commit is contained in:
parent
b66c397a46
commit
46076998a0
@ -16,20 +16,8 @@
|
||||
JsonClientConnection::JsonClientConnection(QTcpSocket *socket) :
|
||||
QObject(),
|
||||
_socket(socket),
|
||||
_schemaChecker(),
|
||||
_receiveBuffer()
|
||||
{
|
||||
// read the json schema from the resource
|
||||
QResource schemaData(":/schema.json");
|
||||
assert(schemaData.isValid());
|
||||
Json::Reader jsonReader;
|
||||
Json::Value schemaJson;
|
||||
if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false))
|
||||
{
|
||||
throw std::runtime_error("Schema error: " + jsonReader.getFormattedErrorMessages()) ;
|
||||
}
|
||||
_schemaChecker.setSchema(schemaJson);
|
||||
|
||||
// connect internal signals and slots
|
||||
connect(_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
|
||||
connect(_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
@ -64,33 +52,80 @@ void JsonClientConnection::socketClosed()
|
||||
emit connectionClosed(this);
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleMessage(const std::string &message)
|
||||
void JsonClientConnection::handleMessage(const std::string &messageString)
|
||||
{
|
||||
Json::Reader reader;
|
||||
Json::Value messageRoot;
|
||||
if (!reader.parse(message, messageRoot, false))
|
||||
Json::Value message;
|
||||
if (!reader.parse(messageString, message, false))
|
||||
{
|
||||
sendErrorReply("Error while parsing json: " + reader.getFormattedErrorMessages());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_schemaChecker.validate(messageRoot))
|
||||
// check basic message
|
||||
std::string errors;
|
||||
if (!checkJson(message, ":schema", errors))
|
||||
{
|
||||
const std::list<std::string> & errors = _schemaChecker.getMessages();
|
||||
std::stringstream ss;
|
||||
ss << "Error while validating json: {";
|
||||
foreach (const std::string & error, errors) {
|
||||
ss << error << ", ";
|
||||
}
|
||||
ss << "}";
|
||||
sendErrorReply(ss.str());
|
||||
sendErrorReply("Error while validating json: " + errors);
|
||||
return;
|
||||
}
|
||||
|
||||
handleNotImplemented(messageRoot);
|
||||
// check specific message
|
||||
const std::string command = message["command"].asString();
|
||||
if (!checkJson(message, QString("schema-%1").arg(QString::fromStdString(command)), errors))
|
||||
{
|
||||
sendErrorReply("Error while validating json: " + errors);
|
||||
return;
|
||||
}
|
||||
|
||||
// switch over all possible commands and handle them
|
||||
if (command == "color")
|
||||
handleColorCommand(message);
|
||||
else if (command == "image")
|
||||
handleImageCommand(message);
|
||||
else if (command == "serverinfo")
|
||||
handleServerInfoCommand(message);
|
||||
else if (command == "clear")
|
||||
handleClearCommand(message);
|
||||
else if (command == "clearall")
|
||||
handleClearallCommand(message);
|
||||
else if (command == "transform")
|
||||
handleTransformCommand(message);
|
||||
else
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleNotImplemented(const Json::Value & message)
|
||||
void JsonClientConnection::handleColorCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleImageCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleServerInfoCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleClearCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleClearallCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleTransformCommand(const Json::Value &message)
|
||||
{
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
void JsonClientConnection::handleNotImplemented()
|
||||
{
|
||||
sendErrorReply("Command not implemented");
|
||||
}
|
||||
@ -112,3 +147,36 @@ void JsonClientConnection::sendErrorReply(const std::string &error)
|
||||
// send reply
|
||||
sendMessage(reply);
|
||||
}
|
||||
|
||||
bool JsonClientConnection::checkJson(const Json::Value & message, const QString & schemaResource, std::string & errorMessage)
|
||||
{
|
||||
// read the json schema from the resource
|
||||
QResource schemaData(schemaResource);
|
||||
assert(schemaData.isValid());
|
||||
Json::Reader jsonReader;
|
||||
Json::Value schemaJson;
|
||||
if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false))
|
||||
{
|
||||
throw std::runtime_error("Schema error: " + jsonReader.getFormattedErrorMessages()) ;
|
||||
}
|
||||
|
||||
// create schema checker
|
||||
JsonSchemaChecker schema;
|
||||
schema.setSchema(schemaJson);
|
||||
|
||||
// check the message
|
||||
if (!schema.validate(message))
|
||||
{
|
||||
const std::list<std::string> & errors = schema.getMessages();
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
foreach (const std::string & error, errors) {
|
||||
ss << error << " ";
|
||||
}
|
||||
ss << "}";
|
||||
errorMessage = ss.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -30,15 +30,22 @@ private slots:
|
||||
|
||||
private:
|
||||
void handleMessage(const std::string & message);
|
||||
void handleNotImplemented(const Json::Value & message);
|
||||
void handleColorCommand(const Json::Value & message);
|
||||
void handleImageCommand(const Json::Value & message);
|
||||
void handleServerInfoCommand(const Json::Value & message);
|
||||
void handleClearCommand(const Json::Value & message);
|
||||
void handleClearallCommand(const Json::Value & message);
|
||||
void handleTransformCommand(const Json::Value & message);
|
||||
void handleNotImplemented();
|
||||
|
||||
void sendMessage(const Json::Value & message);
|
||||
void sendErrorReply(const std::string & error);
|
||||
|
||||
private:
|
||||
QTcpSocket * _socket;
|
||||
bool checkJson(const Json::Value & message, const QString &schemaResource, std::string & errors);
|
||||
|
||||
JsonSchemaChecker _schemaChecker;
|
||||
private:
|
||||
QTcpSocket * _socket;
|
||||
|
||||
QByteArray _receiveBuffer;
|
||||
};
|
||||
|
@ -37,11 +37,11 @@ uint16_t JsonServer::getPort() const
|
||||
|
||||
void JsonServer::newConnection()
|
||||
{
|
||||
std::cout << "New incoming json connection" << std::endl;
|
||||
QTcpSocket * socket = _server.nextPendingConnection();
|
||||
|
||||
if (socket != nullptr)
|
||||
{
|
||||
std::cout << "New json connection" << std::endl;
|
||||
JsonClientConnection * connection = new JsonClientConnection(socket);
|
||||
_openConnections.insert(connection);
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>schema.json</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file alias="schema">schema/schema.json</file>
|
||||
<file alias="schema-color">schema/schema-color.json</file>
|
||||
<file alias="schema-image">schema/schema-image.json</file>
|
||||
<file alias="schema-serverinfo">schema/schema-serverinfo.json</file>
|
||||
<file alias="schema-clear">schema/schema-clear.json</file>
|
||||
<file alias="schema-clearall">schema/schema-clearall.json</file>
|
||||
<file alias="schema-transform">schema/schema-transform.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
16
libsrc/jsonserver/schema/schema-clear.json
Normal file
16
libsrc/jsonserver/schema/schema-clear.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["clear"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
12
libsrc/jsonserver/schema/schema-clearall.json
Normal file
12
libsrc/jsonserver/schema/schema-clearall.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["clearall"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
29
libsrc/jsonserver/schema/schema-color.json
Normal file
29
libsrc/jsonserver/schema/schema-color.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["color"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": true
|
||||
},
|
||||
"duration": {
|
||||
"type": "integer",
|
||||
"required": false
|
||||
},
|
||||
"color": {
|
||||
"type": "array",
|
||||
"required": true,
|
||||
"items" :{
|
||||
"type" : "integer"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
34
libsrc/jsonserver/schema/schema-image.json
Normal file
34
libsrc/jsonserver/schema/schema-image.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["image"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": true
|
||||
},
|
||||
"duration": {
|
||||
"type": "integer",
|
||||
"required": false
|
||||
},
|
||||
"imagewidth": {
|
||||
"type" : "integer",
|
||||
"required": true,
|
||||
"minimum": 0
|
||||
},
|
||||
"imageheight": {
|
||||
"type" : "integer",
|
||||
"required": true,
|
||||
"minimum": 0
|
||||
},
|
||||
"imagedata": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
12
libsrc/jsonserver/schema/schema-serverinfo.json
Normal file
12
libsrc/jsonserver/schema/schema-serverinfo.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["serverinfo"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
@ -5,42 +5,11 @@
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["color", "image", "serverinfo", "clear", "clearall", "transform"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": false
|
||||
},
|
||||
"duration": {
|
||||
"type": "integer",
|
||||
"required": false
|
||||
},
|
||||
"color": {
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"items" :{
|
||||
"type" : "integer"
|
||||
},
|
||||
"minItems": 3,
|
||||
"maxItems": 3
|
||||
},
|
||||
"imagewidth": {
|
||||
"type" : "integer",
|
||||
"required": false,
|
||||
"minimum": 0
|
||||
},
|
||||
"imageheight": {
|
||||
"type" : "integer",
|
||||
"required": false,
|
||||
"minimum": 0
|
||||
},
|
||||
"imagedata": {
|
||||
"type": "string",
|
||||
"required": false
|
||||
"enum" : ["transform"]
|
||||
},
|
||||
"transform": {
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"properties": {
|
||||
"threshold": {
|
||||
"type": "array",
|
11
libsrc/jsonserver/schema/schema.json
Normal file
11
libsrc/jsonserver/schema/schema.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"command": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["color", "image", "serverinfo", "clear", "clearall", "transform"]
|
||||
}
|
||||
}
|
||||
}
|
@ -275,7 +275,7 @@ bool JsonConnection::parseReply(const Json::Value &reply)
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw std::runtime_error("Error while executing command: " + reason);
|
||||
throw std::runtime_error("Error: " + reason);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
Loading…
Reference in New Issue
Block a user