add rest logging

pull/135/head
Simon Stürz 2015-08-01 14:21:34 +02:00 committed by Michael Zanetti
parent 1f6cfd4527
commit 36fbf27762
6 changed files with 147 additions and 37 deletions

View File

@ -34,6 +34,7 @@ DevicesResource::DevicesResource(QObject *parent) :
connect(GuhCore::instance(), &GuhCore::actionExecuted, this, &DevicesResource::actionExecuted); connect(GuhCore::instance(), &GuhCore::actionExecuted, this, &DevicesResource::actionExecuted);
connect(GuhCore::instance(), &GuhCore::deviceSetupFinished, this, &DevicesResource::deviceSetupFinished); connect(GuhCore::instance(), &GuhCore::deviceSetupFinished, this, &DevicesResource::deviceSetupFinished);
connect(GuhCore::instance(), &GuhCore::deviceEditFinished, this, &DevicesResource::deviceEditFinished); connect(GuhCore::instance(), &GuhCore::deviceEditFinished, this, &DevicesResource::deviceEditFinished);
connect(GuhCore::instance(), &GuhCore::pairingFinished, this, &DevicesResource::pairingFinished);
} }
QString DevicesResource::name() const QString DevicesResource::name() const
@ -128,17 +129,18 @@ HttpReply *DevicesResource::proccessDeleteRequest(const HttpRequest &request, co
return removeDevice(m_device); return removeDevice(m_device);
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy} // TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
return createErrorReply(HttpReply::NotImplemented); return createErrorReply(HttpReply::NotImplemented);
} }
HttpReply *DevicesResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) HttpReply *DevicesResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens)
{ {
Q_UNUSED(request) Q_UNUSED(request)
// POST /api/v1/devices // PUT /api/v1/devices
if (urlTokens.count() == 3) if (urlTokens.count() == 3)
return createErrorReply(HttpReply::BadRequest); return createErrorReply(HttpReply::BadRequest);
// POST /api/v1/devices/{deviceId} // PUT /api/v1/devices/{deviceId}
if (urlTokens.count() == 4) if (urlTokens.count() == 4)
return editDevice(m_device, request.payload()); return editDevice(m_device, request.payload());
@ -152,6 +154,14 @@ HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, cons
if (urlTokens.count() == 3) if (urlTokens.count() == 3)
return addConfiguredDevice(request.payload()); 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} // POST /api/v1/devices/{deviceId}
if (urlTokens.count() == 4) if (urlTokens.count() == 4)
return createErrorReply(HttpReply::BadRequest); return createErrorReply(HttpReply::BadRequest);
@ -301,6 +311,71 @@ HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const
return reply; return reply;
} }
HttpReply *DevicesResource::pairDevice(const QByteArray &payload) const
{
QPair<bool, QVariant> 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<bool, QVariant> 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 HttpReply *DevicesResource::editDevice(Device *device, const QByteArray &payload) const
{ {
qCDebug(dcRest) << "Edit device" << device->id(); qCDebug(dcRest) << "Edit device" << device->id();
@ -388,4 +463,24 @@ void DevicesResource::deviceEditFinished(Device *device, DeviceManager::DeviceEr
reply->finished(); 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();
}
} }

View File

@ -46,7 +46,7 @@ private:
mutable QHash<ActionId, HttpReply *> m_asyncActionExecutions; mutable QHash<ActionId, HttpReply *> m_asyncActionExecutions;
mutable QHash<DeviceId, HttpReply *> m_asyncDeviceAdditions; mutable QHash<DeviceId, HttpReply *> m_asyncDeviceAdditions;
mutable QHash<Device *, HttpReply *> m_asyncEditDevice; mutable QHash<Device *, HttpReply *> m_asyncEditDevice;
mutable QHash<QUuid, HttpReply *> m_asyncPairingRequests; mutable QHash<PairingTransactionId, HttpReply *> m_asyncPairingRequests;
Device *m_device; Device *m_device;
@ -68,6 +68,8 @@ private:
// Post methods // Post methods
HttpReply *executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const; HttpReply *executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const;
HttpReply *addConfiguredDevice(const QByteArray &payload) const; HttpReply *addConfiguredDevice(const QByteArray &payload) const;
HttpReply *pairDevice(const QByteArray &payload) const;
HttpReply *confirmPairDevice(const QByteArray &payload) const;
// Put methods // Put methods
HttpReply *editDevice(Device *device, const QByteArray &payload) const; HttpReply *editDevice(Device *device, const QByteArray &payload) const;
@ -76,6 +78,7 @@ private slots:
void actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status); void actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status);
void deviceSetupFinished(Device *device, DeviceManager::DeviceError status); void deviceSetupFinished(Device *device, DeviceManager::DeviceError status);
void deviceEditFinished(Device *device, DeviceManager::DeviceError status); void deviceEditFinished(Device *device, DeviceManager::DeviceError status);
void pairingFinished(const PairingTransactionId &pairingTransactionId, DeviceManager::DeviceError status, const DeviceId &deviceId);
}; };

View File

@ -20,6 +20,11 @@
#include "logsresource.h" #include "logsresource.h"
#include "httprequest.h" #include "httprequest.h"
#include "loggingcategories.h"
#include "guhcore.h"
#include "logging/logengine.h"
#include <QJsonDocument>
namespace guhserver { namespace guhserver {
@ -35,41 +40,53 @@ QString LogsResource::name() const
HttpReply *LogsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens) HttpReply *LogsResource::proccessRequest(const HttpRequest &request, const QStringList &urlTokens)
{ {
Q_UNUSED(request) // check method
Q_UNUSED(urlTokens) HttpReply *reply;
switch (request.method()) {
return createErrorReply(HttpReply::NotImplemented); 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) HttpReply *LogsResource::proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens)
{ {
Q_UNUSED(request) // GET /api/v1/logs?filter={ogFilter}
Q_UNUSED(urlTokens) 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);} return createErrorReply(HttpReply::NotImplemented);}
HttpReply *LogsResource::proccessDeleteRequest(const HttpRequest &request, const QStringList &urlTokens) HttpReply *LogsResource::getLogEntries(const QString &filterString)
{ {
Q_UNUSED(request) qCDebug(dcRest) << "Get log entries";
Q_UNUSED(urlTokens)
return createErrorReply(HttpReply::NotImplemented); QPair<bool, QVariant> verification = RestResource::verifyPayload(filterString.toUtf8());
} if (!verification.first)
return createErrorReply(HttpReply::BadRequest);
HttpReply *LogsResource::proccessPutRequest(const HttpRequest &request, const QStringList &urlTokens) QVariantMap filterMap = verification.second.toMap();
{
Q_UNUSED(request)
Q_UNUSED(urlTokens)
return createErrorReply(HttpReply::NotImplemented); LogFilter filter = JsonTypes::unpackLogFilter(filterMap);
}
HttpReply *LogsResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens) QVariantList entries;
{ foreach (const LogEntry &entry, GuhCore::instance()->logEngine()->logEntries(filter)) {
Q_UNUSED(request) entries.append(JsonTypes::packLogEntry(entry));
Q_UNUSED(urlTokens) }
HttpReply *reply = createSuccessReply();
return createErrorReply(HttpReply::NotImplemented); reply->setPayload(QJsonDocument::fromVariant(entries).toJson());
return reply;
} }
} }

View File

@ -45,17 +45,10 @@ public:
private: private:
// Process method // Process method
HttpReply *proccessGetRequest(const HttpRequest &request, const QStringList &urlTokens) override; 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 // Get methods
HttpReply *getLogEntries(const QString &filterString);
// Delete methods
// Post methods
// Put methods
}; };

View File

@ -49,12 +49,14 @@ void RestServer::setup()
m_vendorsResource = new VendorsResource(this); m_vendorsResource = new VendorsResource(this);
m_pluginsResource = new PluginsResource(this); m_pluginsResource = new PluginsResource(this);
m_rulesResource = new RulesResource(this); m_rulesResource = new RulesResource(this);
m_logsResource = new LogsResource(this);
m_resources.insert(m_deviceResource->name(), m_deviceResource); m_resources.insert(m_deviceResource->name(), m_deviceResource);
m_resources.insert(m_deviceClassesResource->name(), m_deviceClassesResource); m_resources.insert(m_deviceClassesResource->name(), m_deviceClassesResource);
m_resources.insert(m_vendorsResource->name(), m_vendorsResource); m_resources.insert(m_vendorsResource->name(), m_vendorsResource);
m_resources.insert(m_pluginsResource->name(), m_pluginsResource); m_resources.insert(m_pluginsResource->name(), m_pluginsResource);
m_resources.insert(m_rulesResource->name(), m_rulesResource); m_resources.insert(m_rulesResource->name(), m_rulesResource);
m_resources.insert(m_logsResource->name(), m_logsResource);
} }
void RestServer::clientConnected(const QUuid &clientId) 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) void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &request)
{ {
qCDebug(dcRest) << "Process HTTP request";
QStringList urlTokens = request.url().path().split("/"); QStringList urlTokens = request.url().path().split("/");
urlTokens.removeAll(QString()); urlTokens.removeAll(QString());

View File

@ -30,6 +30,7 @@
#include "vendorsresource.h" #include "vendorsresource.h"
#include "pluginsresource.h" #include "pluginsresource.h"
#include "rulesresource.h" #include "rulesresource.h"
#include "logsresource.h"
class HttpRequest; class HttpRequest;
class HttpReply; class HttpReply;
@ -55,6 +56,7 @@ private:
VendorsResource *m_vendorsResource; VendorsResource *m_vendorsResource;
PluginsResource *m_pluginsResource; PluginsResource *m_pluginsResource;
RulesResource *m_rulesResource; RulesResource *m_rulesResource;
LogsResource *m_logsResource;
private slots: private slots:
void setup(); void setup();