Add support for storing application data on the core
This commit is contained in:
parent
96ae3cd01a
commit
60de0a3eed
82
libnymea-core/jsonrpc/appdatahandler.cpp
Normal file
82
libnymea-core/jsonrpc/appdatahandler.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "appdatahandler.h"
|
||||||
|
#include "jsonrpc/jsonrpcserver.h"
|
||||||
|
|
||||||
|
#include "nymeasettings.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
AppDataHandler::AppDataHandler(QObject *parent) : JsonHandler(parent)
|
||||||
|
{
|
||||||
|
// Methods
|
||||||
|
QString description; QVariantMap params; QVariantMap returns;
|
||||||
|
description = "Store an app data entry to the server. App data can be used by the client application "
|
||||||
|
"to store configuration values. The app data storage is a key-value pair storage. Each "
|
||||||
|
"entry value is identified by an appId, a key and optionally a group. The value data is "
|
||||||
|
"a bytearray and can contain arbitrary data, such as a JSON map or image data, however, "
|
||||||
|
"be aware of the maximum packet size for the used transport.\n"
|
||||||
|
"This might be useful to a client application to sync settings across multiple instances of "
|
||||||
|
"the same application.\n"
|
||||||
|
"The group parameter might be used to create groups for this application.\n"
|
||||||
|
"IMPORTANT: Currently no verification of the appId is done. The appid is merely a mechanism "
|
||||||
|
"to prevent different different client apps from colliding by using the same key for data "
|
||||||
|
"entries. This implies that the app data storage may not be suited for sensitive data given "
|
||||||
|
"that anyone with a valid server token can read it.\n ";
|
||||||
|
params.insert("appId", enumValueName(String));
|
||||||
|
params.insert("o:group", enumValueName(String));
|
||||||
|
params.insert("key", enumValueName(String));
|
||||||
|
params.insert("value", enumValueName(String));
|
||||||
|
registerMethod("Store", description, params, returns);
|
||||||
|
|
||||||
|
description.clear(); params.clear(); returns.clear();
|
||||||
|
description = "Retrieve an app data storage value that has previously been set with Store(). If no value "
|
||||||
|
"had been set for this appId/key combination before, an empty value will be returned.";
|
||||||
|
params.insert("appId", enumValueName(String));
|
||||||
|
params.insert("o:group", enumValueName(String));
|
||||||
|
params.insert("key", enumValueName(String));
|
||||||
|
returns.insert("value", enumValueName(String));
|
||||||
|
registerMethod("Load", description, params, returns);
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
description.clear(); params.clear();
|
||||||
|
description = "Emitted whenever the app data is changed on the server.";
|
||||||
|
params.insert("appId", enumValueName(String));
|
||||||
|
params.insert("o:group", enumValueName(String));
|
||||||
|
params.insert("key", enumValueName(String));
|
||||||
|
params.insert("value", enumValueName(String));
|
||||||
|
registerNotification("Changed", description, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AppDataHandler::name() const
|
||||||
|
{
|
||||||
|
return "AppData";
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonReply* AppDataHandler::Store(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
QString appId = params.value("appId").toString();
|
||||||
|
QString group = params.value("group").toString();
|
||||||
|
QString key = params.value("key").toString();
|
||||||
|
QVariant value = params.value("value");
|
||||||
|
|
||||||
|
// Note: we're using a different file for each group as QSettings tends to get slow with loads of keys.
|
||||||
|
// Might be replaced with a DB at some point if needed. However, current estimate is this won't be
|
||||||
|
// used for excessive amounts of data as it is mostly meant as a config file syncing mechanism.
|
||||||
|
QSettings settings(NymeaSettings::storagePath() + "/appdata/" + appId + '/' + group + ".conf", QSettings::IniFormat);
|
||||||
|
settings.setValue(key, value);
|
||||||
|
return createReply(QVariantMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonReply* AppDataHandler::Load(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
QString appId = params.value("appId").toString();
|
||||||
|
QString group = params.value("group").toString();
|
||||||
|
QString key = params.value("key").toString();
|
||||||
|
|
||||||
|
QSettings settings(NymeaSettings::storagePath() + "/appdata/" + appId + '/' + group + ".conf", QSettings::IniFormat);
|
||||||
|
|
||||||
|
QVariantMap returns;
|
||||||
|
|
||||||
|
returns.insert("value", settings.value(key).toString());
|
||||||
|
return createReply(returns);
|
||||||
|
}
|
||||||
22
libnymea-core/jsonrpc/appdatahandler.h
Normal file
22
libnymea-core/jsonrpc/appdatahandler.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef APPDATAHANDLER_H
|
||||||
|
#define APPDATAHANDLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "jsonrpc/jsonhandler.h"
|
||||||
|
|
||||||
|
class AppDataHandler : public JsonHandler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AppDataHandler(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString name() const override;
|
||||||
|
|
||||||
|
Q_INVOKABLE JsonReply *Store(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE JsonReply *Load(const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // APPDATAHANDLER_H
|
||||||
@ -71,6 +71,7 @@
|
|||||||
#include "configurationhandler.h"
|
#include "configurationhandler.h"
|
||||||
#include "networkmanagerhandler.h"
|
#include "networkmanagerhandler.h"
|
||||||
#include "tagshandler.h"
|
#include "tagshandler.h"
|
||||||
|
#include "appdatahandler.h"
|
||||||
#include "systemhandler.h"
|
#include "systemhandler.h"
|
||||||
#include "usershandler.h"
|
#include "usershandler.h"
|
||||||
#include "zigbeehandler.h"
|
#include "zigbeehandler.h"
|
||||||
@ -594,6 +595,7 @@ void JsonRPCServerImplementation::setup()
|
|||||||
registerHandler(new ConfigurationHandler(this));
|
registerHandler(new ConfigurationHandler(this));
|
||||||
registerHandler(new NetworkManagerHandler(NymeaCore::instance()->networkManager(), this));
|
registerHandler(new NetworkManagerHandler(NymeaCore::instance()->networkManager(), this));
|
||||||
registerHandler(new TagsHandler(this));
|
registerHandler(new TagsHandler(this));
|
||||||
|
registerHandler(new AppDataHandler(this));
|
||||||
registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this));
|
registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this));
|
||||||
registerHandler(new UsersHandler(NymeaCore::instance()->userManager(), this));
|
registerHandler(new UsersHandler(NymeaCore::instance()->userManager(), this));
|
||||||
registerHandler(new ZigbeeHandler(NymeaCore::instance()->zigbeeManager(), this));
|
registerHandler(new ZigbeeHandler(NymeaCore::instance()->zigbeeManager(), this));
|
||||||
|
|||||||
@ -86,6 +86,7 @@ HEADERS += nymeacore.h \
|
|||||||
jsonrpc/configurationhandler.h \
|
jsonrpc/configurationhandler.h \
|
||||||
jsonrpc/networkmanagerhandler.h \
|
jsonrpc/networkmanagerhandler.h \
|
||||||
jsonrpc/tagshandler.h \
|
jsonrpc/tagshandler.h \
|
||||||
|
jsonrpc/appdatahandler.h \
|
||||||
jsonrpc/systemhandler.h \
|
jsonrpc/systemhandler.h \
|
||||||
jsonrpc/scriptshandler.h \
|
jsonrpc/scriptshandler.h \
|
||||||
jsonrpc/usershandler.h \
|
jsonrpc/usershandler.h \
|
||||||
@ -173,6 +174,7 @@ SOURCES += nymeacore.cpp \
|
|||||||
jsonrpc/configurationhandler.cpp \
|
jsonrpc/configurationhandler.cpp \
|
||||||
jsonrpc/networkmanagerhandler.cpp \
|
jsonrpc/networkmanagerhandler.cpp \
|
||||||
jsonrpc/tagshandler.cpp \
|
jsonrpc/tagshandler.cpp \
|
||||||
|
jsonrpc/appdatahandler.cpp \
|
||||||
jsonrpc/systemhandler.cpp \
|
jsonrpc/systemhandler.cpp \
|
||||||
jsonrpc/scriptshandler.cpp \
|
jsonrpc/scriptshandler.cpp \
|
||||||
jsonrpc/usershandler.cpp \
|
jsonrpc/usershandler.cpp \
|
||||||
|
|||||||
@ -83,6 +83,8 @@ translations.files = $$[QT_SOURCE_TREE]/translations/*.qm
|
|||||||
# Redefine target to make output file suite the plugin filename schema
|
# Redefine target to make output file suite the plugin filename schema
|
||||||
TARGET = $$qtLibraryTarget(nymea_integrationplugin"$$TARGET")
|
TARGET = $$qtLibraryTarget(nymea_integrationplugin"$$TARGET")
|
||||||
|
|
||||||
|
target.depends += $${JSONFILE}
|
||||||
|
|
||||||
# Install plugin
|
# Install plugin
|
||||||
target.path = $$[QT_INSTALL_LIBS]/nymea/plugins/
|
target.path = $$[QT_INSTALL_LIBS]/nymea/plugins/
|
||||||
INSTALLS += target translations
|
INSTALLS += target translations
|
||||||
|
|||||||
@ -674,7 +674,7 @@ void TestJSONRPC::enableDisableNotifications_legacy()
|
|||||||
|
|
||||||
QStringList expectedNamespaces;
|
QStringList expectedNamespaces;
|
||||||
if (enabled == "true") {
|
if (enabled == "true") {
|
||||||
expectedNamespaces << "Actions" << "NetworkManager" << "Devices" << "Integrations" << "System" << "Rules" << "States" << "Logging" << "Tags" << "JSONRPC" << "Configuration" << "Events" << "Scripts" << "Users" << "Zigbee";
|
expectedNamespaces << "Actions" << "NetworkManager" << "Devices" << "Integrations" << "System" << "Rules" << "States" << "Logging" << "Tags" << "AppData" << "JSONRPC" << "Configuration" << "Events" << "Scripts" << "Users" << "Zigbee";
|
||||||
}
|
}
|
||||||
std::sort(expectedNamespaces.begin(), expectedNamespaces.end());
|
std::sort(expectedNamespaces.begin(), expectedNamespaces.end());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user