json schema added for checking incoming messages

This commit is contained in:
johan 2013-08-17 19:20:19 +02:00
parent 59e13a2b5f
commit b66c397a46
7 changed files with 158 additions and 10 deletions

View File

@ -1,33 +1,42 @@
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/jsonserver)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/jsonserver)
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/jsonserver)
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/jsonserver)
# Group the headers that go through the MOC compiler
SET(JsonServer_QT_HEADERS
set(JsonServer_QT_HEADERS
${CURRENT_HEADER_DIR}/JsonServer.h
${CURRENT_SOURCE_DIR}/JsonClientConnection.h
)
SET(JsonServer_HEADERS
set(JsonServer_HEADERS
)
SET(JsonServer_SOURCES
set(JsonServer_SOURCES
${CURRENT_SOURCE_DIR}/JsonServer.cpp
${CURRENT_SOURCE_DIR}/JsonClientConnection.cpp
)
set(JsonServer_RESOURCES
${CURRENT_SOURCE_DIR}/resource.qrc
)
qt4_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
qt4_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress")
add_library(jsonserver
${JsonServer_HEADERS}
${JsonServer_QT_HEADERS}
${JsonServer_HEADERS_MOC}
${JsonServer_SOURCES}
${JsonServer_RESOURCES}
${JsonServer_HEADERS_MOC}
${JsonServer_RESOURCES_RCC}
)
target_link_libraries(jsonserver
hyperion
hyperion-utils
jsoncpp)
qt4_use_modules(jsonserver

View File

@ -1,12 +1,36 @@
// system includes
#include <stdexcept>
#include <cassert>
// stl includes
#include <iostream>
#include <sstream>
#include <iterator>
// Qt includes
#include <QResource>
// project includes
#include "JsonClientConnection.h"
JsonClientConnection::JsonClientConnection(QTcpSocket *socket) :
QObject(),
_socket(socket)
_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()));
}
@ -50,6 +74,19 @@ void JsonClientConnection::handleMessage(const std::string &message)
return;
}
if (!_schemaChecker.validate(messageRoot))
{
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());
return;
}
handleNotImplemented(messageRoot);
}

View File

@ -10,6 +10,9 @@
// jsoncpp includes
#include <json/json.h>
// util includes
#include <utils/jsonschema/JsonSchemaChecker.h>
class JsonClientConnection : public QObject
{
Q_OBJECT
@ -35,5 +38,7 @@ private:
private:
QTcpSocket * _socket;
JsonSchemaChecker _schemaChecker;
QByteArray _receiveBuffer;
};

View File

@ -18,6 +18,9 @@ JsonServer::JsonServer(Hyperion *hyperion, uint16_t port) :
// Set trigger for incoming connections
connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
// make sure the resources are loaded (they may be left out after static linking
Q_INIT_RESOURCE(resource);
}
JsonServer::~JsonServer()

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>schema.json</file>
</qresource>
</RCC>

View File

@ -0,0 +1,89 @@
{
"type":"object",
"required":true,
"properties":{
"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
},
"transform": {
"type": "object",
"required": false,
"properties": {
"threshold": {
"type": "array",
"required": false,
"items" : {
"type": "double",
"minimum": 0.0,
"maximum": 1.0
},
"minItems": 3,
"maxItems": 3
},
"gamma": {
"type": "array",
"required": false,
"items" : {
"type": "double",
"minimum": 0.0
},
"minItems": 3,
"maxItems": 3
},
"blacklevel": {
"type": "array",
"required": false,
"items" : {
"type": "double"
},
"minItems": 3,
"maxItems": 3
},
"whitelevel": {
"type": "array",
"required": false,
"items" : {
"type": "double"
},
"minItems": 3,
"maxItems": 3
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}

View File

@ -87,9 +87,9 @@ void JsonConnection::setImage(QImage image, int priority, int duration)
Json::Value command;
command["command"] = "image";
command["priority"] = priority;
command["width"] = image.width();
command["height"] = image.height();
command["data"] = std::string(base64Image.data(), base64Image.size());
command["imagewidth"] = image.width();
command["imageheight"] = image.height();
command["imagedata"] = std::string(base64Image.data(), base64Image.size());
if (duration > 0)
{
command["duration"] = duration;