parent
66f4a361a1
commit
5cd3154b64
@ -183,9 +183,9 @@ Rule GuhCore::findRule(const RuleId &ruleId)
|
|||||||
return m_ruleEngine->findRule(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, bool enabled)
|
||||||
{
|
{
|
||||||
return m_ruleEngine->addRule(id, eventDescriptorList, actionList);
|
return m_ruleEngine->addRule(id, eventDescriptorList, actionList, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
RuleEngine::RuleError GuhCore::removeRule(const RuleId &id)
|
RuleEngine::RuleError GuhCore::removeRule(const RuleId &id)
|
||||||
@ -198,6 +198,16 @@ QList<RuleId> GuhCore::findRules(const DeviceId &deviceId)
|
|||||||
return m_ruleEngine->findRules(deviceId);
|
return m_ruleEngine->findRules(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RuleEngine::RuleError GuhCore::enableRule(const RuleId &ruleId)
|
||||||
|
{
|
||||||
|
return m_ruleEngine->enableRule(ruleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleEngine::RuleError GuhCore::disableRule(const RuleId &ruleId)
|
||||||
|
{
|
||||||
|
return m_ruleEngine->disableRule(ruleId);
|
||||||
|
}
|
||||||
|
|
||||||
/*! 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
|
||||||
{
|
{
|
||||||
|
|||||||
@ -66,9 +66,11 @@ public:
|
|||||||
QList<Rule> rules() const;
|
QList<Rule> rules() const;
|
||||||
QList<RuleId> ruleIds() const;
|
QList<RuleId> ruleIds() const;
|
||||||
Rule findRule(const RuleId &ruleId);
|
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, bool enabled = true);
|
||||||
RuleEngine::RuleError removeRule(const RuleId &id);
|
RuleEngine::RuleError removeRule(const RuleId &id);
|
||||||
QList<RuleId> findRules(const DeviceId &deviceId);
|
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||||
|
RuleEngine::RuleError enableRule(const RuleId &ruleId);
|
||||||
|
RuleEngine::RuleError disableRule(const RuleId &ruleId);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void eventTriggered(const Event &event);
|
void eventTriggered(const Event &event);
|
||||||
|
|||||||
@ -139,6 +139,13 @@ QVariantMap JsonHandler::statusToReply(DeviceManager::DeviceError status) const
|
|||||||
return returns;
|
return returns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap JsonHandler::statusToReply(RuleEngine::RuleError status) const
|
||||||
|
{
|
||||||
|
QVariantMap returns;
|
||||||
|
returns.insert("ruleError", JsonTypes::ruleErrorToString(status));
|
||||||
|
return returns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JsonReply::JsonReply(Type type, JsonHandler *handler, const QString &method, const QVariantMap &data):
|
JsonReply::JsonReply(Type type, JsonHandler *handler, const QString &method, const QVariantMap &data):
|
||||||
m_type(type),
|
m_type(type),
|
||||||
|
|||||||
@ -104,6 +104,7 @@ protected:
|
|||||||
JsonReply *createReply(const QVariantMap &data) const;
|
JsonReply *createReply(const QVariantMap &data) const;
|
||||||
JsonReply *createAsyncReply(const QString &method) const;
|
JsonReply *createAsyncReply(const QString &method) const;
|
||||||
QVariantMap statusToReply(DeviceManager::DeviceError status) const;
|
QVariantMap statusToReply(DeviceManager::DeviceError status) const;
|
||||||
|
QVariantMap statusToReply(RuleEngine::RuleError status) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QString, QString> m_descriptions;
|
QHash<QString, QString> m_descriptions;
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#define JSON_PROTOCOL_VERSION 9
|
#define JSON_PROTOCOL_VERSION 10
|
||||||
|
|
||||||
JsonRPCServer::JsonRPCServer(QObject *parent):
|
JsonRPCServer::JsonRPCServer(QObject *parent):
|
||||||
JsonHandler(parent),
|
JsonHandler(parent),
|
||||||
|
|||||||
@ -169,6 +169,7 @@ void JsonTypes::init()
|
|||||||
|
|
||||||
// Rule
|
// Rule
|
||||||
s_rule.insert("id", basicTypeToString(Uuid));
|
s_rule.insert("id", basicTypeToString(Uuid));
|
||||||
|
s_rule.insert("enabled", basicTypeToString(Bool));
|
||||||
s_rule.insert("eventDescriptors", QVariantList() << eventDescriptorRef());
|
s_rule.insert("eventDescriptors", QVariantList() << eventDescriptorRef());
|
||||||
s_rule.insert("actions", QVariantList() << actionRef());
|
s_rule.insert("actions", QVariantList() << actionRef());
|
||||||
s_rule.insert("stateEvaluator", stateEvaluatorRef());
|
s_rule.insert("stateEvaluator", stateEvaluatorRef());
|
||||||
@ -447,6 +448,7 @@ QVariantMap JsonTypes::packRule(const Rule &rule)
|
|||||||
{
|
{
|
||||||
QVariantMap ruleMap;
|
QVariantMap ruleMap;
|
||||||
ruleMap.insert("id", rule.id());
|
ruleMap.insert("id", rule.id());
|
||||||
|
ruleMap.insert("enabled", rule.enabled());
|
||||||
QVariantList eventDescriptorList;
|
QVariantList eventDescriptorList;
|
||||||
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) {
|
||||||
eventDescriptorList.append(JsonTypes::packEventDescriptor(eventDescriptor));
|
eventDescriptorList.append(JsonTypes::packEventDescriptor(eventDescriptor));
|
||||||
|
|||||||
@ -44,10 +44,12 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||||||
|
|
||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
setDescription("AddRule", "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that only"
|
setDescription("AddRule", "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that only"
|
||||||
"one of either eventDescriptor or eventDescriptorList may be passed at a time.");
|
"one of either eventDescriptor or eventDescriptorList may be passed at a time. A rule can be created but left disabled,"
|
||||||
|
"meaning it won't actually be executed until set to enabled. If not given, enabled defaults to true.");
|
||||||
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef());
|
||||||
params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef());
|
params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef());
|
||||||
params.insert("o:stateEvaluator", JsonTypes::stateEvaluatorRef());
|
params.insert("o:stateEvaluator", JsonTypes::stateEvaluatorRef());
|
||||||
|
params.insert("o:enabled", JsonTypes::basicTypeToString(JsonTypes::Bool));
|
||||||
QVariantList actions;
|
QVariantList actions;
|
||||||
actions.append(JsonTypes::actionRef());
|
actions.append(JsonTypes::actionRef());
|
||||||
params.insert("actions", actions);
|
params.insert("actions", actions);
|
||||||
@ -69,6 +71,20 @@ RulesHandler::RulesHandler(QObject *parent) :
|
|||||||
setParams("FindRules", params);
|
setParams("FindRules", params);
|
||||||
returns.insert("ruleIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
returns.insert("ruleIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||||
setReturns("FindRules", returns);
|
setReturns("FindRules", returns);
|
||||||
|
|
||||||
|
params.clear(); returns.clear();
|
||||||
|
setDescription("EnableRule", "Enabled a rule that has previously been disabled.");
|
||||||
|
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||||
|
setParams("EnableRule", params);
|
||||||
|
returns.insert("ruleError", JsonTypes::ruleErrorRef());
|
||||||
|
setReturns("EnableRule", returns);
|
||||||
|
|
||||||
|
params.clear(); returns.clear();
|
||||||
|
setDescription("DisableRule", "Disable a rule. The rule won't be triggered by it's events or state changes while it is disabled.");
|
||||||
|
params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
|
||||||
|
setParams("DisableRule", params);
|
||||||
|
returns.insert("ruleError", JsonTypes::ruleErrorRef());
|
||||||
|
setReturns("DisableRule", returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RulesHandler::name() const
|
QString RulesHandler::name() const
|
||||||
@ -136,8 +152,10 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
|||||||
return createReply(returns);
|
return createReply(returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool enabled = params.value("enabled", true).toBool();
|
||||||
|
|
||||||
RuleId newRuleId = RuleId::createRuleId();
|
RuleId newRuleId = RuleId::createRuleId();
|
||||||
RuleEngine::RuleError status = GuhCore::instance()->addRule(newRuleId, eventDescriptorList, actions);
|
RuleEngine::RuleError status = GuhCore::instance()->addRule(newRuleId, eventDescriptorList, actions, enabled);
|
||||||
if (status == RuleEngine::RuleErrorNoError) {
|
if (status == RuleEngine::RuleErrorNoError) {
|
||||||
returns.insert("ruleId", newRuleId.toString());
|
returns.insert("ruleId", newRuleId.toString());
|
||||||
}
|
}
|
||||||
@ -168,3 +186,13 @@ JsonReply *RulesHandler::FindRules(const QVariantMap ¶ms)
|
|||||||
returns.insert("ruleIds", rulesList);
|
returns.insert("ruleIds", rulesList);
|
||||||
return createReply(returns);
|
return createReply(returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonReply *RulesHandler::EnableRule(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
return createReply(statusToReply(GuhCore::instance()->enableRule(RuleId(params.value("ruleId").toString()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonReply *RulesHandler::DisableRule(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
return createReply(statusToReply(GuhCore::instance()->disableRule(RuleId(params.value("ruleId").toString()))));
|
||||||
|
}
|
||||||
|
|||||||
@ -36,6 +36,8 @@ public:
|
|||||||
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
Q_INVOKABLE JsonReply* RemoveRule(const QVariantMap ¶ms);
|
||||||
Q_INVOKABLE JsonReply* FindRules(const QVariantMap ¶ms);
|
Q_INVOKABLE JsonReply* FindRules(const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
Q_INVOKABLE JsonReply* EnableRule(const QVariantMap ¶ms);
|
||||||
|
Q_INVOKABLE JsonReply* DisableRule(const QVariantMap ¶ms);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RULESHANDLER_H
|
#endif // RULESHANDLER_H
|
||||||
|
|||||||
@ -86,3 +86,15 @@ QList<Action> Rule::actions() const
|
|||||||
{
|
{
|
||||||
return m_actions;
|
return m_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Returns wheter the rule is enabled or not. */
|
||||||
|
bool Rule::enabled() const {
|
||||||
|
return m_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Set the disabled flag of this rule. In order to actually disable the rule you still need to
|
||||||
|
* update the RulesEngine */
|
||||||
|
void Rule::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_enabled = enabled;
|
||||||
|
}
|
||||||
|
|||||||
@ -37,11 +37,16 @@ public:
|
|||||||
StateEvaluator stateEvaluator() const;
|
StateEvaluator stateEvaluator() const;
|
||||||
QList<Action> actions() const;
|
QList<Action> actions() const;
|
||||||
|
|
||||||
|
bool enabled() const;
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RuleId m_id;
|
RuleId m_id;
|
||||||
QList<EventDescriptor> m_eventDescriptors;
|
QList<EventDescriptor> m_eventDescriptors;
|
||||||
StateEvaluator m_stateEvaluator;
|
StateEvaluator m_stateEvaluator;
|
||||||
QList<Action> m_actions;
|
QList<Action> m_actions;
|
||||||
|
|
||||||
|
bool m_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RULE_H
|
#endif // RULE_H
|
||||||
|
|||||||
@ -79,6 +79,8 @@ RuleEngine::RuleEngine(QObject *parent) :
|
|||||||
|
|
||||||
settings.beginGroup(idString);
|
settings.beginGroup(idString);
|
||||||
|
|
||||||
|
bool enabled = settings.value("enabled", true).toBool();
|
||||||
|
|
||||||
QList<EventDescriptor> eventDescriptorList;
|
QList<EventDescriptor> eventDescriptorList;
|
||||||
settings.beginGroup("events");
|
settings.beginGroup("events");
|
||||||
|
|
||||||
@ -133,6 +135,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);
|
||||||
|
rule.setEnabled(enabled);
|
||||||
appendRule(rule);
|
appendRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +154,11 @@ QList<Action> RuleEngine::evaluateEvent(const Event &event)
|
|||||||
QList<Action> actions;
|
QList<Action> actions;
|
||||||
foreach (const RuleId &id, m_ruleIds) {
|
foreach (const RuleId &id, m_ruleIds) {
|
||||||
Rule rule = m_rules.value(id);
|
Rule rule = m_rules.value(id);
|
||||||
|
if (!rule.enabled()) {
|
||||||
|
qDebug() << "Not triggering rule because it is disabled:" << rule.id();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (containsEvent(rule, event)) {
|
if (containsEvent(rule, event)) {
|
||||||
if (rule.stateEvaluator().evaluate()) {
|
if (rule.stateEvaluator().evaluate()) {
|
||||||
qDebug() << "states matching!";
|
qDebug() << "states matching!";
|
||||||
@ -164,13 +172,13 @@ QList<Action> RuleEngine::evaluateEvent(const Event &event)
|
|||||||
|
|
||||||
/*! Add a new \l{Rule} with the given \a EventDescriptorList and \a actions to the engine.
|
/*! Add a new \l{Rule} with the given \a EventDescriptorList and \a actions to the engine.
|
||||||
For convenience, this creates a Rule without any \l{State} comparison. */
|
For convenience, this creates a Rule without any \l{State} comparison. */
|
||||||
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions)
|
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const QList<Action> &actions, bool enabled)
|
||||||
{
|
{
|
||||||
return addRule(ruleId, eventDescriptorList, StateEvaluator(), actions);
|
return addRule(ruleId, eventDescriptorList, StateEvaluator(), actions, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Add a new \l{Rule} with the given \a event, \a states and \a actions to the engine. */
|
/*! Add a new \l{Rule} with the given \a event, \a states and \a actions to the engine. */
|
||||||
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions)
|
RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<EventDescriptor> &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList<Action> &actions, bool enabled)
|
||||||
{
|
{
|
||||||
if (ruleId.isNull()) {
|
if (ruleId.isNull()) {
|
||||||
return RuleErrorInvalidRuleId;
|
return RuleErrorInvalidRuleId;
|
||||||
@ -220,11 +228,13 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QList<Even
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rule rule = Rule(ruleId, eventDescriptorList, stateEvaluator, actions);
|
Rule rule = Rule(ruleId, eventDescriptorList, stateEvaluator, actions);
|
||||||
|
rule.setEnabled(enabled);
|
||||||
appendRule(rule);
|
appendRule(rule);
|
||||||
emit ruleAdded(rule.id());
|
emit ruleAdded(rule.id());
|
||||||
|
|
||||||
QSettings settings(m_settingsFile);
|
QSettings settings(m_settingsFile);
|
||||||
settings.beginGroup(rule.id().toString());
|
settings.beginGroup(rule.id().toString());
|
||||||
|
settings.setValue("enabled", enabled);
|
||||||
settings.beginGroup("events");
|
settings.beginGroup("events");
|
||||||
for (int i = 0; i < eventDescriptorList.count(); i++) {
|
for (int i = 0; i < eventDescriptorList.count(); i++) {
|
||||||
const EventDescriptor &eventDescriptor = eventDescriptorList.at(i);
|
const EventDescriptor &eventDescriptor = eventDescriptorList.at(i);
|
||||||
@ -300,6 +310,50 @@ RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId)
|
|||||||
return RuleErrorNoError;
|
return RuleErrorNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Enables a rule that has been previously disabled.
|
||||||
|
\sa disableRule */
|
||||||
|
RuleEngine::RuleError RuleEngine::enableRule(const RuleId &ruleId)
|
||||||
|
{
|
||||||
|
if (!m_rules.contains(ruleId)) {
|
||||||
|
qWarning() << "Rule not found. Can't enable it";
|
||||||
|
return RuleErrorRuleNotFound;
|
||||||
|
}
|
||||||
|
Rule rule = m_rules.value(ruleId);
|
||||||
|
rule.setEnabled(true);
|
||||||
|
m_rules[ruleId] = rule;
|
||||||
|
QSettings settings(m_settingsFile);
|
||||||
|
settings.beginGroup(ruleId.toString());
|
||||||
|
if (!settings.value("enabled", true).toBool()) {
|
||||||
|
settings.setValue("enabled", true);
|
||||||
|
emit ruleChanged(ruleId);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
return RuleErrorNoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Disables a rule. Disabled rules won't be triggered.
|
||||||
|
\sa enableRule */
|
||||||
|
RuleEngine::RuleError RuleEngine::disableRule(const RuleId &ruleId)
|
||||||
|
{
|
||||||
|
if (!m_rules.contains(ruleId)) {
|
||||||
|
qWarning() << "Rule not found. Can't disable it";
|
||||||
|
return RuleErrorRuleNotFound;
|
||||||
|
}
|
||||||
|
Rule rule = m_rules.value(ruleId);
|
||||||
|
rule.setEnabled(false);
|
||||||
|
m_rules[ruleId] = rule;
|
||||||
|
QSettings settings(m_settingsFile);
|
||||||
|
settings.beginGroup(ruleId.toString());
|
||||||
|
if (settings.value("enabled", true).toBool()) {
|
||||||
|
settings.setValue("enabled", false);
|
||||||
|
emit ruleChanged(ruleId);
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
|
||||||
|
return RuleErrorNoError;
|
||||||
|
}
|
||||||
|
|
||||||
Rule RuleEngine::findRule(const RuleId &ruleId)
|
Rule RuleEngine::findRule(const RuleId &ruleId)
|
||||||
{
|
{
|
||||||
foreach (const Rule &rule, m_rules) {
|
foreach (const Rule &rule, m_rules) {
|
||||||
|
|||||||
@ -53,13 +53,16 @@ public:
|
|||||||
|
|
||||||
QList<Action> evaluateEvent(const Event &event);
|
QList<Action> evaluateEvent(const Event &event);
|
||||||
|
|
||||||
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, bool enabled = true);
|
||||||
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, bool enabled = true);
|
||||||
QList<Rule> rules() const;
|
QList<Rule> rules() const;
|
||||||
QList<RuleId> ruleIds() const;
|
QList<RuleId> ruleIds() const;
|
||||||
|
|
||||||
RuleError removeRule(const RuleId &ruleId);
|
RuleError removeRule(const RuleId &ruleId);
|
||||||
|
|
||||||
|
RuleError enableRule(const RuleId &ruleId);
|
||||||
|
RuleError disableRule(const RuleId &ruleId);
|
||||||
|
|
||||||
Rule findRule(const RuleId &ruleId);
|
Rule findRule(const RuleId &ruleId);
|
||||||
QList<RuleId> findRules(const DeviceId &deviceId);
|
QList<RuleId> findRules(const DeviceId &deviceId);
|
||||||
|
|
||||||
@ -68,6 +71,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void ruleAdded(const RuleId &ruleId);
|
void ruleAdded(const RuleId &ruleId);
|
||||||
void ruleRemoved(const RuleId &ruleId);
|
void ruleRemoved(const RuleId &ruleId);
|
||||||
|
void ruleChanged(const RuleId &ruleId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool containsEvent(const Rule &rule, const Event &event);
|
bool containsEvent(const Rule &rule, const Event &event);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
9
|
10
|
||||||
{
|
{
|
||||||
"methods": {
|
"methods": {
|
||||||
"Actions.ExecuteAction": {
|
"Actions.ExecuteAction": {
|
||||||
@ -263,11 +263,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Rules.AddRule": {
|
"Rules.AddRule": {
|
||||||
"description": "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that onlyone of either eventDescriptor or eventDescriptorList may be passed at a time.",
|
"description": "Add a rule. You can describe rules by one or many EventDesciptors and a StateEvaluator. Note that onlyone of either eventDescriptor or eventDescriptorList may be passed at a time. A rule can be created but left disabled,meaning it won't actually be executed until set to enabled. If not given, enabled defaults to true.",
|
||||||
"params": {
|
"params": {
|
||||||
"actions": [
|
"actions": [
|
||||||
"$ref:Action"
|
"$ref:Action"
|
||||||
],
|
],
|
||||||
|
"o:enabled": "Bool",
|
||||||
"o:eventDescriptor": "$ref:EventDescriptor",
|
"o:eventDescriptor": "$ref:EventDescriptor",
|
||||||
"o:eventDescriptorList": [
|
"o:eventDescriptorList": [
|
||||||
"$ref:EventDescriptor"
|
"$ref:EventDescriptor"
|
||||||
@ -279,6 +280,24 @@
|
|||||||
"ruleError": "$ref:RuleError"
|
"ruleError": "$ref:RuleError"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Rules.DisableRule": {
|
||||||
|
"description": "Disable a rule. The rule won't be triggered by it's events or state changes while it is disabled.",
|
||||||
|
"params": {
|
||||||
|
"ruleId": "Uuid"
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"ruleError": "$ref:RuleError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Rules.EnableRule": {
|
||||||
|
"description": "Enabled a rule that has previously been disabled.",
|
||||||
|
"params": {
|
||||||
|
"ruleId": "Uuid"
|
||||||
|
},
|
||||||
|
"returns": {
|
||||||
|
"ruleError": "$ref:RuleError"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Rules.FindRules": {
|
"Rules.FindRules": {
|
||||||
"description": "Find a list of rules containing any of the given parameters.",
|
"description": "Find a list of rules containing any of the given parameters.",
|
||||||
"params": {
|
"params": {
|
||||||
@ -478,6 +497,7 @@
|
|||||||
"actions": [
|
"actions": [
|
||||||
"$ref:Action"
|
"$ref:Action"
|
||||||
],
|
],
|
||||||
|
"enabled": "Bool",
|
||||||
"eventDescriptors": [
|
"eventDescriptors": [
|
||||||
"$ref:EventDescriptor"
|
"$ref:EventDescriptor"
|
||||||
],
|
],
|
||||||
|
|||||||
@ -33,7 +33,14 @@ class TestRules: public GuhTestBase
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
void cleanupMockHistory();
|
||||||
|
void cleanupRules();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
void addRemoveRules_data();
|
void addRemoveRules_data();
|
||||||
void addRemoveRules();
|
void addRemoveRules();
|
||||||
|
|
||||||
@ -48,8 +55,34 @@ private slots:
|
|||||||
|
|
||||||
void testStateEvaluator2_data();
|
void testStateEvaluator2_data();
|
||||||
void testStateEvaluator2();
|
void testStateEvaluator2();
|
||||||
|
|
||||||
|
void enableDisableRule();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TestRules::cleanupMockHistory() {
|
||||||
|
QNetworkAccessManager nam;
|
||||||
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||||
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/clearactionhistory").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||||
|
QNetworkReply *reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestRules::cleanupRules() {
|
||||||
|
QVariant response = injectAndWait("Rules.GetRules");
|
||||||
|
foreach (const QVariant &ruleId, response.toMap().value("params").toMap().value("ruleIds").toList()) {
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("ruleId", ruleId.toString());
|
||||||
|
verifyRuleError(injectAndWait("Rules.RemoveRule", params));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestRules::cleanup() {
|
||||||
|
cleanupMockHistory();
|
||||||
|
cleanupRules();
|
||||||
|
}
|
||||||
|
|
||||||
void TestRules::addRemoveRules_data()
|
void TestRules::addRemoveRules_data()
|
||||||
{
|
{
|
||||||
QVariantMap validActionNoParams;
|
QVariantMap validActionNoParams;
|
||||||
@ -100,6 +133,7 @@ void TestRules::addRemoveRules_data()
|
|||||||
invalidEventDescriptor.insert("deviceId", DeviceId());
|
invalidEventDescriptor.insert("deviceId", DeviceId());
|
||||||
invalidEventDescriptor.insert("paramDescriptors", QVariantList());
|
invalidEventDescriptor.insert("paramDescriptors", QVariantList());
|
||||||
|
|
||||||
|
QTest::addColumn<bool>("enabled");
|
||||||
QTest::addColumn<QVariantMap>("action1");
|
QTest::addColumn<QVariantMap>("action1");
|
||||||
QTest::addColumn<QVariantMap>("eventDescriptor");
|
QTest::addColumn<QVariantMap>("eventDescriptor");
|
||||||
QTest::addColumn<QVariantList>("eventDescriptorList");
|
QTest::addColumn<QVariantList>("eventDescriptorList");
|
||||||
@ -107,17 +141,19 @@ void TestRules::addRemoveRules_data()
|
|||||||
QTest::addColumn<RuleEngine::RuleError>("error");
|
QTest::addColumn<RuleEngine::RuleError>("error");
|
||||||
|
|
||||||
|
|
||||||
QTest::newRow("valid rule. 1 EventDescriptor, StateEvaluator, 1 Action") << validActionNoParams << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError;
|
QTest::newRow("valid rule. 1 EventDescriptor, StateEvaluator, 1 Action, enabled") << true << validActionNoParams << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError;
|
||||||
QTest::newRow("valid rule. 2 EventDescriptors, 1 Action") << validActionNoParams << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError;
|
QTest::newRow("valid rule. 1 EventDescriptor, StateEvaluator, 1 Action, diabled") << false << validActionNoParams << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError;
|
||||||
QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << validActionNoParams << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter;
|
QTest::newRow("valid rule. 2 EventDescriptors, 1 Action") << true << validActionNoParams << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError;
|
||||||
QTest::newRow("invalid action") << invalidAction << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound;
|
QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter;
|
||||||
QTest::newRow("invalid event descriptor") << validActionNoParams << invalidEventDescriptor << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorDeviceNotFound;
|
QTest::newRow("invalid action") << true << invalidAction << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound;
|
||||||
|
QTest::newRow("invalid event descriptor") <<true << validActionNoParams << invalidEventDescriptor << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorDeviceNotFound;
|
||||||
// QTest::newRow("invalid state evaluator") << validActionNoParams << invalidEventDescriptor << QVariantList() << invalidStateEvaluator << false;
|
// QTest::newRow("invalid state evaluator") << validActionNoParams << invalidEventDescriptor << QVariantList() << invalidStateEvaluator << false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRules::addRemoveRules()
|
void TestRules::addRemoveRules()
|
||||||
{
|
{
|
||||||
|
QFETCH(bool, enabled);
|
||||||
QFETCH(QVariantMap, action1);
|
QFETCH(QVariantMap, action1);
|
||||||
QFETCH(QVariantMap, eventDescriptor);
|
QFETCH(QVariantMap, eventDescriptor);
|
||||||
QFETCH(QVariantList, eventDescriptorList);
|
QFETCH(QVariantList, eventDescriptorList);
|
||||||
@ -136,6 +172,9 @@ void TestRules::addRemoveRules()
|
|||||||
params.insert("eventDescriptorList", eventDescriptorList);
|
params.insert("eventDescriptorList", eventDescriptorList);
|
||||||
}
|
}
|
||||||
params.insert("stateEvaluator", stateEvaluator);
|
params.insert("stateEvaluator", stateEvaluator);
|
||||||
|
if (!enabled) {
|
||||||
|
params.insert("enabled", enabled);
|
||||||
|
}
|
||||||
QVariant response = injectAndWait("Rules.AddRule", params);
|
QVariant response = injectAndWait("Rules.AddRule", params);
|
||||||
verifyRuleError(response, error);
|
verifyRuleError(response, error);
|
||||||
|
|
||||||
@ -159,6 +198,7 @@ void TestRules::addRemoveRules()
|
|||||||
|
|
||||||
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
QVariantMap rule = response.toMap().value("params").toMap().value("rule").toMap();
|
||||||
|
|
||||||
|
QVERIFY2(rule.value("enabled").toBool() == enabled, "Rule enabled state doesn't match");
|
||||||
QVariantList eventDescriptors = rule.value("eventDescriptors").toList();
|
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");
|
||||||
@ -443,5 +483,107 @@ void TestRules::testStateEvaluator2()
|
|||||||
QVERIFY2(mainEvaluator.evaluate() == shouldMatch, shouldMatch ? "State should match" : "State shouldn't match");
|
QVERIFY2(mainEvaluator.evaluate() == shouldMatch, shouldMatch ? "State should match" : "State shouldn't match");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestRules::enableDisableRule()
|
||||||
|
{
|
||||||
|
// Add a rule
|
||||||
|
QVariantMap addRuleParams;
|
||||||
|
QVariantList events;
|
||||||
|
QVariantMap event1;
|
||||||
|
event1.insert("eventTypeId", mockEvent1Id);
|
||||||
|
event1.insert("deviceId", m_mockDeviceId);
|
||||||
|
events.append(event1);
|
||||||
|
addRuleParams.insert("eventDescriptorList", events);
|
||||||
|
|
||||||
|
QVariantList actions;
|
||||||
|
QVariantMap action;
|
||||||
|
action.insert("actionTypeId", mockActionIdNoParams);
|
||||||
|
action.insert("deviceId", m_mockDeviceId);
|
||||||
|
actions.append(action);
|
||||||
|
addRuleParams.insert("actions", actions);
|
||||||
|
QVariant response = injectAndWait("Rules.AddRule", addRuleParams);
|
||||||
|
verifyRuleError(response);
|
||||||
|
RuleId id = RuleId(response.toMap().value("params").toMap().value("ruleId").toString());
|
||||||
|
|
||||||
|
// Trigger an event
|
||||||
|
QNetworkAccessManager nam;
|
||||||
|
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||||
|
|
||||||
|
// trigger event in mock device
|
||||||
|
QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||||
|
QNetworkReply *reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
// Verify rule got executed
|
||||||
|
spy.clear();
|
||||||
|
request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port)));
|
||||||
|
reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
|
||||||
|
QByteArray actionHistory = reply->readAll();
|
||||||
|
qDebug() << "have action history" << actionHistory;
|
||||||
|
QVERIFY2(mockActionIdNoParams == ActionTypeId(actionHistory), "Action not triggered");
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
cleanupMockHistory();
|
||||||
|
|
||||||
|
// Now disable the rule
|
||||||
|
QVariantMap disableParams;
|
||||||
|
disableParams.insert("ruleId", id.toString());
|
||||||
|
response = injectAndWait("Rules.DisableRule", disableParams);
|
||||||
|
verifyRuleError(response);
|
||||||
|
|
||||||
|
|
||||||
|
// trigger event in mock device
|
||||||
|
spy.clear();
|
||||||
|
request = QNetworkRequest(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||||
|
reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
// Verify rule got *NOT* executed
|
||||||
|
spy.clear();
|
||||||
|
request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port)));
|
||||||
|
reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
|
||||||
|
actionHistory = reply->readAll();
|
||||||
|
qDebug() << "have action history" << actionHistory;
|
||||||
|
QVERIFY2(actionHistory.isEmpty(), "Action is triggered while rule is disabled");
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
cleanupMockHistory();
|
||||||
|
|
||||||
|
// Now enable the rule again
|
||||||
|
response = injectAndWait("Rules.EnableRule", disableParams);
|
||||||
|
verifyRuleError(response);
|
||||||
|
|
||||||
|
|
||||||
|
// trigger event in mock device
|
||||||
|
spy.clear();
|
||||||
|
request = QNetworkRequest(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||||
|
reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
// Verify rule got executed
|
||||||
|
spy.clear();
|
||||||
|
request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockDevice1Port)));
|
||||||
|
reply = nam.get(request);
|
||||||
|
spy.wait();
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
|
||||||
|
actionHistory = reply->readAll();
|
||||||
|
qDebug() << "have action history" << actionHistory;
|
||||||
|
QVERIFY2(mockActionIdNoParams == ActionTypeId(actionHistory), "Action not triggered");
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#include "testrules.moc"
|
#include "testrules.moc"
|
||||||
QTEST_MAIN(TestRules)
|
QTEST_MAIN(TestRules)
|
||||||
|
|||||||
Reference in New Issue
Block a user