From 70a929f760e8b0704586eb3b104092ad22271621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 27 Jul 2015 22:39:56 +0200 Subject: [PATCH] add vendorsresource add plugin resource begin rules resource --- server/jsonrpc/jsontypes.cpp | 33 ++++++- server/jsonrpc/jsontypes.h | 5 +- server/jsonrpc/ruleshandler.cpp | 6 +- server/rest/deviceclassesresource.cpp | 2 - server/rest/pluginsresource.cpp | 129 ++++++++++++++++++++++---- server/rest/pluginsresource.h | 14 +-- server/rest/restserver.cpp | 36 +++++++ server/rest/restserver.h | 4 + server/rest/rulesresource.cpp | 75 ++++++++++++++- server/rest/rulesresource.h | 6 ++ server/rest/vendorsresource.cpp | 2 - 11 files changed, 268 insertions(+), 44 deletions(-) diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index cb14b111..fe8a1c20 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -600,6 +600,15 @@ QVariantMap JsonTypes::packRule(const Rule &rule) return ruleMap; } +QVariantList JsonTypes::packRules(const QList rules) +{ + QVariantList rulesList; + foreach (const Rule &rule, rules) { + rulesList.append(JsonTypes::packRule(rule)); + } + return rulesList; +} + QVariantMap JsonTypes::packRuleDescription(const Rule &rule) { QVariantMap ruleDescriptionMap; @@ -693,11 +702,7 @@ QVariantList JsonTypes::packSupportedDevices(const VendorId &vendorId) QVariantList JsonTypes::packConfiguredDevices() { - QVariantList configuredDeviceList; - foreach (Device *device, GuhCore::instance()->configuredDevices()) { - configuredDeviceList.append(packDevice(device)); - } - return configuredDeviceList; + return packRules(GuhCore::instance()->rules()); } QVariantList JsonTypes::packDeviceStates(Device *device) @@ -722,6 +727,24 @@ QVariantList JsonTypes::packDeviceDescriptors(const QList devi return deviceDescriptorList; } +QVariantList JsonTypes::packRuleDescriptions() +{ + QVariantList rulesList; + foreach (const Rule &rule, GuhCore::instance()->rules()) { + rulesList.append(JsonTypes::packRuleDescription(rule)); + } + return rulesList; +} + +QVariantList JsonTypes::packRuleDescriptions(const QList rules) +{ + QVariantList rulesList; + foreach (const Rule &rule, rules) { + rulesList.append(JsonTypes::packRuleDescription(rule)); + } + return rulesList; +} + QVariantList JsonTypes::packActionTypes(const DeviceClass &deviceClass) { QVariantList actionTypes; diff --git a/server/jsonrpc/jsontypes.h b/server/jsonrpc/jsontypes.h index 0968c1e6..59c24bdf 100644 --- a/server/jsonrpc/jsontypes.h +++ b/server/jsonrpc/jsontypes.h @@ -156,6 +156,7 @@ public: static QVariantMap packDevice(Device *device); static QVariantMap packDeviceDescriptor(const DeviceDescriptor &descriptor); static QVariantMap packRule(const Rule &rule); + static QVariantList packRules(const QList rules); static QVariantMap packRuleDescription(const Rule &rule); static QVariantMap packLogEntry(const LogEntry &logEntry); static QVariantList packCreateMethods(DeviceClass::CreateMethods createMethods); @@ -167,12 +168,12 @@ public: static QVariantList packDeviceStates(Device *device); static QVariantList packDeviceDescriptors(const QList deviceDescriptors); + static QVariantList packRuleDescriptions(); + static QVariantList packRuleDescriptions(const QList rules); static QVariantList packActionTypes(const DeviceClass &deviceClass); static QVariantList packStateTypes(const DeviceClass &deviceClass); static QVariantList packEventTypes(const DeviceClass &deviceClass); - - static QVariantList packPlugins(); diff --git a/server/jsonrpc/ruleshandler.cpp b/server/jsonrpc/ruleshandler.cpp index 39db5a01..fd096fd4 100644 --- a/server/jsonrpc/ruleshandler.cpp +++ b/server/jsonrpc/ruleshandler.cpp @@ -154,12 +154,8 @@ JsonReply* RulesHandler::GetRules(const QVariantMap ¶ms) { Q_UNUSED(params) - QVariantList rulesList; - foreach (const Rule &rule, GuhCore::instance()->rules()) { - rulesList.append(JsonTypes::packRuleDescription(rule)); - } QVariantMap returns; - returns.insert("ruleDescriptions", rulesList); + returns.insert("ruleDescriptions", JsonTypes::packRuleDescriptions()); return createReply(returns); } diff --git a/server/rest/deviceclassesresource.cpp b/server/rest/deviceclassesresource.cpp index 1e52d4c0..59d75132 100644 --- a/server/rest/deviceclassesresource.cpp +++ b/server/rest/deviceclassesresource.cpp @@ -66,8 +66,6 @@ HttpReply *DeviceClassesResource::proccessRequest(const HttpRequest &request, co break; } return reply; - - return createErrorReply(HttpReply::NotImplemented); } HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) diff --git a/server/rest/pluginsresource.cpp b/server/rest/pluginsresource.cpp index dc0c6e25..5d3c624f 100644 --- a/server/rest/pluginsresource.cpp +++ b/server/rest/pluginsresource.cpp @@ -20,6 +20,10 @@ #include "pluginsresource.h" #include "network/httprequest.h" +#include "loggingcategories.h" +#include "guhcore.h" + +#include namespace guhserver { @@ -35,43 +39,134 @@ QString PluginsResource::name() const HttpReply *PluginsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) + // get the main resource - return createErrorReply(HttpReply::NotImplemented); + // /api/v1/plugins/{pluginId}/ + if (urlTokens.count() >= 4) { + m_pluginId = PluginId(urlTokens.at(3)); + if (m_pluginId.isNull()) { + qCWarning(dcRest) << "Could not parse PluginId:" << urlTokens.at(3); + return createErrorReply(HttpReply::BadRequest); + } + } + + // check method + HttpReply *reply; + switch (request.method()) { + case HttpRequest::Get: + reply = proccessGetRequest(request, urlTokens); + break; + case HttpRequest::Put: + reply = proccessPutRequest(request, urlTokens); + break; + default: + reply = createErrorReply(HttpReply::BadRequest); + break; + } + return reply; } HttpReply *PluginsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) { Q_UNUSED(request) - Q_UNUSED(urlTokens) - return createErrorReply(HttpReply::NotImplemented); -} + // GET /api/v1/plugins + if (urlTokens.count() == 3) + return getPlugins(); -HttpReply *PluginsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) -{ - Q_UNUSED(request) - Q_UNUSED(urlTokens) + // GET /api/v1/plugins/{pluginId} + if (urlTokens.count() == 4) + return getPlugin(m_pluginId); + + // GET /api/v1/plugins/{pluginId}/configuration + if (urlTokens.count() == 5 && urlTokens.at(4) == "configuration") { + return getPluginConfiguration(m_pluginId); + } return createErrorReply(HttpReply::NotImplemented); } HttpReply *PluginsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) + // PUT /api/v1/plugins/{pluginId}/configuration + if (urlTokens.count() == 5 && urlTokens.at(4) == "configuration") { + return setPluginConfiguration(m_pluginId, request.payload()); + } return createErrorReply(HttpReply::NotImplemented); } -HttpReply *PluginsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) +HttpReply *PluginsResource::getPlugins() const { - Q_UNUSED(request) - Q_UNUSED(urlTokens) + qCDebug(dcRest) << "Get plugins"; + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packPlugins()).toJson()); + return reply; +} - return createErrorReply(HttpReply::NotImplemented); +HttpReply *PluginsResource::getPlugin(const PluginId &pluginId) const +{ + qCDebug(dcRest) << "Get plugin with id" << pluginId; + HttpReply *reply = createSuccessReply(); + foreach (DevicePlugin *plugin, GuhCore::instance()->plugins()) { + if (plugin->pluginId() == pluginId) { + reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packPlugin(plugin)).toJson()); + return reply; + } + } + return createErrorReply(HttpReply::NotFound); +} + +HttpReply *PluginsResource::getPluginConfiguration(const PluginId &pluginId) const +{ + qCDebug(dcRest) << "Get configuration of plugin with id" << pluginId.toString(); + + DevicePlugin *plugin = 0; + plugin = findPlugin(pluginId); + if (!plugin) + return createErrorReply(HttpReply::NotFound); + + QVariantList configurationParamsList; + foreach (const Param ¶m, plugin->configuration()) { + configurationParamsList.append(JsonTypes::packParam(param)); + } + + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(configurationParamsList).toJson()); + return reply; +} + +HttpReply *PluginsResource::setPluginConfiguration(const PluginId &pluginId, const QByteArray &payload) const +{ + DevicePlugin *plugin = 0; + plugin = findPlugin(pluginId); + if (!plugin) + return createErrorReply(HttpReply::NotFound); + + qCDebug(dcRest) << "Set configuration of plugin with id" << pluginId.toString(); + + QPair verification = RestResource::verifyPayload(payload); + if (!verification.first) + return createErrorReply(HttpReply::BadRequest); + + QVariantMap params = verification.second.toMap(); + ParamList pluginParams = JsonTypes::unpackParams(params.value("configuration").toList()); + DeviceManager::DeviceError result = GuhCore::instance()->setPluginConfig(pluginId, pluginParams); + + if (result != DeviceManager::DeviceErrorNoError) + return createErrorReply(HttpReply::BadRequest); + + return createSuccessReply(); +} + +DevicePlugin *PluginsResource::findPlugin(const PluginId &pluginId) const +{ + foreach (DevicePlugin *plugin, GuhCore::instance()->plugins()) { + if (plugin->pluginId() == pluginId) { + return plugin; + } + } + return 0; } } - diff --git a/server/rest/pluginsresource.h b/server/rest/pluginsresource.h index c759c6c1..2823a852 100644 --- a/server/rest/pluginsresource.h +++ b/server/rest/pluginsresource.h @@ -43,20 +43,22 @@ public: HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override; private: + PluginId m_pluginId; + // Process method HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override; - HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override; HttpReply *proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) override; - HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override; // Get methods - - // Delete methods - - // Post methods + HttpReply *getPlugins() const; + HttpReply *getPlugin(const PluginId &pluginId) const; + HttpReply *getPluginConfiguration(const PluginId &pluginId) const; + HttpReply *setPluginConfiguration(const PluginId &pluginId, const QByteArray &payload) const; // Put methods + + DevicePlugin *findPlugin(const PluginId &pluginId) const; }; } diff --git a/server/rest/restserver.cpp b/server/rest/restserver.cpp index 59f4f157..4d9363ca 100644 --- a/server/rest/restserver.cpp +++ b/server/rest/restserver.cpp @@ -47,6 +47,8 @@ void RestServer::setup() m_deviceResource = new DevicesResource(this); m_deviceClassesResource = new DeviceClassesResource(this); m_vendorsResource = new VendorsResource(this); + m_pluginsResource = new PluginsResource(this); + m_rulesResource = new RulesResource(this); } void RestServer::clientConnected(const QUuid &clientId) @@ -77,6 +79,8 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re return; } + // TODO: make generic with resource name + if (urlTokens.at(2) == "devices") { HttpReply *reply = m_deviceResource->proccessRequest(request, urlTokens); reply->setClientId(clientId); @@ -118,6 +122,38 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re reply->deleteLater(); return; } + + if (urlTokens.at(2) == "plugins") { + HttpReply *reply = m_pluginsResource->proccessRequest(request, urlTokens); + reply->setClientId(clientId); + if (reply->type() == HttpReply::TypeAsync) { + connect(reply, &HttpReply::finished, this, &RestServer::asyncReplyFinished); + reply->startWait(); + m_asyncReplies.insert(clientId, reply); + return; + } + m_webserver->sendHttpReply(reply); + reply->deleteLater(); + return; + } + + if (urlTokens.at(2) == "rules") { + HttpReply *reply = m_rulesResource->proccessRequest(request, urlTokens); + reply->setClientId(clientId); + if (reply->type() == HttpReply::TypeAsync) { + connect(reply, &HttpReply::finished, this, &RestServer::asyncReplyFinished); + reply->startWait(); + m_asyncReplies.insert(clientId, reply); + return; + } + m_webserver->sendHttpReply(reply); + reply->deleteLater(); + return; + } + + HttpReply *reply = RestResource::createErrorReply(HttpReply::BadRequest); + m_webserver->sendHttpReply(reply); + reply->deleteLater(); } void RestServer::asyncReplyFinished() diff --git a/server/rest/restserver.h b/server/rest/restserver.h index 4a3124d4..e7827a94 100644 --- a/server/rest/restserver.h +++ b/server/rest/restserver.h @@ -28,6 +28,8 @@ #include "devicesresource.h" #include "deviceclassesresource.h" #include "vendorsresource.h" +#include "pluginsresource.h" +#include "rulesresource.h" class HttpRequest; class HttpReply; @@ -49,6 +51,8 @@ private: DevicesResource *m_deviceResource; DeviceClassesResource *m_deviceClassesResource; VendorsResource *m_vendorsResource; + PluginsResource *m_pluginsResource; + RulesResource *m_rulesResource; private slots: void setup(); diff --git a/server/rest/rulesresource.cpp b/server/rest/rulesresource.cpp index ce7c3266..de5903e9 100644 --- a/server/rest/rulesresource.cpp +++ b/server/rest/rulesresource.cpp @@ -19,6 +19,11 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "rulesresource.h" +#include "network/httprequest.h" +#include "loggingcategories.h" +#include "guhcore.h" + +#include namespace guhserver { @@ -34,18 +39,48 @@ QString RulesResource::name() const HttpReply *RulesResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) + // /api/v1/rules/{ruleId}/ + if (urlTokens.count() >= 4) { + m_ruleId = RuleId(urlTokens.at(3)); + if (m_ruleId.isNull()) { + qCWarning(dcRest) << "Could not parse RuleId:" << urlTokens.at(3); + return createErrorReply(HttpReply::BadRequest); + } + } - return createErrorReply(HttpReply::NotImplemented); + // check method + HttpReply *reply; + switch (request.method()) { + case HttpRequest::Get: + reply = proccessGetRequest(request, urlTokens); + break; + case HttpRequest::Put: + reply = proccessPutRequest(request, urlTokens); + break; + case HttpRequest::Delete: + reply = proccessDeleteRequest(request, urlTokens); + break; + default: + reply = createErrorReply(HttpReply::BadRequest); + break; + } + return reply; } HttpReply *RulesResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) { Q_UNUSED(request) - Q_UNUSED(urlTokens) - return createErrorReply(HttpReply::NotImplemented);} + // GET /api/v1/rules + if (urlTokens.count() == 3) + return getRules(); + + // GET /api/v1/rules/{ruleId} + if (urlTokens.count() == 4) + return getRuleDetails(m_ruleId); + + return createErrorReply(HttpReply::NotImplemented); +} HttpReply *RulesResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) { @@ -71,5 +106,35 @@ HttpReply *RulesResource::proccessPostRequest(const HttpRequest &request, const return createErrorReply(HttpReply::NotImplemented); } +HttpReply *RulesResource::getRules() const +{ + qCDebug(dcRest) << "Get rule descriptions"; + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packRuleDescriptions()).toJson()); + return reply; +} + +Rule RulesResource::findRule(const RuleId &ruleId) const +{ + foreach (const Rule &rule, GuhCore::instance()->rules()) { + if (rule.id() == ruleId) { + return rule; + } + } + return Rule(); +} + +HttpReply *RulesResource::getRuleDetails(const RuleId &ruleId) const +{ + Rule rule = findRule(ruleId); + if (rule.id().isNull()) + return createErrorReply(HttpReply::NotFound); + + qCDebug(dcRest) << "Get rule details"; + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packRule(rule)).toJson()); + return reply; +} + } diff --git a/server/rest/rulesresource.h b/server/rest/rulesresource.h index c81a34b7..9a946c07 100644 --- a/server/rest/rulesresource.h +++ b/server/rest/rulesresource.h @@ -43,6 +43,8 @@ public: HttpReply *proccessRequest(const HttpRequest &request, const QStringList &urlTokens) override; private: + RuleId m_ruleId; + // Process method HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override; HttpReply *proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) override; @@ -50,6 +52,8 @@ private: HttpReply *proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) override; // Get methods + HttpReply *getRules() const; + HttpReply *getRuleDetails(const RuleId &ruleId) const; // Delete methods @@ -57,6 +61,8 @@ private: // Put methods + + Rule findRule(const RuleId &ruleId) const; }; } diff --git a/server/rest/vendorsresource.cpp b/server/rest/vendorsresource.cpp index 1c86eddf..d52fd45b 100644 --- a/server/rest/vendorsresource.cpp +++ b/server/rest/vendorsresource.cpp @@ -59,8 +59,6 @@ HttpReply *VendorsResource::proccessRequest(const HttpRequest &request, const QS break; } return reply; - - return createErrorReply(HttpReply::NotImplemented); } HttpReply *VendorsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)