more work on rules
disallow removing a device if a rule still refers to it unless parameters contain information on what to do with those rules.
This commit is contained in:
parent
cd67ab567b
commit
be90f47f63
@ -78,9 +78,37 @@ QList<DeviceClass> GuhCore::supportedDevices(const VendorId &vendorId) const
|
|||||||
return m_deviceManager->supportedDevices(vendorId);
|
return m_deviceManager->supportedDevices(vendorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<DeviceManager::DeviceError, QString> GuhCore::removeConfiguredDevice(const DeviceId &deviceId)
|
QPair<DeviceManager::DeviceError, QString> GuhCore::removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList)
|
||||||
{
|
{
|
||||||
// TODO: make sure we don't remove a device and keep stale rules around...
|
QHash<RuleId, RuleEngine::RemovePolicy> toBeChanged;
|
||||||
|
QList<RuleId> unhandledRules;
|
||||||
|
foreach (const RuleId &ruleId, m_ruleEngine->findRules(deviceId)) {
|
||||||
|
bool found = false;
|
||||||
|
foreach (const RuleId &policyRuleId, removePolicyList.keys()) {
|
||||||
|
if (ruleId == policyRuleId) {
|
||||||
|
found = true;
|
||||||
|
toBeChanged.insert(ruleId, removePolicyList.value(ruleId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
unhandledRules.append(ruleId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unhandledRules.isEmpty()) {
|
||||||
|
return qMakePair<DeviceManager::DeviceError, QString>(DeviceManager::DeviceErrorMissingParameter, "There are unhandled rules which depend on this device.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the rules...
|
||||||
|
foreach (const RuleId &ruleId, toBeChanged.keys()) {
|
||||||
|
if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyCascade) {
|
||||||
|
m_ruleEngine->removeRule(ruleId);
|
||||||
|
} else if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyUpdate){
|
||||||
|
m_ruleEngine->removeDeviceFromRule(ruleId, deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m_deviceManager->removeConfiguredDevice(deviceId);
|
return m_deviceManager->removeConfiguredDevice(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +172,16 @@ QList<Rule> GuhCore::rules() const
|
|||||||
return m_ruleEngine->rules();
|
return m_ruleEngine->rules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<RuleId> GuhCore::ruleIds() const
|
||||||
|
{
|
||||||
|
return m_ruleEngine->ruleIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule GuhCore::findRule(const RuleId &ruleId)
|
||||||
|
{
|
||||||
|
return m_ruleEngine->findRule(ruleId);
|
||||||
|
}
|
||||||
|
|
||||||
RuleEngine::RuleError GuhCore::addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList)
|
RuleEngine::RuleError GuhCore::addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList)
|
||||||
{
|
{
|
||||||
return m_ruleEngine->addRule(id, eventDescriptorList, actionList);
|
return m_ruleEngine->addRule(id, eventDescriptorList, actionList);
|
||||||
@ -154,6 +192,11 @@ RuleEngine::RuleError GuhCore::removeRule(const RuleId &id)
|
|||||||
return m_ruleEngine->removeRule(id);
|
return m_ruleEngine->removeRule(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<RuleId> GuhCore::findRules(const DeviceId &deviceId)
|
||||||
|
{
|
||||||
|
return m_ruleEngine->findRules(deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Returns a pointer to the \l{DeviceManager} instance owned by GuhCore.*/
|
/*! Returns a pointer to the \l{DeviceManager} instance owned by GuhCore.*/
|
||||||
DeviceManager *GuhCore::deviceManager() const
|
DeviceManager *GuhCore::deviceManager() const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public:
|
|||||||
QList<Device*> configuredDevices() const;
|
QList<Device*> configuredDevices() const;
|
||||||
Device *findConfiguredDevice(const DeviceId &deviceId) const;
|
Device *findConfiguredDevice(const DeviceId &deviceId) const;
|
||||||
QList<Device*> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
|
QList<Device*> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
|
||||||
QPair<DeviceManager::DeviceError, QString> removeConfiguredDevice(const DeviceId &deviceId);
|
QPair<DeviceManager::DeviceError, QString> removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList);
|
||||||
|
|
||||||
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId);
|
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId);
|
||||||
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const QList<Param> ¶ms);
|
QPair<DeviceManager::DeviceError, QString> pairDevice(const DeviceClassId &deviceClassId, const QList<Param> ¶ms);
|
||||||
@ -64,8 +64,11 @@ public:
|
|||||||
QPair<DeviceManager::DeviceError, QString> executeAction(const Action &action);
|
QPair<DeviceManager::DeviceError, QString> executeAction(const Action &action);
|
||||||
|
|
||||||
QList<Rule> rules() const;
|
QList<Rule> rules() const;
|
||||||
|
QList<RuleId> ruleIds() const;
|
||||||
|
Rule findRule(const RuleId &ruleId);
|
||||||
RuleEngine::RuleError addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList);
|
RuleEngine::RuleError addRule(const RuleId &id, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actionList);
|
||||||
RuleEngine::RuleError removeRule(const RuleId &id);
|
RuleEngine::RuleError removeRule(const RuleId &id);
|
||||||
|
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void eventTriggered(const Event &event);
|
void eventTriggered(const Event &event);
|
||||||
|
|||||||
@ -147,6 +147,12 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
setDescription("RemoveConfiguredDevice", "Remove a device from the system.");
|
setDescription("RemoveConfiguredDevice", "Remove a device from the system.");
|
||||||
params.insert("deviceId", "uuid");
|
params.insert("deviceId", "uuid");
|
||||||
|
QVariantList removePolicyList;
|
||||||
|
QVariantMap policy;
|
||||||
|
policy.insert("ruleId", "uuid");
|
||||||
|
policy.insert("policy", JsonTypes::removePolicyTypesRef());
|
||||||
|
removePolicyList.append(policy);
|
||||||
|
params.insert("o:removePolicyList", removePolicyList);
|
||||||
setParams("RemoveConfiguredDevice", params);
|
setParams("RemoveConfiguredDevice", params);
|
||||||
returns.insert("success", "bool");
|
returns.insert("success", "bool");
|
||||||
returns.insert("errorMessage", "string");
|
returns.insert("errorMessage", "string");
|
||||||
@ -480,8 +486,16 @@ JsonReply* DeviceHandler::GetConfiguredDevices(const QVariantMap ¶ms) const
|
|||||||
|
|
||||||
JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms)
|
JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms)
|
||||||
{
|
{
|
||||||
|
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||||
|
QHash<RuleId, RuleEngine::RemovePolicy> removePolicyList;
|
||||||
|
foreach (const QVariant &variant, params.value("removePolicyList").toList()) {
|
||||||
|
RuleId ruleId = RuleId(variant.toMap().value("ruleId").toString());
|
||||||
|
RuleEngine::RemovePolicy policy = variant.toMap().value("policy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate;
|
||||||
|
removePolicyList.insert(ruleId, policy);
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap returns;
|
QVariantMap returns;
|
||||||
QPair<DeviceManager::DeviceError, QString> status = GuhCore::instance()->removeConfiguredDevice(DeviceId(params.value("deviceId").toString()));
|
QPair<DeviceManager::DeviceError, QString> status = GuhCore::instance()->removeConfiguredDevice(deviceId, removePolicyList);
|
||||||
switch(status.first) {
|
switch(status.first) {
|
||||||
case DeviceManager::DeviceErrorNoError:
|
case DeviceManager::DeviceErrorNoError:
|
||||||
returns.insert("success", true);
|
returns.insert("success", true);
|
||||||
@ -491,6 +505,10 @@ JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms)
|
|||||||
returns.insert("success", false);
|
returns.insert("success", false);
|
||||||
returns.insert("errorMessage", QString("No such device: %1").arg(status.second));
|
returns.insert("errorMessage", QString("No such device: %1").arg(status.second));
|
||||||
break;
|
break;
|
||||||
|
case DeviceManager::DeviceErrorMissingParameter:
|
||||||
|
returns.insert("success", false);
|
||||||
|
returns.insert("errorMessage", QString("Missing Parameter: %1").arg(status.second));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
returns.insert("success", false);
|
returns.insert("success", false);
|
||||||
returns.insert("errorMessage", "Unknown error.");
|
returns.insert("errorMessage", "Unknown error.");
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#define JSON_PROTOCOL_VERSION 2
|
#define JSON_PROTOCOL_VERSION 3
|
||||||
|
|
||||||
JsonRPCServer::JsonRPCServer(QObject *parent):
|
JsonRPCServer::JsonRPCServer(QObject *parent):
|
||||||
JsonHandler(parent),
|
JsonHandler(parent),
|
||||||
|
|||||||
@ -32,6 +32,7 @@ QVariantList JsonTypes::s_stateOperatorTypes;
|
|||||||
QVariantList JsonTypes::s_valueOperatorTypes;
|
QVariantList JsonTypes::s_valueOperatorTypes;
|
||||||
QVariantList JsonTypes::s_createMethodTypes;
|
QVariantList JsonTypes::s_createMethodTypes;
|
||||||
QVariantList JsonTypes::s_setupMethodTypes;
|
QVariantList JsonTypes::s_setupMethodTypes;
|
||||||
|
QVariantList JsonTypes::s_removePolicyTypes;
|
||||||
|
|
||||||
QVariantMap JsonTypes::s_paramType;
|
QVariantMap JsonTypes::s_paramType;
|
||||||
QVariantMap JsonTypes::s_param;
|
QVariantMap JsonTypes::s_param;
|
||||||
@ -60,6 +61,7 @@ void JsonTypes::init()
|
|||||||
s_valueOperatorTypes << "OperatorTypeEquals" << "OperatorTypeNotEquals" << "OperatorTypeLess" << "OperatorTypeGreater" << "OperatorTypeLessThan" << "OperatorTypeGreaterThan";
|
s_valueOperatorTypes << "OperatorTypeEquals" << "OperatorTypeNotEquals" << "OperatorTypeLess" << "OperatorTypeGreater" << "OperatorTypeLessThan" << "OperatorTypeGreaterThan";
|
||||||
s_createMethodTypes << "CreateMethodUser" << "CreateMethodAuto" << "CreateMethodDiscovery";
|
s_createMethodTypes << "CreateMethodUser" << "CreateMethodAuto" << "CreateMethodDiscovery";
|
||||||
s_setupMethodTypes << "SetupMethodJustAdd" << "SetupMethodDisplayPin" << "SetupMethodEnterPin" << "SetupMethodPushButton";
|
s_setupMethodTypes << "SetupMethodJustAdd" << "SetupMethodDisplayPin" << "SetupMethodEnterPin" << "SetupMethodPushButton";
|
||||||
|
s_removePolicyTypes << "RemovePolicyCascade" << "RemovePolicyUpdate";
|
||||||
|
|
||||||
// ParamType
|
// ParamType
|
||||||
s_paramType.insert("name", "string");
|
s_paramType.insert("name", "string");
|
||||||
@ -180,6 +182,7 @@ QVariantMap JsonTypes::allTypes()
|
|||||||
allTypes.insert("SetupMethodType", setupMethodTypes());
|
allTypes.insert("SetupMethodType", setupMethodTypes());
|
||||||
allTypes.insert("ValueOperatorType", valueOperatorTypes());
|
allTypes.insert("ValueOperatorType", valueOperatorTypes());
|
||||||
allTypes.insert("StateOperatorType", stateOperatorTypes());
|
allTypes.insert("StateOperatorType", stateOperatorTypes());
|
||||||
|
allTypes.insert("RemovePolicyType", removePolicyTypes());
|
||||||
allTypes.insert("StateType", stateTypeDescription());
|
allTypes.insert("StateType", stateTypeDescription());
|
||||||
allTypes.insert("StateDescriptor", stateDescriptorDescription());
|
allTypes.insert("StateDescriptor", stateDescriptorDescription());
|
||||||
allTypes.insert("StateEvaluator", stateEvaluatorDescription());
|
allTypes.insert("StateEvaluator", stateEvaluatorDescription());
|
||||||
|
|||||||
@ -69,6 +69,7 @@ public:
|
|||||||
DECLARE_TYPE(valueOperatorTypes, "ValueOperatorType")
|
DECLARE_TYPE(valueOperatorTypes, "ValueOperatorType")
|
||||||
DECLARE_TYPE(createMethodTypes, "CreateMethodType")
|
DECLARE_TYPE(createMethodTypes, "CreateMethodType")
|
||||||
DECLARE_TYPE(setupMethodTypes, "SetupMethodType")
|
DECLARE_TYPE(setupMethodTypes, "SetupMethodType")
|
||||||
|
DECLARE_TYPE(removePolicyTypes, "RemovePolicyType")
|
||||||
DECLARE_OBJECT(paramType, "ParamType")
|
DECLARE_OBJECT(paramType, "ParamType")
|
||||||
DECLARE_OBJECT(param, "Param")
|
DECLARE_OBJECT(param, "Param")
|
||||||
DECLARE_OBJECT(paramDescriptor, "ParamDescriptor")
|
DECLARE_OBJECT(paramDescriptor, "ParamDescriptor")
|
||||||
|
|||||||
@ -32,11 +32,16 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
setDescription("GetRules", "Get all configured rules");
|
setDescription("GetRules", "Get all configured rules");
|
||||||
setParams("GetRules", params);
|
setParams("GetRules", params);
|
||||||
QVariantList rules;
|
returns.insert("ruleIds", QVariantList() << "uuid");
|
||||||
rules.append(JsonTypes::ruleRef());
|
|
||||||
returns.insert("rules", rules);
|
|
||||||
setReturns("GetRules", returns);
|
setReturns("GetRules", returns);
|
||||||
|
|
||||||
|
params.clear(); returns.clear();
|
||||||
|
setDescription("GetRuleDetails", "Get details for the rule identified by ruleId");
|
||||||
|
params.insert("ruleId", "uuid");
|
||||||
|
setParams("GetRuleDetails", params);
|
||||||
|
returns.insert("rule", JsonTypes::ruleRef());
|
||||||
|
setReturns("GetRuleDetails", returns);
|
||||||
|
|
||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
setDescription("AddRule", "Add a rule.");
|
setDescription("AddRule", "Add a rule.");
|
||||||
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
||||||
@ -58,6 +63,13 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||||||
returns.insert("success", "bool");
|
returns.insert("success", "bool");
|
||||||
returns.insert("errorMessage", "string");
|
returns.insert("errorMessage", "string");
|
||||||
setReturns("RemoveRule", returns);
|
setReturns("RemoveRule", returns);
|
||||||
|
|
||||||
|
params.clear(); returns.clear();
|
||||||
|
setDescription("FindRules", "Find a list of rules containing any of the given parameters.");
|
||||||
|
params.insert("deviceId", "uuid");
|
||||||
|
setParams("FindRules", params);
|
||||||
|
returns.insert("ruleIds", QVariantList() << "uuid");
|
||||||
|
setReturns("FindRules", returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RulesHandler::name() const
|
QString RulesHandler::name() const
|
||||||
@ -70,16 +82,26 @@ JsonReply* RulesHandler::GetRules(const QVariantMap ¶ms)
|
|||||||
Q_UNUSED(params)
|
Q_UNUSED(params)
|
||||||
|
|
||||||
QVariantList rulesList;
|
QVariantList rulesList;
|
||||||
foreach (const Rule &rule, GuhCore::instance()->rules()) {
|
foreach (const RuleId &ruleId, GuhCore::instance()->ruleIds()) {
|
||||||
QVariantMap ruleMap = JsonTypes::packRule(rule);
|
rulesList.append(ruleId);
|
||||||
rulesList.append(ruleMap);
|
|
||||||
}
|
}
|
||||||
QVariantMap returns;
|
QVariantMap returns;
|
||||||
returns.insert("rules", rulesList);
|
returns.insert("ruleIds", rulesList);
|
||||||
|
|
||||||
return createReply(returns);
|
return createReply(returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonReply *RulesHandler::GetRuleDetails(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
RuleId ruleId = RuleId(params.value("ruleId").toString());
|
||||||
|
Rule rule = GuhCore::instance()->findRule(ruleId);
|
||||||
|
QVariantMap ruleData;
|
||||||
|
if (!rule.id().isNull()) {
|
||||||
|
ruleData.insert("rule", JsonTypes::packRule(rule));
|
||||||
|
}
|
||||||
|
return createReply(ruleData);
|
||||||
|
}
|
||||||
|
|
||||||
JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||||
{
|
{
|
||||||
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
|
if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) {
|
||||||
@ -157,3 +179,18 @@ JsonReply* RulesHandler::RemoveRule(const QVariantMap ¶ms)
|
|||||||
}
|
}
|
||||||
return createReply(returns);
|
return createReply(returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonReply *RulesHandler::FindRules(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
|
||||||
|
QList<RuleId> rules = GuhCore::instance()->findRules(deviceId);
|
||||||
|
|
||||||
|
QVariantList rulesList;
|
||||||
|
foreach (const RuleId &ruleId, rules) {
|
||||||
|
rulesList.append(ruleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap returns;
|
||||||
|
returns.insert("ruleIds", rulesList);
|
||||||
|
return createReply(returns);
|
||||||
|
}
|
||||||
|
|||||||
@ -30,9 +30,11 @@ public:
|
|||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
Q_INVOKABLE JsonReply* GetRules(const QVariantMap ¶ms);
|
Q_INVOKABLE JsonReply* GetRules(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE JsonReply* GetRuleDetails(const QVariantMap ¶ms);
|
||||||
|
|
||||||
Q_INVOKABLE JsonReply* AddRule(const QVariantMap ¶ms);
|
Q_INVOKABLE JsonReply* AddRule(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE JsonReply* FindRules(const QVariantMap ¶ms);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -133,7 +133,7 @@ RuleEngine::RuleEngine(QObject *parent) :
|
|||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
Rule rule = Rule(RuleId(idString), eventDescriptorList, stateEvaluator, actions);
|
Rule rule = Rule(RuleId(idString), eventDescriptorList, stateEvaluator, actions);
|
||||||
m_rules.append(rule);
|
appendRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -149,12 +149,12 @@ QList<Action> RuleEngine::evaluateEvent(const Event &event)
|
|||||||
qDebug() << "got event:" << event << device->name();
|
qDebug() << "got event:" << event << device->name();
|
||||||
|
|
||||||
QList<Action> actions;
|
QList<Action> actions;
|
||||||
for (int i = 0; i < m_rules.count(); ++i) {
|
foreach (const RuleId &id, m_ruleIds) {
|
||||||
qDebug() << "evaluating rule" << i << m_rules.at(i).eventDescriptors();
|
Rule rule = m_rules.value(id);
|
||||||
if (containsEvent(m_rules.at(i), event)) {
|
if (containsEvent(rule, event)) {
|
||||||
if (m_rules.at(i).stateEvaluator().evaluate()) {
|
if (rule.stateEvaluator().evaluate()) {
|
||||||
qDebug() << "states matching!";
|
qDebug() << "states matching!";
|
||||||
actions.append(m_rules.at(i).actions());
|
actions.append(rule.actions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +220,7 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<Even
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rule rule = Rule(ruleId, eventDescriptorList, stateEvaluator, actions);
|
Rule rule = Rule(ruleId, eventDescriptorList, stateEvaluator, actions);
|
||||||
m_rules.append(rule);
|
appendRule(rule);
|
||||||
emit ruleAdded(rule.id());
|
emit ruleAdded(rule.id());
|
||||||
|
|
||||||
QSettings settings(m_settingsFile);
|
QSettings settings(m_settingsFile);
|
||||||
@ -263,10 +263,18 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<Even
|
|||||||
return RuleErrorNoError;
|
return RuleErrorNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Returns a list of all \l{Rule}{Rules} loaded in this Engine.*/
|
/*! Returns a list of all \l{Rule}{Rules} loaded in this Engine.
|
||||||
|
Be aware that this does not necessarily reflect the order of the rules in the engine.
|
||||||
|
Use ruleIds() if you need the correct order.
|
||||||
|
*/
|
||||||
QList<Rule> RuleEngine::rules() const
|
QList<Rule> RuleEngine::rules() const
|
||||||
{
|
{
|
||||||
return m_rules;
|
return m_rules.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<RuleId> RuleEngine::ruleIds() const
|
||||||
|
{
|
||||||
|
return m_ruleIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Removes the \l{Rule} with the given \a ruleId from the Engine.
|
/*! Removes the \l{Rule} with the given \a ruleId from the Engine.
|
||||||
@ -274,22 +282,22 @@ QList<Rule> RuleEngine::rules() const
|
|||||||
was successful or not. */
|
was successful or not. */
|
||||||
RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_rules.count(); ++i) {
|
int index = m_ruleIds.indexOf(ruleId);
|
||||||
Rule rule = m_rules.at(i);
|
|
||||||
if (rule.id() == ruleId) {
|
|
||||||
|
|
||||||
m_rules.takeAt(i);
|
if (index < 0) {
|
||||||
|
return RuleErrorRuleNotFound;
|
||||||
QSettings settings(m_settingsFile);
|
|
||||||
settings.beginGroup(rule.id().toString());
|
|
||||||
settings.remove("");
|
|
||||||
settings.endGroup();
|
|
||||||
|
|
||||||
emit ruleRemoved(rule.id());
|
|
||||||
return RuleErrorNoError;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return RuleErrorRuleNotFound;
|
|
||||||
|
m_ruleIds.takeAt(index);
|
||||||
|
m_rules.remove(ruleId);
|
||||||
|
|
||||||
|
QSettings settings(m_settingsFile);
|
||||||
|
settings.beginGroup(ruleId.toString());
|
||||||
|
settings.remove("");
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
emit ruleRemoved(ruleId);
|
||||||
|
return RuleErrorNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rule RuleEngine::findRule(const RuleId &ruleId)
|
Rule RuleEngine::findRule(const RuleId &ruleId)
|
||||||
@ -302,6 +310,68 @@ Rule RuleEngine::findRule(const RuleId &ruleId)
|
|||||||
return Rule();
|
return Rule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<RuleId> RuleEngine::findRules(const DeviceId &deviceId)
|
||||||
|
{
|
||||||
|
// Find all offending rules
|
||||||
|
QList<RuleId> offendingRules;
|
||||||
|
foreach (const Rule &rule, m_rules) {
|
||||||
|
bool offending = false;
|
||||||
|
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
||||||
|
if (eventDescriptor.deviceId() == deviceId) {
|
||||||
|
offending = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!offending && rule.stateEvaluator().containsDevice(deviceId)) {
|
||||||
|
offending = true;
|
||||||
|
}
|
||||||
|
if (!offending) {
|
||||||
|
foreach (const Action &action, rule.actions()) {
|
||||||
|
if (action.deviceId() == deviceId) {
|
||||||
|
offending = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (offending) {
|
||||||
|
offendingRules.append(rule.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offendingRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId)
|
||||||
|
{
|
||||||
|
if (!m_rules.contains(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Rule rule = m_rules.value(id);
|
||||||
|
QList<EventDescriptor> eventDescriptors = rule.eventDescriptors();
|
||||||
|
QList<int> removeIndexes;
|
||||||
|
for (int i = 0; i < eventDescriptors.count(); i++) {
|
||||||
|
if (eventDescriptors.at(i).deviceId() == deviceId) {
|
||||||
|
removeIndexes.append(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (removeIndexes.count() > 0) {
|
||||||
|
eventDescriptors.takeAt(removeIndexes.takeLast());
|
||||||
|
}
|
||||||
|
StateEvaluator stateEvalatuator = rule.stateEvaluator();
|
||||||
|
stateEvalatuator.removeDevice(deviceId);
|
||||||
|
|
||||||
|
QList<Action> actions = rule.actions();
|
||||||
|
for (int i = 0; i < actions.count(); i++) {
|
||||||
|
if (actions.at(i).deviceId() == deviceId) {
|
||||||
|
removeIndexes.append(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (removeIndexes.count() > 0) {
|
||||||
|
actions.takeAt(removeIndexes.takeLast());
|
||||||
|
}
|
||||||
|
Rule newRule(id, eventDescriptors, stateEvalatuator, actions);
|
||||||
|
m_rules[id] = newRule;
|
||||||
|
}
|
||||||
|
|
||||||
bool RuleEngine::containsEvent(const Rule &rule, const Event &event)
|
bool RuleEngine::containsEvent(const Rule &rule, const Event &event)
|
||||||
{
|
{
|
||||||
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
||||||
@ -311,3 +381,9 @@ bool RuleEngine::containsEvent(const Rule &rule, const Event &event)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RuleEngine::appendRule(const Rule &rule)
|
||||||
|
{
|
||||||
|
m_rules.insert(rule.id(), rule);
|
||||||
|
m_ruleIds.append(rule.id());
|
||||||
|
}
|
||||||
|
|||||||
@ -40,6 +40,11 @@ public:
|
|||||||
RuleErrorActionTypeNotFound
|
RuleErrorActionTypeNotFound
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RemovePolicy {
|
||||||
|
RemovePolicyCascade,
|
||||||
|
RemovePolicyUpdate
|
||||||
|
};
|
||||||
|
|
||||||
explicit RuleEngine(QObject *parent = 0);
|
explicit RuleEngine(QObject *parent = 0);
|
||||||
|
|
||||||
QList<Action> evaluateEvent(const Event &event);
|
QList<Action> evaluateEvent(const Event &event);
|
||||||
@ -47,10 +52,14 @@ public:
|
|||||||
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions);
|
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions);
|
||||||
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions);
|
RuleError addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions);
|
||||||
QList<Rule> rules() const;
|
QList<Rule> rules() const;
|
||||||
|
QList<RuleId> ruleIds() const;
|
||||||
|
|
||||||
RuleError removeRule(const RuleId &ruleId);
|
RuleError removeRule(const RuleId &ruleId);
|
||||||
|
|
||||||
Rule findRule(const RuleId &ruleId);
|
Rule findRule(const RuleId &ruleId);
|
||||||
|
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||||
|
|
||||||
|
void removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ruleAdded(const RuleId &ruleId);
|
void ruleAdded(const RuleId &ruleId);
|
||||||
@ -59,10 +68,12 @@ signals:
|
|||||||
private:
|
private:
|
||||||
bool containsEvent(const Rule &rule, const Event &event);
|
bool containsEvent(const Rule &rule, const Event &event);
|
||||||
|
|
||||||
|
void appendRule(const Rule &rule);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_settingsFile;
|
QString m_settingsFile;
|
||||||
QList<Rule> m_rules;
|
QList<RuleId> m_ruleIds; // Keeping a list of RuleIds to keep sorting order...
|
||||||
|
QHash<RuleId, Rule> m_rules; // ...but use a Hash for faster finding
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RULEENGINE_H
|
#endif // RULEENGINE_H
|
||||||
|
|||||||
@ -99,6 +99,29 @@ bool StateEvaluator::evaluate() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StateEvaluator::containsDevice(const DeviceId &deviceId) const
|
||||||
|
{
|
||||||
|
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
foreach (const StateEvaluator &childEvaluator, m_childEvaluators) {
|
||||||
|
if (childEvaluator.containsDevice(deviceId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateEvaluator::removeDevice(const DeviceId &deviceId)
|
||||||
|
{
|
||||||
|
if (m_stateDescriptor.deviceId() == deviceId) {
|
||||||
|
m_stateDescriptor = StateDescriptor();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_childEvaluators.count(); i++) {
|
||||||
|
m_childEvaluators[i].removeDevice(deviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StateEvaluator::dumpToSettings(QSettings &settings, const QString &groupName) const
|
void StateEvaluator::dumpToSettings(QSettings &settings, const QString &groupName) const
|
||||||
{
|
{
|
||||||
settings.beginGroup(groupName);
|
settings.beginGroup(groupName);
|
||||||
|
|||||||
@ -45,6 +45,9 @@ public:
|
|||||||
void setOperatorType(StateOperator operatorType);
|
void setOperatorType(StateOperator operatorType);
|
||||||
|
|
||||||
bool evaluate() const;
|
bool evaluate() const;
|
||||||
|
bool containsDevice(const DeviceId &deviceId) const;
|
||||||
|
|
||||||
|
void removeDevice(const DeviceId &deviceId);
|
||||||
|
|
||||||
void dumpToSettings(QSettings &settings, const QString &groupName) const;
|
void dumpToSettings(QSettings &settings, const QString &groupName) const;
|
||||||
static StateEvaluator loadFromSettings(QSettings &settings, const QString &groupPrefix);
|
static StateEvaluator loadFromSettings(QSettings &settings, const QString &groupPrefix);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
2
|
3
|
||||||
{
|
{
|
||||||
"methods": {
|
"methods": {
|
||||||
"Actions.ExecuteAction": {
|
"Actions.ExecuteAction": {
|
||||||
@ -194,7 +194,13 @@
|
|||||||
"Devices.RemoveConfiguredDevice": {
|
"Devices.RemoveConfiguredDevice": {
|
||||||
"description": "Remove a device from the system.",
|
"description": "Remove a device from the system.",
|
||||||
"params": {
|
"params": {
|
||||||
"deviceId": "uuid"
|
"deviceId": "uuid",
|
||||||
|
"o:removePolicyList": [
|
||||||
|
{
|
||||||
|
"policy": "$ref:RemovePolicyType",
|
||||||
|
"ruleId": "uuid"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"returns": {
|
"returns": {
|
||||||
"errorMessage": "string",
|
"errorMessage": "string",
|
||||||
@ -261,13 +267,33 @@
|
|||||||
"success": "bool"
|
"success": "bool"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Rules.FindRules": {
|
||||||
|
"description": "Find a list of rules containing any of the given parameters.",
|
||||||
|
"params": {
|
||||||
|
"deviceId": "uuid"
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"ruleIds": [
|
||||||
|
"uuid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Rules.GetRuleDetails": {
|
||||||
|
"description": "Get details for the rule identified by ruleId",
|
||||||
|
"params": {
|
||||||
|
"ruleId": "uuid"
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"rule": "$ref:Rule"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Rules.GetRules": {
|
"Rules.GetRules": {
|
||||||
"description": "Get all configured rules",
|
"description": "Get all configured rules",
|
||||||
"params": {
|
"params": {
|
||||||
},
|
},
|
||||||
"returns": {
|
"returns": {
|
||||||
"rules": [
|
"ruleIds": [
|
||||||
"$ref:Rule"
|
"uuid"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -405,6 +431,10 @@
|
|||||||
"$ref:Param"
|
"$ref:Param"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"RemovePolicyType": [
|
||||||
|
"RemovePolicyCascade",
|
||||||
|
"RemovePolicyUpdate"
|
||||||
|
],
|
||||||
"Rule": {
|
"Rule": {
|
||||||
"actions": [
|
"actions": [
|
||||||
"$ref:Action"
|
"$ref:Action"
|
||||||
|
|||||||
@ -142,7 +142,7 @@ void TestRules::addRemoveRules()
|
|||||||
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
RuleId newRuleId = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
||||||
|
|
||||||
response = injectAndWait("Rules.GetRules");
|
response = injectAndWait("Rules.GetRules");
|
||||||
QVariantList rules = response.toMap().value("params").toMap().value("rules").toList();
|
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
QVERIFY2(rules.count() == 0, "There should be no rules.");
|
QVERIFY2(rules.count() == 0, "There should be no rules.");
|
||||||
@ -150,10 +150,16 @@ void TestRules::addRemoveRules()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
||||||
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
|
QCOMPARE(RuleId(rules.first().toString()), newRuleId);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("ruleId", newRuleId);
|
||||||
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
||||||
|
// verifySuccess(response);
|
||||||
|
|
||||||
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
|
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
||||||
|
|
||||||
|
QVariantList eventDescriptors = rule.value("eventDescriptors").toList();
|
||||||
if (!eventDescriptor.isEmpty()) {
|
if (!eventDescriptor.isEmpty()) {
|
||||||
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
|
QVERIFY2(eventDescriptors.count() == 1, "There shoud be exactly one eventDescriptor");
|
||||||
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor, "Event descriptor doesn't match");
|
QVERIFY2(eventDescriptors.first().toMap() == eventDescriptor, "Event descriptor doesn't match");
|
||||||
@ -172,7 +178,7 @@ void TestRules::addRemoveRules()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList replyActions = rules.first().toMap().value("actions").toList();
|
QVariantList replyActions = rule.value("actions").toList();
|
||||||
QVERIFY2(actions == replyActions, "Actions don't match");
|
QVERIFY2(actions == replyActions, "Actions don't match");
|
||||||
|
|
||||||
|
|
||||||
@ -251,12 +257,18 @@ void TestRules::loadStoreConfig()
|
|||||||
|
|
||||||
response = injectAndWait("Rules.GetRules");
|
response = injectAndWait("Rules.GetRules");
|
||||||
|
|
||||||
QVariantList rules = response.toMap().value("params").toMap().value("rules").toList();
|
QVariantList rules = response.toMap().value("params").toMap().value("ruleIds").toList();
|
||||||
|
|
||||||
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
QVERIFY2(rules.count() == 1, "There should be exactly one rule");
|
||||||
QCOMPARE(RuleId(rules.first().toMap().value("id").toString()), newRuleId);
|
QCOMPARE(RuleId(rules.first().toString()), newRuleId);
|
||||||
|
|
||||||
QVariantList eventDescriptors = rules.first().toMap().value("eventDescriptors").toList();
|
params.clear();
|
||||||
|
params.insert("ruleId", rules.first().toString());
|
||||||
|
response = injectAndWait("Rules.GetRuleDetails", params);
|
||||||
|
|
||||||
|
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
||||||
|
|
||||||
|
QVariantList eventDescriptors = rule.value("eventDescriptors").toList();
|
||||||
QVERIFY2(eventDescriptors.count() == 2, "There shoud be exactly 2 eventDescriptors");
|
QVERIFY2(eventDescriptors.count() == 2, "There shoud be exactly 2 eventDescriptors");
|
||||||
foreach (const QVariant &expectedEventDescriptorVariant, eventDescriptorList) {
|
foreach (const QVariant &expectedEventDescriptorVariant, eventDescriptorList) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -270,7 +282,7 @@ void TestRules::loadStoreConfig()
|
|||||||
QVERIFY2(found, "missing eventdescriptor");
|
QVERIFY2(found, "missing eventdescriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList replyActions = rules.first().toMap().value("actions").toList();
|
QVariantList replyActions = rule.value("actions").toList();
|
||||||
foreach (const QVariant &actionVariant, actions) {
|
foreach (const QVariant &actionVariant, actions) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach (const QVariant &replyActionVariant, replyActions) {
|
foreach (const QVariant &replyActionVariant, replyActions) {
|
||||||
|
|||||||
Reference in New Issue
Block a user