diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index 78b3fec4..ddbabfc9 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -148,7 +148,7 @@ void JsonTypes::init() s_param.insert("value", basicTypeRef()); // RuleAction - s_ruleAction.insert(" actionTypeId", basicTypeToString(Uuid)); + s_ruleAction.insert("actionTypeId", basicTypeToString(Uuid)); s_ruleAction.insert("deviceId", basicTypeToString(Uuid)); s_ruleAction.insert("o:ruleActionParams", QVariantList() << ruleActionParamRef()); @@ -265,6 +265,7 @@ void JsonTypes::init() s_rule.insert("actions", QVariantList() << ruleActionRef()); s_rule.insert("exitActions", QVariantList() << ruleActionRef()); s_rule.insert("stateEvaluator", stateEvaluatorRef()); + s_rule.insert("timeDescriptor", timeDescriptorRef()); // RuleDescription s_ruleDescription.insert("id", basicTypeToString(Uuid)); @@ -531,7 +532,6 @@ QVariantMap JsonTypes::packStateEvaluator(const StateEvaluator &stateEvaluator) foreach (const StateEvaluator &childEvaluator, stateEvaluator.childEvaluators()) { childEvaluators.append(packStateEvaluator(childEvaluator)); } - qCDebug(dcJsonRpc) << "state operator:" << stateOperator() << stateEvaluator.operatorType(); variantMap.insert("operator", stateOperator().at(stateEvaluator.operatorType())); if (childEvaluators.count() > 0) { variantMap.insert("childEvaluators", childEvaluators); @@ -702,6 +702,7 @@ QVariantMap JsonTypes::packRule(const Rule &rule) ruleMap.insert("enabled", rule.enabled()); ruleMap.insert("active", rule.active()); ruleMap.insert("executable", rule.executable()); + ruleMap.insert("timeDescriptor", JsonTypes::packTimeDescriptor(rule.timeDescriptor())); QVariantList eventDescriptorList; foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) { @@ -870,8 +871,10 @@ QVariantMap JsonTypes::packTimeDescriptor(const TimeDescriptor &timeDescriptor) foreach (const CalendarItem &calendarItem, timeDescriptor.calendarItems()) { calendarItems.append(packCalendarItem(calendarItem)); } + timeDescriptorVariant.insert("calendarItems", calendarItems); } + // TODO: TimeEventItems return timeDescriptorVariant; @@ -1047,6 +1050,68 @@ ParamList JsonTypes::unpackParams(const QVariantList ¶mList) return params; } +Rule JsonTypes::unpackRule(const QVariantMap &ruleMap) +{ + // The rule id will only be valid if unpacking for edit + RuleId ruleId = RuleId(ruleMap.value("ruleId").toString()); + + QString name = ruleMap.value("name", QString()).toString(); + + // By default enabled + bool enabled = ruleMap.value("enabled", true).toBool(); + + // By default executable + bool executable = ruleMap.value("executable", true).toBool(); + + StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(ruleMap.value("stateEvaluator").toMap()); + TimeDescriptor timeDescriptor = JsonTypes::unpackTimeDescriptor(ruleMap.value("timeDescriptor").toMap()); + + QList eventDescriptors; + if (ruleMap.contains("eventDescriptors")) { + QVariantList eventDescriptorVariantList = ruleMap.value("eventDescriptors").toList(); + qCDebug(dcJsonRpc) << "unpacking eventDescriptors:" << eventDescriptorVariantList; + foreach (const QVariant &eventDescriptorVariant, eventDescriptorVariantList) { + eventDescriptors.append(JsonTypes::unpackEventDescriptor(eventDescriptorVariant.toMap())); + } + } + + QList actions; + if (ruleMap.contains("actions")) { + QVariantList actionsVariantList = ruleMap.value("actions").toList(); + foreach (const QVariant &actionVariant, actionsVariantList) { + actions.append(JsonTypes::unpackRuleAction(actionVariant.toMap())); + } + } + + QList exitActions; + if (ruleMap.contains("exitActions")) { + QVariantList exitActionsVariantList = ruleMap.value("exitActions").toList(); + foreach (const QVariant &exitActionVariant, exitActionsVariantList) { + exitActions.append(JsonTypes::unpackRuleAction(exitActionVariant.toMap())); + } + } + + Rule rule; + rule.setId(ruleId); + rule.setName(name); + rule.setTimeDescriptor(timeDescriptor); + rule.setStateEvaluator(stateEvaluator); + rule.setEventDescriptors(eventDescriptors); + rule.setActions(actions); + rule.setExitActions(exitActions); + rule.setEnabled(enabled); + rule.setExecutable(executable); + return rule; +} + +RuleAction JsonTypes::unpackRuleAction(const QVariantMap &ruleActionMap) +{ + RuleAction action(ActionTypeId(ruleActionMap.value("actionTypeId").toString()), DeviceId(ruleActionMap.value("deviceId").toString())); + RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(ruleActionMap.value("ruleActionParams").toList()); + action.setRuleActionParams(actionParamList); + return action; +} + /*! Returns a \l{RuleActionParam} created from the given \a ruleActionParamMap. */ RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionParamMap) { @@ -1485,6 +1550,30 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qCWarning(dcJsonRpc) << "LogEntry not matching"; return result; } + } else if (refName == timeDescriptorRef()) { + QPair result = validateMap(timeDescriptorDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "TimeDescriptor not matching"; + return result; + } + } else if (refName == calendarItemRef()) { + QPair result = validateMap(calendarItemDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "CalendarItem not matching"; + return result; + } + } else if (refName == timeDescriptorRef()) { + QPair result = validateMap(timeEventItemDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "TimeEventItem not matching"; + return result; + } + } else if (refName == repeatingOptionRef()) { + QPair result = validateMap(repeatingOptionDescription(), variant.toMap()); + if (!result.first) { + qCWarning(dcJsonRpc) << "RepeatingOption not matching"; + return result; + } } else if (refName == basicTypeRef()) { QPair result = validateBasicType(variant); if (!result.first) { @@ -1575,6 +1664,12 @@ QPair JsonTypes::validateVariant(const QVariant &templateVariant, qCWarning(dcJsonRpc) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(deviceIconRef()); return result; } + } else if (refName == repeatingModeRef()) { + QPair result = validateEnum(s_repeatingMode, variant); + if (!result.first) { + qCWarning(dcJsonRpc) << QString("Value %1 not allowed in %2").arg(variant.toString()).arg(repeatingModeRef()); + return result; + } } else { Q_ASSERT_X(false, "JsonTypes", QString("Unhandled ref: %1").arg(refName).toLatin1().data()); return report(false, QString("Unhandled ref %1. Server implementation incomplete.").arg(refName)); @@ -1640,180 +1735,6 @@ QPair JsonTypes::validateBasicType(const QVariant &variant) return report(false, QString("Error validating basic type %1.").arg(variant.toString())); } -/*! Returns the type of the \l{Param} with the given \a paramName of the \l{ActionType} with the given \a actionTypeId. */ -QVariant::Type JsonTypes::getActionParamType(const ActionTypeId &actionTypeId, const QString ¶mName) -{ - foreach (const DeviceClass &deviceClass, GuhCore::instance()->deviceManager()->supportedDevices()) { - foreach (const ActionType &actionType, deviceClass.actionTypes()) { - if (actionType.id() == actionTypeId) { - foreach (const ParamType ¶mType, actionType.paramTypes()) { - if (paramType.name() == paramName) { - return paramType.type(); - } - } - } - } - } - return QVariant::Invalid; -} - -/*! Returns the type of the \l{Param} with the given \a paramName of the \l{EventType} with the given \a eventTypeId. */ -QVariant::Type JsonTypes::getEventParamType(const EventTypeId &eventTypeId, const QString ¶mName) -{ - foreach (const DeviceClass &deviceClass, GuhCore::instance()->deviceManager()->supportedDevices()) { - foreach (const EventType &eventType, deviceClass.eventTypes()) { - if (eventType.id() == eventTypeId) { - foreach (const ParamType ¶mType, eventType.paramTypes()) { - // get ParamType of Event - if (paramType.name() == paramName) { - return paramType.type(); - } - } - } - } - } - return QVariant::Invalid; -} - -/*! Returns true if the given \a eventTypeId is in the given \a eventDescriptors.*/ -bool JsonTypes::checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId) -{ - foreach (const EventDescriptor eventDescriptor, eventDescriptors) { - if (eventDescriptor.eventTypeId() == eventTypeId) { - return true; - } - } - return false; -} - -/*! Verifies if the given \a params contain a valid rule. Returns \l{RuleEngine::RuleError} to inform about the result.*/ -RuleEngine::RuleError JsonTypes::verifyRuleConsistency(const QVariantMap ¶ms) -{ - // check if there are an eventDescriptor and an eventDescriptorList - if (params.contains("eventDescriptor") && params.contains("eventDescriptorList")) { - qCWarning(dcJsonRpc) << "Only one of eventDesciptor or eventDescriptorList may be used."; - return RuleEngine::RuleErrorInvalidParameter; - } - - // check if this rules is based on any event and contains exit actions - if (params.contains("eventDescriptor") || params.contains("eventDescriptorList")) { - if (params.contains("exitActions")) { - qCWarning(dcJsonRpc) << "The exitActions will never be executed if the rule contains an eventDescriptor."; - return RuleEngine::RuleErrorInvalidRuleFormat; - } - } - - // check if there are any actions - if (params.value("actions").toList().isEmpty()) { - qCWarning(dcJsonRpc) << "Rule actions missing. A rule without actions has no effect."; - return RuleEngine::RuleErrorMissingParameter; - } - - // TODO: check if events and stateEvaluators are missing - - return RuleEngine::RuleErrorNoError; -} - -/*! Verifies if the given \a params contain a valid rule. Returns \l{RuleEngine::RuleError} to inform about the result.*/ -QPair, RuleEngine::RuleError> JsonTypes::verifyEventDescriptors(const QVariantMap ¶ms) -{ - // Check and unpack eventDescriptors - QList eventDescriptorList = QList(); - if (params.contains("eventDescriptor")) { - QVariantMap eventMap = params.value("eventDescriptor").toMap(); - qCDebug(dcJsonRpc) << "unpacking eventDescriptor" << eventMap; - eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap)); - } else if (params.contains("eventDescriptorList")) { - QVariantList eventDescriptors = params.value("eventDescriptorList").toList(); - qCDebug(dcJsonRpc) << "unpacking eventDescriptorList:" << eventDescriptors; - foreach (const QVariant &eventVariant, eventDescriptors) { - QVariantMap eventMap = eventVariant.toMap(); - eventDescriptorList.append(JsonTypes::unpackEventDescriptor(eventMap)); - } - } - return QPair, RuleEngine::RuleError>(eventDescriptorList, RuleEngine::RuleErrorNoError); -} - -/*! Verifies if the given \a eventDescriptorList corresponds to an action in the given \a params. Returns \l{RuleEngine::RuleError} and \l{RuleAction} list to inform about the result.*/ -QPair, RuleEngine::RuleError> JsonTypes::verifyActions(const QVariantMap ¶ms, const QList &eventDescriptorList) -{ - QList actions; - QVariantList actionList = params.value("actions").toList(); - if (actionList.isEmpty()) { - qCWarning(dcJsonRpc) << "Rule has no actions. This rule will do nothing."; - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleFormat); - } - - qCDebug(dcJsonRpc) << "unpacking actions:" << actionList; - foreach (const QVariant &actionVariant, actionList) { - QVariantMap actionMap = actionVariant.toMap(); - RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString())); - RuleActionParamList actionParamList = JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList()); - foreach (const RuleActionParam &ruleActionParam, actionParamList) { - if (!ruleActionParam.isValid()) { - qCWarning(dcJsonRpc) << "got an actionParam with value AND eventTypeId!"; - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter); - } - } - qCDebug(dcJsonRpc) << "params in exitAction" << action.ruleActionParams(); - action.setRuleActionParams(actionParamList); - actions.append(action); - } - - // check possible eventTypeIds in params - foreach (const RuleAction &ruleAction, actions) { - if (ruleAction.isEventBased()) { - foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) { - if (ruleActionParam.eventTypeId() != EventTypeId()) { - // We have an eventTypeId - if (eventDescriptorList.isEmpty()) { - qCWarning(dcJsonRpc) << "RuleAction" << ruleAction.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors."; - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter); - } - // now check if this eventType is in the eventDescriptorList of this rule - if (!checkEventDescriptors(eventDescriptorList, ruleActionParam.eventTypeId())) { - qCWarning(dcJsonRpc) << "eventTypeId from RuleAction" << ruleAction.actionTypeId() << "missing in eventDescriptors."; - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorInvalidRuleActionParameter); - } - - // check if the param type of the event and the action match - QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamName()); - QVariant::Type actionParamType = getActionParamType(ruleAction.actionTypeId(), ruleActionParam.name()); - if (eventParamType != actionParamType) { - qCWarning(dcJsonRpc) << "RuleActionParam" << ruleActionParam.name() << " and given event param " << ruleActionParam.eventParamName() << "have not the same type:"; - qCWarning(dcJsonRpc) << " -> actionParamType:" << actionParamType; - qCWarning(dcJsonRpc) << " -> eventParamType:" << eventParamType; - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorTypesNotMatching); - } - } - } - } - } - return QPair, RuleEngine::RuleError>(actions, RuleEngine::RuleErrorNoError); -} - -/*! Verifies if exit actions of the rule in the given \a params. Returns \l{RuleEngine::RuleError} and \l{RuleAction} list to inform about the result. */ -QPair, RuleEngine::RuleError> JsonTypes::verifyExitActions(const QVariantMap ¶ms) -{ - QList exitActions; - if (params.contains("exitActions")) { - QVariantList exitActionList = params.value("exitActions").toList(); - qCDebug(dcJsonRpc) << "unpacking exitActions:" << exitActionList; - foreach (const QVariant &actionVariant, exitActionList) { - QVariantMap actionMap = actionVariant.toMap(); - RuleAction action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString())); - if (action.isEventBased()) { - qCWarning(dcJsonRpc) << "got exitAction with a param value containing an eventTypeId!"; - return QPair, RuleEngine::RuleError>(exitActions, RuleEngine::RuleErrorInvalidRuleActionParameter); - } - qCDebug(dcJsonRpc) << "params in exitAction" << action.ruleActionParams(); - action.setRuleActionParams(JsonTypes::unpackRuleActionParams(actionMap.value("ruleActionParams").toList())); - exitActions.append(action); - } - } - return QPair, RuleEngine::RuleError>(exitActions, RuleEngine::RuleErrorNoError); -} - /*! Compairs the given \a value with the given \a enumDescription. Returns the error string and false if the enum does not contain the given \a value. */ QPair JsonTypes::validateEnum(const QVariantList &enumDescription, const QVariant &value) diff --git a/server/jsonrpc/jsontypes.h b/server/jsonrpc/jsontypes.h index 45d82724..46efbcc1 100644 --- a/server/jsonrpc/jsontypes.h +++ b/server/jsonrpc/jsontypes.h @@ -201,6 +201,8 @@ public: // unpack Types static Param unpackParam(const QVariantMap ¶mMap); static ParamList unpackParams(const QVariantList ¶mList); + static Rule unpackRule(const QVariantMap &ruleMap); + static RuleAction unpackRuleAction(const QVariantMap &ruleActionMap); static RuleActionParam unpackRuleActionParam(const QVariantMap &ruleActionParamMap); static RuleActionParamList unpackRuleActionParams(const QVariantList &ruleActionParamList); static ParamDescriptor unpackParamDescriptor(const QVariantMap ¶mDescriptorMap); @@ -222,15 +224,6 @@ public: static QPair validateEnum(const QVariantList &enumList, const QVariant &value); static QPair validateBasicType(const QVariant &variant); - // rule validation helper methods - static bool checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId); - static QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const QString ¶mName); - static QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const QString ¶mName); - static RuleEngine::RuleError verifyRuleConsistency(const QVariantMap ¶ms); - static QPair, RuleEngine::RuleError> verifyEventDescriptors(const QVariantMap ¶ms); - static QPair, RuleEngine::RuleError> verifyActions(const QVariantMap ¶ms, const QList &eventDescriptorList); - static QPair, RuleEngine::RuleError> verifyExitActions(const QVariantMap ¶ms); - private: static bool s_initialized; static void init(); diff --git a/server/jsonrpc/ruleshandler.cpp b/server/jsonrpc/ruleshandler.cpp index f7a5dedc..4e4eeeaf 100644 --- a/server/jsonrpc/ruleshandler.cpp +++ b/server/jsonrpc/ruleshandler.cpp @@ -87,36 +87,33 @@ RulesHandler::RulesHandler(QObject *parent) : 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. 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:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef()); + params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("actions", QVariantList() << JsonTypes::ruleActionRef()); + params.insert("o:timeDescriptor", JsonTypes::timeDescriptorRef()); params.insert("o:stateEvaluator", JsonTypes::stateEvaluatorRef()); + params.insert("o:eventDescriptors", QVariantList() << JsonTypes::eventDescriptorRef()); params.insert("o:exitActions", QVariantList() << JsonTypes::ruleActionRef()); params.insert("o:enabled", JsonTypes::basicTypeToString(JsonTypes::Bool)); params.insert("o:executable", JsonTypes::basicTypeToString(JsonTypes::Bool)); - params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); - QVariantList actions; - actions.append(JsonTypes::ruleActionRef()); - params.insert("actions", actions); setParams("AddRule", params); returns.insert("ruleError", JsonTypes::ruleErrorRef()); returns.insert("o:ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); setReturns("AddRule", returns); - params.clear(); returns.clear(); actions.clear(); + params.clear(); returns.clear(); setDescription("EditRule", "Edit the parameters of a rule. The configuration of the rule with the given ruleId " "will be replaced with the new given configuration. In ordert to enable or disable a Rule, please use the " "methods \"Rules.EnableRule\" and \"Rules.DisableRule\". If successfull, the notification \"Rule.RuleConfigurationChanged\" " "will be emitted."); params.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid)); params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("o:eventDescriptor", JsonTypes::eventDescriptorRef()); - params.insert("o:eventDescriptorList", QVariantList() << JsonTypes::eventDescriptorRef()); + params.insert("actions", QVariantList() << JsonTypes::ruleActionRef()); + params.insert("o:timeDescriptor", JsonTypes::timeDescriptorRef()); params.insert("o:stateEvaluator", JsonTypes::stateEvaluatorRef()); + params.insert("o:eventDescriptors", QVariantList() << JsonTypes::eventDescriptorRef()); params.insert("o:exitActions", QVariantList() << JsonTypes::ruleActionRef()); params.insert("o:enabled", JsonTypes::basicTypeToString(JsonTypes::Bool)); params.insert("o:executable", JsonTypes::basicTypeToString(JsonTypes::Bool)); - actions.append(JsonTypes::ruleActionRef()); - params.insert("actions", actions); setParams("EditRule", params); returns.insert("ruleError", JsonTypes::ruleErrorRef()); returns.insert("o:rule", JsonTypes::ruleRef()); @@ -224,59 +221,13 @@ JsonReply *RulesHandler::GetRuleDetails(const QVariantMap ¶ms) JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms) { - // check rule consistency - RuleEngine::RuleError ruleConsistencyError = JsonTypes::verifyRuleConsistency(params); - if (ruleConsistencyError != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(ruleConsistencyError)); - return createReply(returns); - } + Rule rule = JsonTypes::unpackRule(params); + rule.setId(RuleId::createRuleId()); - // Check and upack eventDescriptorList - QPair, RuleEngine::RuleError> eventDescriptorVerification = JsonTypes::verifyEventDescriptors(params); - QList eventDescriptorList = eventDescriptorVerification.first; - if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(eventDescriptorVerification.second)); - return createReply(returns); - } - - // Check and unpack stateEvaluator - qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap(); - StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap()); - if (!stateEvaluator.isValid()) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidStateEvaluatorValue)); - return createReply(returns); - } - - // Check and unpack actions - QPair, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList); - QList actions = actionsVerification.first; - if (actionsVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(actionsVerification.second)); - return createReply(returns); - } - - // Check and unpack exitActions - QPair, RuleEngine::RuleError> exitActionsVerification = JsonTypes::verifyExitActions(params); - QList exitActions = exitActionsVerification.first; - if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(exitActionsVerification.second)); - return createReply(returns); - } - - QString name = params.value("name", QString()).toString(); - bool enabled = params.value("enabled", true).toBool(); - bool executable = params.value("executable", true).toBool(); - - RuleId newRuleId = RuleId::createRuleId(); - RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->addRule(newRuleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled, executable); + RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->addRule(rule); QVariantMap returns; if (status == RuleEngine::RuleErrorNoError) { - returns.insert("ruleId", newRuleId.toString()); + returns.insert("ruleId", rule.id().toString()); } returns.insert("ruleError", JsonTypes::ruleErrorToString(status)); return createReply(returns); @@ -284,59 +235,11 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms) JsonReply *RulesHandler::EditRule(const QVariantMap ¶ms) { - // check rule consistency - RuleEngine::RuleError ruleConsistencyError = JsonTypes::verifyRuleConsistency(params); - if (ruleConsistencyError != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(ruleConsistencyError)); - return createReply(returns); - } - - // Check and upack eventDescriptorList - QPair, RuleEngine::RuleError> eventDescriptorVerification = JsonTypes::verifyEventDescriptors(params); - QList eventDescriptorList = eventDescriptorVerification.first; - if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(eventDescriptorVerification.second)); - return createReply(returns); - } - - // Check and unpack stateEvaluator - qCDebug(dcJsonRpc) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap(); - StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap()); - if (!stateEvaluator.isValid()) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidStateEvaluatorValue)); - return createReply(returns); - } - - // Check and unpack actions - QPair, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList); - QList actions = actionsVerification.first; - if (actionsVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(actionsVerification.second)); - return createReply(returns); - } - - // Check and unpack exitActions - QPair, RuleEngine::RuleError> exitActionsVerification = JsonTypes::verifyExitActions(params); - QList exitActions = exitActionsVerification.first; - if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) { - QVariantMap returns; - returns.insert("ruleError", JsonTypes::ruleErrorToString(exitActionsVerification.second)); - return createReply(returns); - } - - QString name = params.value("name", QString()).toString(); - bool enabled = params.value("enabled", true).toBool(); - bool executable = params.value("executable", true).toBool(); - - RuleId ruleId = RuleId(params.value("ruleId").toString()); - RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->editRule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled, executable); + Rule rule = JsonTypes::unpackRule(params); + RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->editRule(rule); QVariantMap returns; if (status == RuleEngine::RuleErrorNoError) { - returns.insert("rule", JsonTypes::packRule(GuhCore::instance()->ruleEngine()->findRule(ruleId))); + returns.insert("rule", JsonTypes::packRule(GuhCore::instance()->ruleEngine()->findRule(rule.id()))); } returns.insert("ruleError", JsonTypes::ruleErrorToString(status)); return createReply(returns); diff --git a/server/rest/rulesresource.cpp b/server/rest/rulesresource.cpp index 04a1e46d..a79c6b93 100644 --- a/server/rest/rulesresource.cpp +++ b/server/rest/rulesresource.cpp @@ -75,8 +75,10 @@ HttpReply *RulesResource::proccessRequest(const HttpRequest &request, const QStr return createRuleErrorReply(HttpReply::BadRequest, RuleEngine::RuleErrorRuleNotFound); } - if (GuhCore::instance()->ruleEngine()->findRule(m_ruleId).id().isNull()) + if (!GuhCore::instance()->ruleEngine()->findRule(m_ruleId).isValid()) { + qCWarning(dcRest) << "Could not find rule with id" << m_ruleId.toString(); return createRuleErrorReply(HttpReply::NotFound, RuleEngine::RuleErrorRuleNotFound); + } } @@ -201,7 +203,7 @@ HttpReply *RulesResource::getRules(const DeviceId &deviceId) const QList ruleList; foreach (const RuleId &ruleId, ruleIdsList) { Rule rule = GuhCore::instance()->ruleEngine()->findRule(ruleId); - if (!rule.id().isNull()) + if (rule.isValid()) ruleList.append(rule); } reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";"); @@ -212,11 +214,11 @@ HttpReply *RulesResource::getRules(const DeviceId &deviceId) const HttpReply *RulesResource::getRuleDetails(const RuleId &ruleId) const { - Rule rule = GuhCore::instance()->ruleEngine()->findRule(ruleId); - if (rule.id().isNull()) - return createRuleErrorReply(HttpReply::NotFound, RuleEngine::RuleErrorRuleNotFound); - qCDebug(dcRest) << "Get rule details"; + + // Note: rule existence already checked + Rule rule = GuhCore::instance()->ruleEngine()->findRule(ruleId); + HttpReply *reply = createSuccessReply(); reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";"); reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packRule(rule)).toJson()); @@ -228,7 +230,6 @@ HttpReply *RulesResource::removeRule(const RuleId &ruleId) const qCDebug(dcRest) << "Remove rule with id" << ruleId.toString(); RuleEngine::RuleError status = GuhCore::instance()->removeRule(ruleId); - if (status != RuleEngine::RuleErrorNoError) return createRuleErrorReply(HttpReply::InternalServerError, status); @@ -244,45 +245,12 @@ HttpReply *RulesResource::addRule(const QByteArray &payload) const return createErrorReply(HttpReply::BadRequest); QVariantMap params = verification.second.toMap(); + Rule rule = JsonTypes::unpackRule(params); + rule.setId(RuleId::createRuleId()); - // check rule consistency - RuleEngine::RuleError ruleConsistencyError = JsonTypes::verifyRuleConsistency(params); - if (ruleConsistencyError != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, ruleConsistencyError); - - // Check and upack eventDescriptorList - QPair, RuleEngine::RuleError> eventDescriptorVerification = JsonTypes::verifyEventDescriptors(params); - QList eventDescriptorList = eventDescriptorVerification.first; - if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, eventDescriptorVerification.second); - - // Check and unpack stateEvaluator - qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap(); - StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap()); - if (!stateEvaluator.isValid()) - return createRuleErrorReply(HttpReply::BadRequest, RuleEngine::RuleErrorInvalidStateEvaluatorValue); - - // Check and unpack actions - QPair, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList); - QList actions = actionsVerification.first; - if (actionsVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, actionsVerification.second); - - // Check and unpack exitActions - QPair, RuleEngine::RuleError> exitActionsVerification = JsonTypes::verifyExitActions(params); - QList exitActions = exitActionsVerification.first; - if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, exitActionsVerification.second); - - QString name = params.value("name", QString()).toString(); - bool enabled = params.value("enabled", true).toBool(); - bool executable = params.value("executable", true).toBool(); - - RuleId newRuleId = RuleId::createRuleId(); - RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->addRule(newRuleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled, executable); - + RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->addRule(rule); if (status == RuleEngine::RuleErrorNoError) { - QVariant returns = JsonTypes::packRule(GuhCore::instance()->ruleEngine()->findRule(newRuleId)); + QVariant returns = JsonTypes::packRule(GuhCore::instance()->ruleEngine()->findRule(rule.id())); HttpReply *reply = createSuccessReply(); reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";"); reply->setPayload(QJsonDocument::fromVariant(returns).toJson()); @@ -297,7 +265,6 @@ HttpReply *RulesResource::enableRule(const RuleId &ruleId) const qCDebug(dcRest) << "Enable rule with id" << ruleId.toString(); RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->enableRule(ruleId); - if (status != RuleEngine::RuleErrorNoError) return createRuleErrorReply(HttpReply::InternalServerError, status); @@ -309,7 +276,6 @@ HttpReply *RulesResource::disableRule(const RuleId &ruleId) const qCDebug(dcRest) << "Disable rule with id" << ruleId.toString(); RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->disableRule(ruleId); - if (status != RuleEngine::RuleErrorNoError) return createRuleErrorReply(HttpReply::InternalServerError, status); @@ -321,7 +287,6 @@ HttpReply *RulesResource::executeActions(const RuleId &ruleId) const qCDebug(dcRest) << "Execute actions of rule with id" << ruleId.toString(); RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->executeActions(ruleId); - if (status != RuleEngine::RuleErrorNoError) return createRuleErrorReply(HttpReply::InternalServerError, status); @@ -333,7 +298,6 @@ HttpReply *RulesResource::executeExitActions(const RuleId &ruleId) const qCDebug(dcRest) << "Execute exit actions of rule with id" << ruleId.toString(); RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->executeExitActions(ruleId); - if (status != RuleEngine::RuleErrorNoError) return createRuleErrorReply(HttpReply::InternalServerError, status); @@ -349,41 +313,9 @@ HttpReply *RulesResource::editRule(const RuleId &ruleId, const QByteArray &paylo return createErrorReply(HttpReply::BadRequest); QVariantMap params = verification.second.toMap(); + Rule rule = JsonTypes::unpackRule(params); - // check rule consistency - RuleEngine::RuleError ruleConsistencyError = JsonTypes::verifyRuleConsistency(params); - if (ruleConsistencyError != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, ruleConsistencyError); - - // Check and upack eventDescriptorList - QPair, RuleEngine::RuleError> eventDescriptorVerification = JsonTypes::verifyEventDescriptors(params); - QList eventDescriptorList = eventDescriptorVerification.first; - if (eventDescriptorVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, eventDescriptorVerification.second); - - // Check and unpack stateEvaluator - qCDebug(dcRest) << "unpacking stateEvaluator:" << params.value("stateEvaluator").toMap(); - StateEvaluator stateEvaluator = JsonTypes::unpackStateEvaluator(params.value("stateEvaluator").toMap()); - if (!stateEvaluator.isValid()) - return createRuleErrorReply(HttpReply::BadRequest, RuleEngine::RuleErrorInvalidStateEvaluatorValue); - - // Check and unpack actions - QPair, RuleEngine::RuleError> actionsVerification = JsonTypes::verifyActions(params, eventDescriptorList); - QList actions = actionsVerification.first; - if (actionsVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, actionsVerification.second); - - // Check and unpack exitActions - QPair, RuleEngine::RuleError> exitActionsVerification = JsonTypes::verifyExitActions(params); - QList exitActions = exitActionsVerification.first; - if (exitActionsVerification.second != RuleEngine::RuleErrorNoError) - return createRuleErrorReply(HttpReply::BadRequest, exitActionsVerification.second); - - QString name = params.value("name", QString()).toString(); - bool enabled = params.value("enabled", true).toBool(); - - RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->editRule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled); - + RuleEngine::RuleError status = GuhCore::instance()->ruleEngine()->editRule(rule); if (status == RuleEngine::RuleErrorNoError) { qCDebug(dcRest) << "Edit rule successfully finished"; return createRuleErrorReply(HttpReply::Ok, status); diff --git a/server/rule.cpp b/server/rule.cpp index 8ea01684..cb0ca4e2 100644 --- a/server/rule.cpp +++ b/server/rule.cpp @@ -33,6 +33,7 @@ */ #include "rule.h" +#include "loggingcategories.h" #include @@ -40,17 +41,13 @@ namespace guhserver { /*! Constructs an empty, invalid rule. */ Rule::Rule(): - Rule(RuleId(), QString(), QList(), StateEvaluator(), QList(), QList()) -{ -} - -/*! Constructs a Rule with the given \a id, \a name, \a eventDescriptorList, \a stateEvaluator and \a actions.*/ -Rule::Rule(const RuleId &id, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions) : - m_id(id), - m_name(name), - m_eventDescriptors(eventDescriptorList), - m_stateEvaluator(stateEvaluator), - m_actions(actions), + m_id(RuleId()), + m_name(QString()), + m_timeDescriptor(TimeDescriptor()), + m_stateEvaluator(StateEvaluator()), + m_eventDescriptors(QList()), + m_actions(QList()), + m_exitActions(QList()), m_enabled(false), m_active(false), m_executable(false) @@ -58,45 +55,43 @@ Rule::Rule(const RuleId &id, const QString &name, const QList & } -/*! Constructs a Rule with the given \a id, \a name, \a eventDescriptorList, \a stateEvaluator, \a actions and \a exitActions.*/ -Rule::Rule(const RuleId &id, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions): - m_id(id), - m_name(name), - m_eventDescriptors(eventDescriptorList), - m_stateEvaluator(stateEvaluator), - m_actions(actions), - m_exitActions(exitActions), - m_enabled(false), - m_active(false), - m_executable(false) -{ -} - -/*! Constructs a Rule with the given \a id, \a name, \a stateEvaluator, \a actions and \a exitActions. This type of rule - * works only state based and executes the \a actions once the rule enters the active state and executes the \a exitActions - * once the rule exits the active state.*/ -Rule::Rule(const RuleId &id, const QString &name, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions) : - m_id(id), - m_name(name), - m_stateEvaluator(stateEvaluator), - m_actions(actions), - m_exitActions(exitActions), - m_enabled(false), - m_active(false), - m_executable(false) -{ -} - -/*! Returns the id or the Rule. */ +/*! Returns the id of this Rule. */ RuleId Rule::id() const { return m_id; } -/*! Returns the \l{EventDescriptor} for this Rule.*/ -QList Rule::eventDescriptors() const +void Rule::setId(const RuleId &ruleId) { - return m_eventDescriptors; + m_id = ruleId; +} + +/*! Returns the name of this rule. */ +QString Rule::name() const +{ + return m_name; +} + +void Rule::setName(const QString &name) +{ + m_name = name; +} + +/*! Returns true if the rule is active. */ +bool Rule::active() const +{ + return m_active; +} + +/*! Returns the \l{TimeDescriptor} or this Rule. */ +TimeDescriptor Rule::timeDescriptor() const +{ + return m_timeDescriptor; +} + +void Rule::setTimeDescriptor(const TimeDescriptor &timeDescriptor) +{ + m_timeDescriptor = timeDescriptor; } /*! Returns the StateEvaluator that needs to evaluate successfully in order for this to Rule apply. */ @@ -105,22 +100,42 @@ StateEvaluator Rule::stateEvaluator() const return m_stateEvaluator; } +void Rule::setStateEvaluator(const StateEvaluator &stateEvaluator) +{ + m_stateEvaluator = stateEvaluator; +} + +/*! Returns the \l{EventDescriptor} for this Rule.*/ +QList Rule::eventDescriptors() const +{ + return m_eventDescriptors; +} + +void Rule::setEventDescriptors(const QList &eventDescriptors) +{ + m_eventDescriptors = eventDescriptors; +} + /*! Returns the \l{RuleAction}{RuleActions} to be executed when this Rule is matched and states match. */ QList Rule::actions() const { return m_actions; } +void Rule::setActions(const QList actions) +{ + m_actions = actions; +} + /*! Returns the \l{RuleAction}{RuleActions} to be executed when this Rule leaves the active state. */ QList Rule::exitActions() const { return m_exitActions; } -/*! Returns the name of this rule. */ -QString Rule::name() const +void Rule::setExitActions(const QList exitActions) { - return m_name; + m_exitActions = exitActions; } /*! Returns true if the rule is enabled. */ @@ -130,35 +145,47 @@ bool Rule::enabled() const { /*! Set the \a enabled flag of this rule. In order to actually enable/disable the rule you still need to * update the \l{RuleEngine} */ -void Rule::setEnabled(bool enabled) +void Rule::setEnabled(const bool &enabled) { m_enabled = enabled; } -/*! Returns true if the rule is active. */ -bool Rule::active() const -{ - return m_active; -} - -/*! Set the rule \a executable. */ -void Rule::setExecutable(const bool &executable) -{ - m_executable = executable; -} - /*! Returns true if the rule is executable. */ bool Rule::executable() const { return m_executable; } -void Rule::setName(const QString &name) +/*! Set the rule \a executable. */ +void Rule::setExecutable(const bool &executable) { - m_name = name; + m_executable = executable; } -void Rule::setActive(bool active) +bool Rule::isValid() const +{ + return !m_id.isNull(); +} + +bool Rule::isConsistent() const +{ + // check if this rules is based on any event and contains exit actions + if (!eventDescriptors().isEmpty() && !exitActions().isEmpty()) { + qCWarning(dcRuleEngine) << "Rule not consistent. The exitActions will never be executed if the rule contains an eventDescriptor."; + return false; + } + + // check if there are any actions + if (actions().isEmpty()) { + qCWarning(dcRuleEngine) << "Rule not consistent. A rule without actions has no effect."; + return false; + } + + return true; +} + + +void Rule::setActive(const bool &active) { m_active = active; } diff --git a/server/rule.h b/server/rule.h index 185e557e..493ec273 100644 --- a/server/rule.h +++ b/server/rule.h @@ -26,6 +26,7 @@ #include "types/ruleaction.h" #include "types/eventdescriptor.h" #include "stateevaluator.h" +#include "time/timedescriptor.h" #include @@ -35,35 +36,50 @@ class Rule { public: Rule(); - Rule(const RuleId &id, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions); - Rule(const RuleId &id, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions); - Rule(const RuleId &id, const QString &name, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions); RuleId id() const; - QList eventDescriptors() const; - StateEvaluator stateEvaluator() const; - QList actions() const; - QList exitActions() const; + void setId(const RuleId &ruleId); QString name() const; - bool enabled() const; - void setEnabled(bool enabled); + void setName(const QString &name); bool active() const; - void setExecutable(const bool &executable); + TimeDescriptor timeDescriptor() const; + void setTimeDescriptor(const TimeDescriptor &timeDescriptor); + + StateEvaluator stateEvaluator() const; + void setStateEvaluator(const StateEvaluator &stateEvaluator); + + QList eventDescriptors() const; + void setEventDescriptors(const QList &eventDescriptors); + + QList actions() const; + void setActions(const QList actions); + + QList exitActions() const; + void setExitActions(const QList exitActions); + + bool enabled() const; + void setEnabled(const bool &enabled); + bool executable() const; + void setExecutable(const bool &executable); + + // verification methods + bool isValid() const; + bool isConsistent() const; private: friend class RuleEngine; - void setName(const QString &name); - void setActive(bool active); + void setActive(const bool &active); private: RuleId m_id; QString m_name; - QList m_eventDescriptors; + TimeDescriptor m_timeDescriptor; StateEvaluator m_stateEvaluator; + QList m_eventDescriptors; QList m_actions; QList m_exitActions; diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index 2b4e960e..8ef914a6 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -205,7 +205,13 @@ RuleEngine::RuleEngine(QObject *parent) : } settings.endGroup(); - Rule rule = Rule(RuleId(idString), name, eventDescriptorList, stateEvaluator, actions, exitActions); + Rule rule; + rule.setId(RuleId(idString)); + rule.setName(name); + rule.setEventDescriptors(eventDescriptorList); + rule.setStateEvaluator(stateEvaluator); + rule.setActions(actions); + rule.setExitActions(exitActions); rule.setEnabled(enabled); rule.setExecutable(executable); appendRule(rule); @@ -272,35 +278,40 @@ QList RuleEngine::evaluateEvent(const Event &event) return rules; } -/*! Add a new \l{Rule} with the given \a ruleId , \a name, \a eventDescriptorList, \a actions and \a enabled value to the engine. - For convenience, this creates a Rule without any \l{State} comparison. -*/ -RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const QList &actions, bool enabled) +QList RuleEngine::evaluateTime(const QDateTime &dateTime) { - return addRule(ruleId, name, eventDescriptorList, StateEvaluator(), actions, QList(), enabled); + Q_UNUSED(dateTime) + QList rules; + + return rules; } -/*! Add a new \l{Rule} with the given \a ruleId, \a name, \a eventDescriptorList, \a stateEvaluator, the list of \a actions, the list of \a exitActions, the \a enabled and the \a executable value to the engine. - If \a fromEdit is true, the notification Rules. RuleAdded will not be emitted. -*/ -RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled, bool executable, bool fromEdit) +RuleEngine::RuleError RuleEngine::addRule(const Rule &rule, bool fromEdit) { - if (ruleId.isNull()) + if (rule.id().isNull()) return RuleErrorInvalidRuleId; - if (!findRule(ruleId).id().isNull()) { - qCWarning(dcRuleEngine) << "Already have a rule with this id!"; + if (!findRule(rule.id()).id().isNull()) { + qCWarning(dcRuleEngine) << "Already have a rule with this id."; return RuleErrorInvalidRuleId; } - foreach (const EventDescriptor &eventDescriptor, eventDescriptorList) { + if (!rule.isConsistent()) { + qCWarning(dcRuleEngine) << "Rule inconsistent."; + return RuleErrorInvalidRuleFormat; + } + + // Check IDs in each EventDescriptor + foreach (const EventDescriptor &eventDescriptor, rule.eventDescriptors()) { + // check deviceId Device *device = GuhCore::instance()->deviceManager()->findConfiguredDevice(eventDescriptor.deviceId()); if (!device) { qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for eventTypeId" << eventDescriptor.eventTypeId(); return RuleErrorDeviceNotFound; } - DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); + // Check eventTypeId for this deivce + DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); bool eventTypeFound = false; foreach (const EventType &eventType, deviceClass.eventTypes()) { if (eventType.id() == eventDescriptor.eventTypeId()) { @@ -313,45 +324,84 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n } } + // Check state evaluator + if (!rule.stateEvaluator().isValid()) { + qCWarning(dcRuleEngine) << "Got an invalid StateEvaluator."; + return RuleErrorInvalidStateEvaluatorValue; + } - - foreach (const RuleAction &action, actions) { + // Check actions + foreach (const RuleAction &action, rule.actions()) { Device *device = GuhCore::instance()->deviceManager()->findConfiguredDevice(action.deviceId()); if (!device) { - qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for actionTypeId" << action.actionTypeId(); + qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for action with actionTypeId" << action.actionTypeId(); return RuleErrorDeviceNotFound; } + DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); if (!deviceClass.hasActionType(action.actionTypeId())) { qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << action.actionTypeId(); return RuleErrorActionTypeNotFound; } - // if the action is eventbased, it is already checked - if (!action.isEventBased()) { + // check possible eventTypeIds in params + if (action.isEventBased()) { + foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) { + if (ruleActionParam.eventTypeId() != EventTypeId()) { + // We have an eventTypeId + if (rule.eventDescriptors().isEmpty()) { + qCWarning(dcRuleEngine) << "Cannot create rule. RuleAction" << action.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors."; + return RuleErrorInvalidRuleActionParameter; + } + + // now check if this eventType is in the eventDescriptorList of this rule + if (!checkEventDescriptors(rule.eventDescriptors(), ruleActionParam.eventTypeId())) { + qCWarning(dcRuleEngine) << "Cannot create rule. EventTypeId from RuleAction" << action.actionTypeId() << "not in eventDescriptors."; + return RuleErrorInvalidRuleActionParameter; + } + + // check if the param type of the event and the action match + QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamName()); + QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.name()); + if (eventParamType != actionParamType) { + qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.name() << " and given event param " << ruleActionParam.eventParamName() << "have not the same type:"; + qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType; + qCWarning(dcRuleEngine) << " -> eventParamType:" << eventParamType; + return RuleErrorTypesNotMatching; + } + } + } + } else { // verify action params foreach (const ActionType &actionType, deviceClass.actionTypes()) { if (actionType.id() == action.actionTypeId()) { ParamList finalParams = action.toAction().params(); DeviceManager::DeviceError paramCheck = GuhCore::instance()->deviceManager()->verifyParams(actionType.paramTypes(), finalParams); - if (paramCheck != DeviceManager::DeviceErrorNoError) + if (paramCheck != DeviceManager::DeviceErrorNoError) { + qCWarning(dcRuleEngine) << "Cannot create rule. Got an invalid actionParam."; return RuleErrorInvalidRuleActionParameter; + } } } } + + foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) { + if (!ruleActionParam.isValid()) { + qCWarning(dcRuleEngine) << "Cannot create rule. Got an actionParam with \"value\" AND \"eventTypeId\"."; + return RuleEngine::RuleErrorInvalidRuleActionParameter; + } + } } - if (actions.count() > 0) - qCDebug(dcRuleEngine) << "actions" << actions.last().actionTypeId() << actions.last().ruleActionParams(); - - foreach (const RuleAction &action, exitActions) { + // Check exit actions + foreach (const RuleAction &action, rule.exitActions()) { Device *device = GuhCore::instance()->deviceManager()->findConfiguredDevice(action.deviceId()); if (!device) { - qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for actionTypeId" << action.actionTypeId(); + qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for exit action with actionTypeId" << action.actionTypeId(); return RuleErrorDeviceNotFound; } - DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); + DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId()); if (!deviceClass.hasActionType(action.actionTypeId())) { qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << action.actionTypeId(); return RuleErrorActionTypeNotFound; @@ -362,60 +412,67 @@ RuleEngine::RuleError RuleEngine::addRule(const RuleId &ruleId, const QString &n if (actionType.id() == action.actionTypeId()) { ParamList finalParams = action.toAction().params(); DeviceManager::DeviceError paramCheck = GuhCore::instance()->deviceManager()->verifyParams(actionType.paramTypes(), finalParams); - if (paramCheck != DeviceManager::DeviceErrorNoError) + if (paramCheck != DeviceManager::DeviceErrorNoError) { + qCWarning(dcRuleEngine) << "Cannot create rule. Got an invalid exit actionParam."; return RuleErrorInvalidRuleActionParameter; + } + } + } + + // Exit action can never be event based. + if (action.isEventBased()) { + qCWarning(dcRuleEngine) << "Cannot create rule. Got exitAction with an actionParam containing an eventTypeId. "; + return RuleErrorInvalidRuleActionParameter; + } + + foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) { + if (!ruleActionParam.isValid()) { + qCWarning(dcRuleEngine) << "Cannot create rule. Got an actionParam with \"value\" AND \"eventTypeId\"."; + return RuleEngine::RuleErrorInvalidRuleActionParameter; } } } - if (exitActions.count() > 0) - qCDebug(dcRuleEngine) << "exit actions" << exitActions.last().actionTypeId() << exitActions.last().ruleActionParams(); - - Rule rule = Rule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions); - rule.setEnabled(enabled); - rule.setExecutable(executable); appendRule(rule); saveRule(rule); + if (!fromEdit) emit ruleAdded(rule); return RuleErrorNoError; } -/*! Edit a \l{Rule} with the given \a ruleId, \a name, \a eventDescriptorList, \a stateEvaluator, - the list of \a actions, the list of \a exitActions, the \a enabled and the \a executable in the engine. -*/ -RuleEngine::RuleError RuleEngine::editRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled, bool executable) +RuleEngine::RuleError RuleEngine::editRule(const Rule &rule) { - if (ruleId.isNull()) + if (rule.id().isNull()) return RuleErrorInvalidRuleId; - // Store rule in case the add new rule fails - Rule rule = findRule(ruleId); - - if (rule.id().isNull()) { - qCWarning(dcRuleEngine) << "Cannot edit rule. There is no rule with id:" << ruleId.toString(); + Rule oldRule = findRule(rule.id()); + if (oldRule.id().isNull()) { + qCWarning(dcRuleEngine) << "Cannot edit rule. There is no rule with id:" << rule.id().toString(); return RuleErrorRuleNotFound; } // First remove old rule with this id - RuleError removeResult = removeRule(ruleId, true); + RuleError removeResult = removeRule(oldRule.id(), true); if (removeResult != RuleErrorNoError) { + qCWarning(dcRuleEngine) << "Cannot edit rule. Could not remove the old rule."; // no need to restore, rule is still in system return removeResult; } - // The rule is removed, now add it with the same id and new vonfiguration - RuleError addResult = addRule(ruleId, name, eventDescriptorList, stateEvaluator, actions, exitActions, enabled, executable, true); + // The rule is removed, now add the new one + RuleError addResult = addRule(rule); if (addResult != RuleErrorNoError) { - // restore rule - appendRule(rule); + qCWarning(dcRuleEngine) << "Cannot edit rule. Could not add the new rule. Restoring the old rule."; + // restore old rule + appendRule(oldRule); return addResult; } - emit ruleConfigurationChanged(m_rules.value(ruleId)); - + // Successfully changed the rule + emit ruleConfigurationChanged(rule); return RuleErrorNoError; } @@ -449,6 +506,7 @@ RuleEngine::RuleError RuleEngine::removeRule(const RuleId &ruleId, bool fromEdit m_ruleIds.takeAt(index); m_rules.remove(ruleId); + m_activeRules.removeAll(ruleId); GuhSettings settings(GuhSettings::SettingsRoleRules); settings.beginGroup(ruleId.toString()); @@ -568,12 +626,10 @@ RuleEngine::RuleError RuleEngine::executeExitActions(const RuleId &ruleId) /*! Returns the \l{Rule} with the given \a ruleId. If the \l{Rule} does not exist, it will return \l{Rule::Rule()} */ Rule RuleEngine::findRule(const RuleId &ruleId) { - foreach (const Rule &rule, m_rules) { - if (rule.id() == ruleId) { - return rule; - } - } - return Rule(); + if (!m_rules.contains(ruleId)) + return Rule(); + + return m_rules.value(ruleId); } /*! Returns a list of all \l{Rule}{Rules} loaded in this Engine, which contains a \l{Device} with the given \a deviceId. */ @@ -670,7 +726,12 @@ void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId settings.remove(""); settings.endGroup(); - Rule newRule(id, rule.name(), eventDescriptors, stateEvalatuator, actions); + Rule newRule; + newRule.setId(id); + newRule.setName(rule.name()); + newRule.setEventDescriptors(eventDescriptors); + newRule.setStateEvaluator(stateEvalatuator); + newRule.setActions(actions); m_rules[id] = newRule; // save it @@ -702,6 +763,48 @@ bool RuleEngine::containsState(const StateEvaluator &stateEvaluator, const Event return false; } +bool RuleEngine::checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId) +{ + foreach (const EventDescriptor eventDescriptor, eventDescriptors) { + if (eventDescriptor.eventTypeId() == eventTypeId) { + return true; + } + } + return false; +} + +QVariant::Type RuleEngine::getActionParamType(const ActionTypeId &actionTypeId, const QString ¶mName) +{ + foreach (const DeviceClass &deviceClass, GuhCore::instance()->deviceManager()->supportedDevices()) { + foreach (const ActionType &actionType, deviceClass.actionTypes()) { + if (actionType.id() == actionTypeId) { + foreach (const ParamType ¶mType, actionType.paramTypes()) { + if (paramType.name() == paramName) { + return paramType.type(); + } + } + } + } + } + return QVariant::Invalid; +} + +QVariant::Type RuleEngine::getEventParamType(const EventTypeId &eventTypeId, const QString ¶mName) +{ + foreach (const DeviceClass &deviceClass, GuhCore::instance()->deviceManager()->supportedDevices()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { + if (eventType.id() == eventTypeId) { + foreach (const ParamType ¶mType, eventType.paramTypes()) { + if (paramType.name() == paramName) { + return paramType.type(); + } + } + } + } + } + return QVariant::Invalid; +} + void RuleEngine::appendRule(const Rule &rule) { m_rules.insert(rule.id(), rule); diff --git a/server/ruleengine.h b/server/ruleengine.h index b971e814..b0a218f3 100644 --- a/server/ruleengine.h +++ b/server/ruleengine.h @@ -67,10 +67,14 @@ public: ~RuleEngine(); QList evaluateEvent(const Event &event); + QList evaluateTime(const QDateTime &dateTime); - RuleError addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const QList &actions, bool enabled = true); - RuleError addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled = true, bool executable = true, bool fromEdit = false); - RuleError editRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled = true, bool executable = true); + RuleError addRule(const Rule &rule, bool fromEdit = false); +// RuleError addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const QList &actions, bool enabled = true); +// RuleError addRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled = true, bool executable = true, bool fromEdit = false); + + RuleError editRule(const Rule &rule); +// RuleError editRule(const RuleId &ruleId, const QString &name, const QList &eventDescriptorList, const StateEvaluator &stateEvaluator, const QList &actions, const QList &exitActions, bool enabled = true, bool executable = true); QList rules() const; QList ruleIds() const; @@ -97,6 +101,10 @@ private: bool containsEvent(const Rule &rule, const Event &event); bool containsState(const StateEvaluator &stateEvaluator, const Event &stateChangeEvent); + bool checkEventDescriptors(const QList eventDescriptors, const EventTypeId &eventTypeId); + QVariant::Type getActionParamType(const ActionTypeId &actionTypeId, const QString ¶mName); + QVariant::Type getEventParamType(const EventTypeId &eventTypeId, const QString ¶mName); + void appendRule(const Rule &rule); void saveRule(const Rule &rule); diff --git a/server/servermanager.h b/server/servermanager.h index 878c3fb4..a14dd757 100644 --- a/server/servermanager.h +++ b/server/servermanager.h @@ -50,9 +50,7 @@ private: QSslKey m_certificateKey; QSslCertificate m_certificate; - bool loadCertificate(const QString &certificateKeyFileName, const QString &certificateFileName); - }; } diff --git a/server/time/timemanager.cpp b/server/time/timemanager.cpp index 479cf28f..072dd5fe 100644 --- a/server/time/timemanager.cpp +++ b/server/time/timemanager.cpp @@ -100,6 +100,14 @@ QDate TimeManager::currentDate() const return QDateTime::currentDateTimeUtc().toTimeZone(m_timeZone).date(); } +#ifdef TESTING_ENABLED +void TimeManager::stopTimer() +{ + // Stop clock (used for testing) + m_guhTimer->stop(); +} +#endif + void TimeManager::guhTimeout() { // tick for deviceManager diff --git a/server/time/timemanager.h b/server/time/timemanager.h index 3f730efe..2c656423 100644 --- a/server/time/timemanager.h +++ b/server/time/timemanager.h @@ -41,6 +41,10 @@ public: QTime currentTime() const; QDate currentDate() const; +#ifdef TESTING_ENABLED + void stopTimer(); +#endif + private: QTimeZone m_timeZone; QDateTime m_dateTime; diff --git a/tests/auto/restrules/testrestrules.cpp b/tests/auto/restrules/testrestrules.cpp index f8d18c72..0373f7a5 100644 --- a/tests/auto/restrules/testrestrules.cpp +++ b/tests/auto/restrules/testrestrules.cpp @@ -220,7 +220,7 @@ void TestRestRules::findRule() RuleId ruleId = RuleId(response.toMap().value("id").toString()); QVERIFY(!ruleId.isNull()); - QUrl url(QString("http://localhost:3333/api/v1/rules/%1").arg(ruleId.toString())); + QUrl url(QString("http://localhost:3333/api/v1/rules")); QUrlQuery query; query.addQueryItem("deviceId", m_mockDeviceId.toString()); url.setQuery(query); @@ -462,7 +462,6 @@ void TestRestRules::addRemoveRules_data() QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << 200 << true << "TestRule"; QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << 200 << true << "TestRule"; QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << 200 << true << "TestRule"; - QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << 400 << false << "TestRule"; QTest::newRow("invalid action") << true << invalidAction << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << 400 << false << "TestRule"; QTest::newRow("invalid event descriptor") << true << validActionNoParams << QVariantMap() << invalidEventDescriptor << QVariantList() << validStateEvaluator << 400 << false << "TestRule"; } @@ -490,10 +489,10 @@ void TestRestRules::addRemoveRules() params.insert("actions", actions); if (!eventDescriptor.isEmpty()) { - params.insert("eventDescriptor", eventDescriptor); + params.insert("eventDescriptors", QVariantList() << eventDescriptor); } if (!eventDescriptorList.isEmpty()) { - params.insert("eventDescriptorList", eventDescriptorList); + params.insert("eventDescriptors", eventDescriptorList); } QVariantList exitActions; @@ -523,9 +522,11 @@ void TestRestRules::addRemoveRules() RuleId ruleId = RuleId(response.toMap().value("id").toString()); QVERIFY(!ruleId.isNull()); + qDebug() << QJsonDocument::fromVariant(response).toJson(); + // GET rule details request = QNetworkRequest(QUrl(QString("http://localhost:3333/api/v1/rules/%1").arg(ruleId.toString()))); - request.setHeader(QNetworkRequest::ContentTypeHeader, "text/json"); + //request.setHeader(QNetworkRequest::ContentTypeHeader, "text/json"); response = getAndWait(request); QVERIFY(!response.isNull()); @@ -548,8 +549,7 @@ void TestRestRules::emptyRule() request.setHeader(QNetworkRequest::ContentTypeHeader, "text/json"); QVariant response = postAndWait(request, params, 400); - QCOMPARE(response.toMap().value("error").toString(), JsonTypes::ruleErrorToString(RuleEngine::RuleErrorMissingParameter)); - + QCOMPARE(response.toMap().value("error").toString(), JsonTypes::ruleErrorToString(RuleEngine::RuleErrorInvalidRuleFormat)); } void TestRestRules::editRules_data() @@ -694,7 +694,6 @@ void TestRestRules::editRules_data() QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << 200 << "TestRule"; QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << 200 << "TestRule"; QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << 200 << "TestRule"; - QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << 400 << "TestRule"; } void TestRestRules::editRules() @@ -796,7 +795,7 @@ void TestRestRules::editRules() actions.append(action1); actions.append(action2); params.insert("actions", actions); - params.insert("eventDescriptorList", eventDescriptorList1); + params.insert("eventDescriptors", eventDescriptorList1); params.insert("stateEvaluator", stateEvaluator0); params.insert("name", "TestRule"); @@ -821,10 +820,10 @@ void TestRestRules::editRules() params.insert("name", name); if (!eventDescriptor.isEmpty()) { - params.insert("eventDescriptor", eventDescriptor); + params.insert("eventDescriptors", QVariantList() << eventDescriptor); } if (!eventDescriptorList.isEmpty()) { - params.insert("eventDescriptorList", eventDescriptorList); + params.insert("eventDescriptors", eventDescriptorList); } actions.clear(); actions.append(action); @@ -872,7 +871,7 @@ void TestRestRules::enableDisableRule() event1.insert("eventTypeId", mockEvent1Id); event1.insert("deviceId", m_mockDeviceId); events.append(event1); - addRuleParams.insert("eventDescriptorList", events); + addRuleParams.insert("eventDescriptors", events); addRuleParams.insert("name", "TestRule"); QVariantList actions; diff --git a/tests/auto/rules/testrules.cpp b/tests/auto/rules/testrules.cpp index b150bbdd..2fb2e8ba 100644 --- a/tests/auto/rules/testrules.cpp +++ b/tests/auto/rules/testrules.cpp @@ -116,7 +116,7 @@ void TestRules::emptyRule() params.insert("name", QString()); params.insert("actions", QVariantList()); QVariant response = injectAndWait("Rules.AddRule", params); - verifyRuleError(response, RuleEngine::RuleErrorMissingParameter); + verifyRuleError(response, RuleEngine::RuleErrorInvalidRuleFormat); } void TestRules::getInvalidRule() @@ -342,7 +342,7 @@ void TestRules::addRemoveRules_data() QTest::newRow("invalid rule. enabled, 1 Action (eventBased), types not matching, name") << true << invalidActionEventBased3 << QVariantMap() << validEventDescriptor1 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorTypesNotMatching << false << "TestRule"; - QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased << QVariantMap() << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter << false << "TestRule"; + QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased << QVariantMap() << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorTypesNotMatching << false << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 StateEvaluator, name") << true << validActionEventBased << QVariantMap() << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleActionParameter << false << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << validActionEventBased << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action, 1 ExitAction (EventBased), name") << true << validActionNoParams << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << false << "TestRule"; @@ -358,7 +358,6 @@ void TestRules::addRemoveRules_data() QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule"; QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule"; QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError << true << "TestRule"; - QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter << false << "TestRule"; QTest::newRow("invalid action") << true << invalidAction << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorActionTypeNotFound << false << "TestRule"; QTest::newRow("invalid event descriptor") << true << validActionNoParams << QVariantMap() << invalidEventDescriptor << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorDeviceNotFound << false << "TestRule"; QTest::newRow("invalid StateDescriptor") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << invalidStateEvaluator << RuleEngine::RuleErrorInvalidParameter << true << "TestRule"; @@ -384,10 +383,10 @@ void TestRules::addRemoveRules() params.insert("actions", actions); if (!eventDescriptor.isEmpty()) { - params.insert("eventDescriptor", eventDescriptor); + params.insert("eventDescriptors", QVariantList() << eventDescriptor); } if (!eventDescriptorList.isEmpty()) { - params.insert("eventDescriptorList", eventDescriptorList); + params.insert("eventDescriptors", eventDescriptorList); } QVariantList exitActions; if (!exitAction1.isEmpty()) { @@ -587,7 +586,7 @@ void TestRules::editRules_data() QTest::newRow("invalid rule. enabled, 1 Action (eventBased), types not matching, name") << true << invalidActionEventBased3 << QVariantMap() << validEventDescriptor1 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorTypesNotMatching << "TestRule"; - QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased << QVariantMap() << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleActionParameter << "TestRule"; + QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << invalidActionEventBased << QVariantMap() << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorTypesNotMatching << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 StateEvaluator, name") << true << validActionEventBased << QVariantMap() << QVariantMap() << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorInvalidRuleActionParameter << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action (eventBased), 1 EventDescriptor, name") << true << validActionEventBased << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << "TestRule"; QTest::newRow("invalid rule. enabled, 1 Action, 1 ExitAction (EventBased), name") << true << validActionNoParams << validActionEventBased << validEventDescriptor2 << QVariantList() << QVariantMap() << RuleEngine::RuleErrorInvalidRuleFormat << "TestRule"; @@ -602,7 +601,6 @@ void TestRules::editRules_data() QTest::newRow("valid rule. enabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << "TestRule"; QTest::newRow("valid rule. diabled, 1 EventDescriptor, StateEvaluator, 1 Action, name") << false << validActionNoParams << QVariantMap() << validEventDescriptor1 << QVariantList() << validStateEvaluator << RuleEngine::RuleErrorNoError << "TestRule"; QTest::newRow("valid rule. 2 EventDescriptors, 1 Action, name") << true << validActionNoParams << QVariantMap() << QVariantMap() << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorNoError << "TestRule"; - QTest::newRow("invalid rule: eventDescriptor and eventDescriptorList used") << true << validActionNoParams << QVariantMap() << validEventDescriptor1 << eventDescriptorList << validStateEvaluator << RuleEngine::RuleErrorInvalidParameter << "TestRule"; } void TestRules::editRules() @@ -704,7 +702,7 @@ void TestRules::editRules() actions.append(action1); actions.append(action2); params.insert("actions", actions); - params.insert("eventDescriptorList", eventDescriptorList1); + params.insert("eventDescriptors", eventDescriptorList1); params.insert("stateEvaluator", stateEvaluator0); params.insert("name", "TestRule"); QVariant response = injectAndWait("Rules.AddRule", params); @@ -721,10 +719,10 @@ void TestRules::editRules() params.insert("name", name); if (!eventDescriptor.isEmpty()) { - params.insert("eventDescriptor", eventDescriptor); + params.insert("eventDescriptors", QVariantList() << eventDescriptor); } if (!eventDescriptorList.isEmpty()) { - params.insert("eventDescriptorList", eventDescriptorList); + params.insert("eventDescriptors", eventDescriptorList); } actions.clear(); actions.append(action); @@ -989,7 +987,7 @@ void TestRules::loadStoreConfig() actions.append(action1); actions.append(action2); params.insert("actions", actions); - params.insert("eventDescriptorList", eventDescriptorList); + params.insert("eventDescriptors", eventDescriptorList); params.insert("stateEvaluator", stateEvaluator1); params.insert("name", "TestRule"); QVariant response = injectAndWait("Rules.AddRule", params); @@ -1017,7 +1015,7 @@ void TestRules::loadStoreConfig() QVariantList actions3; actions3.append(validActionEventBased); params3.insert("actions", actions3); - params3.insert("eventDescriptorList", validEventDescriptors3); + params3.insert("eventDescriptors", validEventDescriptors3); params3.insert("name", "TestRule3"); QVariant response3 = injectAndWait("Rules.AddRule", params3); @@ -1223,7 +1221,7 @@ void TestRules::evaluateEvent() event1.insert("eventTypeId", mockEvent1Id); event1.insert("deviceId", m_mockDeviceId); events.append(event1); - addRuleParams.insert("eventDescriptorList", events); + addRuleParams.insert("eventDescriptors", events); QVariantList actions; QVariantMap action; @@ -1424,7 +1422,7 @@ void TestRules::enableDisableRule() event1.insert("eventTypeId", mockEvent1Id); event1.insert("deviceId", m_mockDeviceId); events.append(event1); - addRuleParams.insert("eventDescriptorList", events); + addRuleParams.insert("eventDescriptors", events); addRuleParams.insert("name", "TestRule"); QVariantList actions; @@ -1494,7 +1492,7 @@ void TestRules::testEventBasedAction() QVariantMap eventDescriptor; eventDescriptor.insert("eventTypeId", mockIntStateId); eventDescriptor.insert("deviceId", m_mockDeviceId); - addRuleParams.insert("eventDescriptor", eventDescriptor); + addRuleParams.insert("eventDescriptors", QVariantList() << eventDescriptor); addRuleParams.insert("name", "TestRule"); addRuleParams.insert("enabled", true); diff --git a/tests/auto/timemanager/testtimemanager.cpp b/tests/auto/timemanager/testtimemanager.cpp index 7f9feb26..80e81358 100644 --- a/tests/auto/timemanager/testtimemanager.cpp +++ b/tests/auto/timemanager/testtimemanager.cpp @@ -40,11 +40,11 @@ private slots: void changeTimeZone_data(); void changeTimeZone(); + void addTimeDescriptor_data(); + void addTimeDescriptor(); + }; - - - void TestTimeManager::changeTimeZone_data() { QTest::addColumn("timeZoneId");