1 /**
2 * Copyright © 2021 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "get_managed_objects.hpp"
17
18 #include "../manager.hpp"
19 #include "event.hpp"
20
21 namespace phosphor::fan::control::json
22 {
23
24 using json = nlohmann::json;
25
GetManagedObjects(const json & jsonObj,const std::vector<Group> & groups)26 GetManagedObjects::GetManagedObjects(const json& jsonObj,
27 const std::vector<Group>& groups) :
28 ActionBase(jsonObj, groups)
29 {
30 setActions(jsonObj);
31 }
32
run(Zone & zone)33 void GetManagedObjects::run(Zone& zone)
34 {
35 std::set<std::string> services;
36
37 // Call Manager::addObjects to refresh the values of the group members.
38 // If there is an ObjectManager interface that handles them, then
39 // the code can combine all members in the same service down to one call.
40 // If no ObjectManager, then still need addObjects calls for each.
41 for (const auto& group : _groups)
42 {
43 for (const auto& member : group.getMembers())
44 {
45 try
46 {
47 std::vector<std::string> objMgrPaths;
48
49 const auto& service =
50 zone.getManager()->getService(member, group.getInterface());
51
52 if (!service.empty())
53 {
54 objMgrPaths = zone.getManager()->getPaths(
55 service, "org.freedesktop.DBus.ObjectManager");
56 }
57 else
58 {
59 continue;
60 }
61
62 // Look for the ObjectManager as an ancestor of the path.
63 auto hasObjMgr = std::any_of(
64 objMgrPaths.begin(), objMgrPaths.end(),
65 [member](const auto& path) {
66 return member.find(path) != std::string::npos;
67 });
68
69 if (!hasObjMgr || services.find(service) == services.end())
70 {
71 if (hasObjMgr)
72 {
73 services.insert(service);
74 }
75
76 zone.getManager()->addObjects(member, group.getInterface(),
77 group.getProperty());
78 }
79 }
80 catch (const std::exception& e)
81 {
82 // May have been called from a name_owner_changed trigger
83 // and the service may have been lost.
84 }
85 }
86 }
87
88 // Perform the actions
89 std::for_each(_actions.begin(), _actions.end(),
90 [](auto& action) { action->run(); });
91 }
92
setZones(std::vector<std::reference_wrapper<Zone>> & zones)93 void GetManagedObjects::setZones(
94 std::vector<std::reference_wrapper<Zone>>& zones)
95 {
96 for (auto& zone : zones)
97 {
98 this->addZone(zone);
99 // Add zone to _actions
100 std::for_each(_actions.begin(), _actions.end(),
101 [&zone](std::unique_ptr<ActionBase>& action) {
102 action->addZone(zone);
103 });
104 }
105 }
106
setActions(const json & jsonObj)107 void GetManagedObjects::setActions(const json& jsonObj)
108 {
109 if (!jsonObj.contains("actions"))
110 {
111 return;
112 }
113
114 for (const auto& jsonAct : jsonObj["actions"])
115 {
116 if (!jsonAct.contains("name"))
117 {
118 throw ActionParseError{getName(), "Missing required action name"};
119 }
120
121 // Get any configured profile restrictions on the action
122 std::vector<std::string> profiles;
123 if (jsonAct.contains("profiles"))
124 {
125 profiles = jsonAct["profiles"].get<std::vector<std::string>>();
126 }
127
128 // Set the groups configured for each action run when the timer expires
129 std::vector<Group> groups;
130 Event::setGroups(jsonAct, profiles, groups);
131
132 // If no groups on that action, use our own groups instead
133 const std::vector<Group>* groupPtr = &groups;
134 if (groups.empty())
135 {
136 groupPtr = &_groups;
137 }
138
139 // List of zones is set on these actions by overriden setZones()
140 auto actObj = ActionFactory::getAction(
141 jsonAct["name"].get<std::string>(), jsonAct, *groupPtr, {});
142 if (actObj)
143 {
144 _actions.emplace_back(std::move(actObj));
145 }
146 }
147 }
148
149 } // namespace phosphor::fan::control::json
150