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 "networkmanagerhandler.h"
|
||||
#include "tagshandler.h"
|
||||
#include "appdatahandler.h"
|
||||
#include "systemhandler.h"
|
||||
#include "usershandler.h"
|
||||
#include "zigbeehandler.h"
|
||||
@ -594,6 +595,7 @@ void JsonRPCServerImplementation::setup()
|
||||
registerHandler(new ConfigurationHandler(this));
|
||||
registerHandler(new NetworkManagerHandler(NymeaCore::instance()->networkManager(), this));
|
||||
registerHandler(new TagsHandler(this));
|
||||
registerHandler(new AppDataHandler(this));
|
||||
registerHandler(new SystemHandler(NymeaCore::instance()->platform(), this));
|
||||
registerHandler(new UsersHandler(NymeaCore::instance()->userManager(), this));
|
||||
registerHandler(new ZigbeeHandler(NymeaCore::instance()->zigbeeManager(), this));
|
||||
|
||||
@ -86,6 +86,7 @@ HEADERS += nymeacore.h \
|
||||
jsonrpc/configurationhandler.h \
|
||||
jsonrpc/networkmanagerhandler.h \
|
||||
jsonrpc/tagshandler.h \
|
||||
jsonrpc/appdatahandler.h \
|
||||
jsonrpc/systemhandler.h \
|
||||
jsonrpc/scriptshandler.h \
|
||||
jsonrpc/usershandler.h \
|
||||
@ -173,6 +174,7 @@ SOURCES += nymeacore.cpp \
|
||||
jsonrpc/configurationhandler.cpp \
|
||||
jsonrpc/networkmanagerhandler.cpp \
|
||||
jsonrpc/tagshandler.cpp \
|
||||
jsonrpc/appdatahandler.cpp \
|
||||
jsonrpc/systemhandler.cpp \
|
||||
jsonrpc/scriptshandler.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
|
||||
TARGET = $$qtLibraryTarget(nymea_integrationplugin"$$TARGET")
|
||||
|
||||
target.depends += $${JSONFILE}
|
||||
|
||||
# Install plugin
|
||||
target.path = $$[QT_INSTALL_LIBS]/nymea/plugins/
|
||||
INSTALLS += target translations
|
||||
|
||||
@ -674,7 +674,7 @@ void TestJSONRPC::enableDisableNotifications_legacy()
|
||||
|
||||
QStringList expectedNamespaces;
|
||||
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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user