control: Use event groups on `signal` triggers
Use the provided event groups when enabling any `signal` triggers
instead of the action groups. Event groups are what's used with setting
up event triggers and may or may not be a different set of groups than
what's used when actions are run depending on event configuration.
Change-Id: I78b6255ada52ed718469a6700b4bc2603b2a85cb
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/manager.hpp b/control/json/manager.hpp
index eb5a6ca..86e47dd 100644
--- a/control/json/manager.hpp
+++ b/control/json/manager.hpp
@@ -83,8 +83,7 @@
constexpr auto Prop = 2;
using SignalObject = std::tuple<std::string, std::string, std::string>;
/* Dbus signal actions */
-using SignalActions =
- std::vector<std::reference_wrapper<std::unique_ptr<ActionBase>>>;
+using SignalActions = std::vector<std::unique_ptr<ActionBase>>&;
/**
* Signal handler function that handles parsing a signal's message for a
* particular signal object and stores the results in the manager
diff --git a/control/json/triggers/signal.cpp b/control/json/triggers/signal.cpp
index 075697f..b39bc4a 100644
--- a/control/json/triggers/signal.cpp
+++ b/control/json/triggers/signal.cpp
@@ -74,12 +74,13 @@
{
if (isSameSig(pkg))
{
- // Same signal expected, add action to be run when signal
+ // Same signal expected, add actions to be run when signal
// received
auto& pkgActions = std::get<SignalActions>(signalPkg);
auto& actions = std::get<SignalActions>(pkg);
- // Only one action is given on the signal package passed in
- actions.push_back(pkgActions.front());
+ actions.insert(actions.end(),
+ std::make_move_iterator(pkgActions.begin()),
+ std::make_move_iterator(pkgActions.end()));
}
else
{
@@ -90,131 +91,117 @@
}
}
-void propertiesChanged(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void propertiesChanged(Manager* mgr, const Group& group, SignalActions actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
// will do nothing since signals require a group
- for (const auto& group : action->getGroups())
+ for (const auto& member : group.getMembers())
{
- for (const auto& member : group.getMembers())
- {
- // Setup property changed signal handler on the group member's
- // property
- const auto match =
- rules::propertiesChanged(member, group.getInterface());
- SignalPkg signalPkg = {Handlers::propertiesChanged,
- SignalObject(std::cref(member),
- std::cref(group.getInterface()),
- std::cref(group.getProperty())),
- SignalActions({action})};
- auto isSameSig = [&prop = group.getProperty()](SignalPkg& pkg) {
- auto& obj = std::get<SignalObject>(pkg);
- return prop == std::get<Prop>(obj);
- };
+ // Setup property changed signal handler on the group member's
+ // property
+ const auto match =
+ rules::propertiesChanged(member, group.getInterface());
+ SignalPkg signalPkg = {Handlers::propertiesChanged,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions(actions)};
+ auto isSameSig = [&prop = group.getProperty()](SignalPkg& pkg) {
+ auto& obj = std::get<SignalObject>(pkg);
+ return prop == std::get<Prop>(obj);
+ };
- subscribe(match, std::move(signalPkg), isSameSig, mgr);
- }
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
}
}
-void interfacesAdded(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void interfacesAdded(Manager* mgr, const Group& group, SignalActions actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
// will do nothing since signals require a group
- for (const auto& group : action->getGroups())
+ for (const auto& member : group.getMembers())
{
- for (const auto& member : group.getMembers())
- {
- // Setup interfaces added signal handler on the group member
- const auto match = rules::interfacesAdded(member);
- SignalPkg signalPkg = {Handlers::interfacesAdded,
- SignalObject(std::cref(member),
- std::cref(group.getInterface()),
- std::cref(group.getProperty())),
- SignalActions({action})};
- auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
- auto& obj = std::get<SignalObject>(pkg);
- return intf == std::get<Intf>(obj);
- };
+ // Setup interfaces added signal handler on the group member
+ const auto match = rules::interfacesAdded(member);
+ SignalPkg signalPkg = {Handlers::interfacesAdded,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions(actions)};
+ auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
+ auto& obj = std::get<SignalObject>(pkg);
+ return intf == std::get<Intf>(obj);
+ };
- subscribe(match, std::move(signalPkg), isSameSig, mgr);
- }
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
}
}
-void interfacesRemoved(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void interfacesRemoved(Manager* mgr, const Group& group, SignalActions actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
// will do nothing since signals require a group
- for (const auto& group : action->getGroups())
+ for (const auto& member : group.getMembers())
{
- for (const auto& member : group.getMembers())
- {
- // Setup interfaces added signal handler on the group member
- const auto match = rules::interfacesRemoved(member);
- SignalPkg signalPkg = {Handlers::interfacesRemoved,
- SignalObject(std::cref(member),
- std::cref(group.getInterface()),
- std::cref(group.getProperty())),
- SignalActions({action})};
- auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
- auto& obj = std::get<SignalObject>(pkg);
- return intf == std::get<Intf>(obj);
- };
+ // Setup interfaces added signal handler on the group member
+ const auto match = rules::interfacesRemoved(member);
+ SignalPkg signalPkg = {Handlers::interfacesRemoved,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions(actions)};
+ auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
+ auto& obj = std::get<SignalObject>(pkg);
+ return intf == std::get<Intf>(obj);
+ };
- subscribe(match, std::move(signalPkg), isSameSig, mgr);
- }
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
}
}
-void nameOwnerChanged(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
// will do nothing since signals require a group
- for (const auto& group : action->getGroups())
+ for (const auto& member : group.getMembers())
{
- for (const auto& member : group.getMembers())
+ auto serv = Manager::getService(member, group.getInterface());
+ if (!serv.empty())
{
- auto serv = Manager::getService(member, group.getInterface());
- if (!serv.empty())
- {
- // Setup name owner changed signal handler on the group
- // member's service
- const auto match = rules::nameOwnerChanged(serv);
- SignalPkg signalPkg = {
- Handlers::nameOwnerChanged,
- SignalObject(std::cref(member),
- std::cref(group.getInterface()),
- std::cref(group.getProperty())),
- SignalActions({action})};
- // If signal match already exists, then the service will be the
- // same so add action to be run
- auto isSameSig = [](SignalPkg& pkg) { return true; };
+ // Setup name owner changed signal handler on the group
+ // member's service
+ const auto match = rules::nameOwnerChanged(serv);
+ SignalPkg signalPkg = {Handlers::nameOwnerChanged,
+ SignalObject(std::cref(member),
+ std::cref(group.getInterface()),
+ std::cref(group.getProperty())),
+ SignalActions(actions)};
+ // If signal match already exists, then the service will be the
+ // same so add action to be run
+ auto isSameSig = [](SignalPkg& pkg) { return true; };
- subscribe(match, std::move(signalPkg), isSameSig, mgr);
- }
- else
- {
- // Unable to construct nameOwnerChanged match string
- // Path and/or interface configured does not exist on dbus yet?
- // TODO How to handle this? Create timer to keep checking for
- // service to appear? When to stop checking?
- log<level::ERR>(
- fmt::format(
- "Events will not be triggered by name owner changed"
- "signals from service of path {}, interface {}",
- member, group.getInterface())
- .c_str());
- }
+ subscribe(match, std::move(signalPkg), isSameSig, mgr);
+ }
+ else
+ {
+ // Unable to construct nameOwnerChanged match string
+ // Path and/or interface configured does not exist on dbus yet?
+ // TODO How to handle this? Create timer to keep checking for
+ // service to appear? When to stop checking?
+ log<level::ERR>(
+ fmt::format("Events will not be triggered by name owner changed"
+ "signals from service of path {}, interface {}",
+ member, group.getInterface())
+ .c_str());
}
}
}
-void member(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void member(Manager* mgr, const Group&, SignalActions actions,
const json& jsonObj)
{
if (!jsonObj.contains("member") || !jsonObj["member"].contains("name") ||
@@ -232,7 +219,7 @@
rules::interface(jsonObj["member"]["interface"].get<std::string>());
// No SignalObject required to associate to this signal
SignalPkg signalPkg = {Handlers::member, SignalObject(),
- SignalActions({action})};
+ SignalActions(actions)};
// If signal match already exists, then the member signal will be the
// same so add action to be run
auto isSameSig = [](SignalPkg& pkg) { return true; };
@@ -240,7 +227,7 @@
}
enableTrigger triggerSignal(const json& jsonObj, const std::string& eventName,
- std::vector<std::unique_ptr<ActionBase>>& actions)
+ SignalActions actions)
{
auto subscriber = signals.end();
if (jsonObj.contains("signal"))
@@ -269,10 +256,10 @@
jsonObj](const std::string& eventName, Manager* mgr,
const std::vector<Group>& groups,
std::vector<std::unique_ptr<ActionBase>>& actions) {
- for (auto& action : actions)
+ for (const auto& group : groups)
{
- // Call signal subscriber for each group in the action
- subscriber->second(mgr, action, jsonObj);
+ // Call signal subscriber for each group
+ subscriber->second(mgr, group, actions, jsonObj);
}
};
}
diff --git a/control/json/triggers/signal.hpp b/control/json/triggers/signal.hpp
index 2030a5d..881673a 100644
--- a/control/json/triggers/signal.hpp
+++ b/control/json/triggers/signal.hpp
@@ -37,6 +37,7 @@
*
* @param[in] match - Signal match string to subscribe to
* @param[in] pkg - Data package to attach to signal
+ * @param[in] isSameSig - Function to determine if same signal being subscribed
* @param[in] mgr - Pointer to manager of the trigger
*/
void subscribe(const std::string& match, SignalPkg&& pkg,
@@ -46,51 +47,56 @@
* @brief Subscribes to a propertiesChanged signal
*
* @param[in] mgr - Pointer to manager of the trigger
- * @param[in] action - Action to be run when signal is received
+ * @param[in] group - Group to subscribe signal against
+ * @param[in] actions - Actions to be run when signal is received
*/
-void propertiesChanged(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void propertiesChanged(Manager* mgr, const Group& group, SignalActions actions,
const json&);
/**
* @brief Subscribes to an interfacesAdded signal
*
* @param[in] mgr - Pointer to manager of the trigger
- * @param[in] action - Action to be run when signal is received
+ * @param[in] group - Group to subscribe signal against
+ * @param[in] actions - Actions to be run when signal is received
*/
-void interfacesAdded(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void interfacesAdded(Manager* mgr, const Group& group, SignalActions actions,
const json&);
/**
* @brief Subscribes to an interfacesRemoved signal
*
* @param[in] mgr - Pointer to manager of the trigger
- * @param[in] action - Action to be run when signal is received
+ * @param[in] group - Group to subscribe signal against
+ * @param[in] actions - Actions to be run when signal is received
*/
-void interfacesRemoved(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void interfacesRemoved(Manager* mgr, const Group& group, SignalActions actions,
const json&);
/**
* @brief Subscribes to a nameOwnerChanged signal
*
* @param[in] mgr - Pointer to manager of the trigger
- * @param[in] action - Action to be run when signal is received
+ * @param[in] group - Group to subscribe signal against
+ * @param[in] actions - Actions to be run when signal is received
*/
-void nameOwnerChanged(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions actions,
const json&);
/**
* @brief Subscribes to a dbus member signal
*
* @param[in] mgr - Pointer to manager of the trigger
- * @param[in] action - Action to be run when signal is received
+ * @param[in] group - Group to subscribe signal against
+ * @param[in] actions - Actions to be run when signal is received
* @param[in] jsonObj - JSON object for the trigger
*/
-void member(Manager* mgr, std::unique_ptr<ActionBase>& action,
+void member(Manager* mgr, const Group&, SignalActions actions,
const json& jsonObj);
// Match setup function for signals
-using SignalMatch = std::function<void(
- Manager*, std::unique_ptr<ActionBase>& action, const json&)>;
+using SignalMatch = std::function<void(Manager*, const Group&,
+ SignalActions actions, const json&)>;
/* Supported signals to their corresponding match setup functions */
static const std::unordered_map<std::string, SignalMatch> signals = {
@@ -112,6 +118,6 @@
* configuration, is received.
*/
enableTrigger triggerSignal(const json& jsonObj, const std::string& eventName,
- std::vector<std::unique_ptr<ActionBase>>& actions);
+ SignalActions actions);
} // namespace phosphor::fan::control::json::trigger::signal