From 36fbf27762b1391d07dbbcc896c659ece76c73d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sat, 1 Aug 2015 14:21:34 +0200 Subject: [PATCH] add rest logging --- server/rest/devicesresource.cpp | 99 ++++++++++++++++++++++++++++++++- server/rest/devicesresource.h | 5 +- server/rest/logsresource.cpp | 65 ++++++++++++++-------- server/rest/logsresource.h | 9 +-- server/rest/restserver.cpp | 4 +- server/rest/restserver.h | 2 + 6 files changed, 147 insertions(+), 37 deletions(-) diff --git a/server/rest/devicesresource.cpp b/server/rest/devicesresource.cpp index dc69d5f3..56bede0b 100644 --- a/server/rest/devicesresource.cpp +++ b/server/rest/devicesresource.cpp @@ -34,6 +34,7 @@ DevicesResource::DevicesResource(QObject *parent) : connect(GuhCore::instance(), &GuhCore::actionExecuted, this, &DevicesResource::actionExecuted); connect(GuhCore::instance(), &GuhCore::deviceSetupFinished, this, &DevicesResource::deviceSetupFinished); connect(GuhCore::instance(), &GuhCore::deviceEditFinished, this, &DevicesResource::deviceEditFinished); + connect(GuhCore::instance(), &GuhCore::pairingFinished, this, &DevicesResource::pairingFinished); } QString DevicesResource::name() const @@ -128,17 +129,18 @@ HttpReply *DevicesResource::proccessDeleteRequest(const HttpRequest &request, co return removeDevice(m_device); // TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy} + return createErrorReply(HttpReply::NotImplemented); } HttpReply *DevicesResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) { Q_UNUSED(request) - // POST /api/v1/devices + // PUT /api/v1/devices if (urlTokens.count() == 3) return createErrorReply(HttpReply::BadRequest); - // POST /api/v1/devices/{deviceId} + // PUT /api/v1/devices/{deviceId} if (urlTokens.count() == 4) return editDevice(m_device, request.payload()); @@ -152,6 +154,14 @@ HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, cons if (urlTokens.count() == 3) return addConfiguredDevice(request.payload()); + // POST /api/v1/devices/pair + if (urlTokens.count() == 4 && urlTokens.at(3) == "pair") + return pairDevice(request.payload()); + + // POST /api/v1/devices/confirmpairing + if (urlTokens.count() == 4 && urlTokens.at(3) == "confirmpairing") + return confirmPairDevice(request.payload()); + // POST /api/v1/devices/{deviceId} if (urlTokens.count() == 4) return createErrorReply(HttpReply::BadRequest); @@ -301,6 +311,71 @@ HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const return reply; } +HttpReply *DevicesResource::pairDevice(const QByteArray &payload) const +{ + QPair verification = RestResource::verifyPayload(payload); + if (!verification.first) + return createErrorReply(HttpReply::BadRequest); + + QVariantMap params = verification.second.toMap(); + + DeviceClassId deviceClassId(params.value("deviceClassId").toString()); + DeviceClass deviceClass = GuhCore::instance()->findDeviceClass(deviceClassId); + + if (deviceClassId.isNull()) { + qCWarning(dcRest) << "Could not find deviceClassId" << params.value("deviceClassId").toString(); + return createErrorReply(HttpReply::BadRequest); + } + + qCDebug(dcRest) << "Pair device with deviceClassId" << deviceClassId.toString(); + + DeviceManager::DeviceError status; + PairingTransactionId pairingTransactionId = PairingTransactionId::createPairingTransactionId(); + if (params.contains("deviceDescriptorId")) { + DeviceDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString()); + status = GuhCore::instance()->pairDevice(pairingTransactionId, deviceClassId, deviceDescriptorId); + } else { + ParamList deviceParams = JsonTypes::unpackParams(params.value("deviceParams").toList()); + status = GuhCore::instance()->pairDevice(pairingTransactionId, deviceClassId, deviceParams); + } + + if (status != DeviceManager::DeviceErrorNoError) + return createErrorReply(HttpReply::BadRequest); + + QVariantMap returns; + returns.insert("displayMessage", deviceClass.pairingInfo()); + returns.insert("pairingTransactionId", pairingTransactionId.toString()); + returns.insert("setupMethod", JsonTypes::setupMethod().at(deviceClass.setupMethod())); + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(returns).toJson()); + return reply; +} + +HttpReply *DevicesResource::confirmPairDevice(const QByteArray &payload) const +{ + QPair verification = RestResource::verifyPayload(payload); + if (!verification.first) + return createErrorReply(HttpReply::BadRequest); + + QVariantMap params = verification.second.toMap(); + + PairingTransactionId pairingTransactionId = PairingTransactionId(params.value("pairingTransactionId").toString()); + QString secret = params.value("secret").toString(); + DeviceManager::DeviceError status = GuhCore::instance()->confirmPairing(pairingTransactionId, secret); + + if (status == DeviceManager::DeviceErrorAsync) { + HttpReply *reply = createAsyncReply(); + qCDebug(dcRest) << "Confirm pairing async reply"; + m_asyncPairingRequests.insert(pairingTransactionId, reply); + return reply; + } + + if (status != DeviceManager::DeviceErrorNoError) + return createErrorReply(HttpReply::InternalServerError); + + return createSuccessReply(); +} + HttpReply *DevicesResource::editDevice(Device *device, const QByteArray &payload) const { qCDebug(dcRest) << "Edit device" << device->id(); @@ -388,4 +463,24 @@ void DevicesResource::deviceEditFinished(Device *device, DeviceManager::DeviceEr reply->finished(); } +void DevicesResource::pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId) +{ + if (!m_asyncPairingRequests.contains(pairingTransactionId)) + return; // Not the device pairing we are waiting for. + + HttpReply *reply = m_asyncPairingRequests.take(pairingTransactionId); + if (status == DeviceManager::DeviceErrorNoError) { + qCDebug(dcRest) << "Pairing device finished successfully"; + QVariantMap response; + response.insert("deviceId", deviceId.toString()); + reply->setPayload(QJsonDocument::fromVariant(response).toJson()); + reply->setHttpStatusCode(HttpReply::Ok); + } else { + qCDebug(dcRest) << "Pairing device finished with error" << status; + reply->setHttpStatusCode(HttpReply::InternalServerError); + } + + reply->finished(); +} + } diff --git a/server/rest/devicesresource.h b/server/rest/devicesresource.h index 31193f13..3fd29d68 100644 --- a/server/rest/devicesresource.h +++ b/server/rest/devicesresource.h @@ -46,7 +46,7 @@ private: mutable QHash m_asyncActionExecutions; mutable QHash m_asyncDeviceAdditions; mutable QHash m_asyncEditDevice; - mutable QHash m_asyncPairingRequests; + mutable QHash m_asyncPairingRequests; Device *m_device; @@ -68,6 +68,8 @@ private: // Post methods HttpReply *executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const; HttpReply *addConfiguredDevice(const QByteArray &payload) const; + HttpReply *pairDevice(const QByteArray &payload) const; + HttpReply *confirmPairDevice(const QByteArray &payload) const; // Put methods HttpReply *editDevice(Device *device, const QByteArray &payload) const; @@ -76,6 +78,7 @@ private slots: void actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status); void deviceSetupFinished(Device *device, DeviceManager::DeviceError status); void deviceEditFinished(Device *device, DeviceManager::DeviceError status); + void pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId); }; diff --git a/server/rest/logsresource.cpp b/server/rest/logsresource.cpp index 5a2a7398..37b7d82f 100644 --- a/server/rest/logsresource.cpp +++ b/server/rest/logsresource.cpp @@ -20,6 +20,11 @@ #include "logsresource.h" #include "httprequest.h" +#include "loggingcategories.h" +#include "guhcore.h" +#include "logging/logengine.h" + +#include namespace guhserver { @@ -35,41 +40,53 @@ QString LogsResource::name() const HttpReply *LogsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) - - return createErrorReply(HttpReply::NotImplemented); + // check method + HttpReply *reply; + switch (request.method()) { + case HttpRequest::Get: + reply = proccessGetRequest(request, urlTokens); + break; + default: + reply = createErrorReply(HttpReply::BadRequest); + break; + } + return reply; } HttpReply *LogsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) - + // GET /api/v1/logs?filter={ogFilter} + if (urlTokens.count() == 3) { + // check filter + QString filterString; + if (request.url().hasQuery()) { + if (request.urlQuery().hasQueryItem("filter")) { + filterString = request.urlQuery().queryItemValue("filter"); + } + } + return getLogEntries(filterString); + } return createErrorReply(HttpReply::NotImplemented);} -HttpReply *LogsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) +HttpReply *LogsResource::getLogEntries(const QString &filterString) { - Q_UNUSED(request) - Q_UNUSED(urlTokens) + qCDebug(dcRest) << "Get log entries"; - return createErrorReply(HttpReply::NotImplemented); -} + QPair verification = RestResource::verifyPayload(filterString.toUtf8()); + if (!verification.first) + return createErrorReply(HttpReply::BadRequest); -HttpReply *LogsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) -{ - Q_UNUSED(request) - Q_UNUSED(urlTokens) + QVariantMap filterMap = verification.second.toMap(); - return createErrorReply(HttpReply::NotImplemented); -} + LogFilter filter = JsonTypes::unpackLogFilter(filterMap); -HttpReply *LogsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) -{ - Q_UNUSED(request) - Q_UNUSED(urlTokens) - - return createErrorReply(HttpReply::NotImplemented); + QVariantList entries; + foreach (const LogEntry &entry, GuhCore::instance()->logEngine()->logEntries(filter)) { + entries.append(JsonTypes::packLogEntry(entry)); + } + HttpReply *reply = createSuccessReply(); + reply->setPayload(QJsonDocument::fromVariant(entries).toJson()); + return reply; } } diff --git a/server/rest/logsresource.h b/server/rest/logsresource.h index 20403ff9..fda26e22 100644 --- a/server/rest/logsresource.h +++ b/server/rest/logsresource.h @@ -45,17 +45,10 @@ public: private: // 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 + HttpReply *getLogEntries(const QString &filterString); - // Delete methods - - // Post methods - - // Put methods }; diff --git a/server/rest/restserver.cpp b/server/rest/restserver.cpp index 29fb9a04..23726afd 100644 --- a/server/rest/restserver.cpp +++ b/server/rest/restserver.cpp @@ -49,12 +49,14 @@ void RestServer::setup() m_vendorsResource = new VendorsResource(this); m_pluginsResource = new PluginsResource(this); m_rulesResource = new RulesResource(this); + m_logsResource = new LogsResource(this); m_resources.insert(m_deviceResource->name(), m_deviceResource); m_resources.insert(m_deviceClassesResource->name(), m_deviceClassesResource); m_resources.insert(m_vendorsResource->name(), m_vendorsResource); m_resources.insert(m_pluginsResource->name(), m_pluginsResource); m_resources.insert(m_rulesResource->name(), m_rulesResource); + m_resources.insert(m_logsResource->name(), m_logsResource); } void RestServer::clientConnected(const QUuid &clientId) @@ -69,8 +71,6 @@ void RestServer::clientDisconnected(const QUuid &clientId) void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &request) { - qCDebug(dcRest) << "Process HTTP request"; - QStringList urlTokens = request.url().path().split("/"); urlTokens.removeAll(QString()); diff --git a/server/rest/restserver.h b/server/rest/restserver.h index fb40d5f2..ec9a76a2 100644 --- a/server/rest/restserver.h +++ b/server/rest/restserver.h @@ -30,6 +30,7 @@ #include "vendorsresource.h" #include "pluginsresource.h" #include "rulesresource.h" +#include "logsresource.h" class HttpRequest; class HttpReply; @@ -55,6 +56,7 @@ private: VendorsResource *m_vendorsResource; PluginsResource *m_pluginsResource; RulesResource *m_rulesResource; + LogsResource *m_logsResource; private slots: void setup();