xref: /openbmc/phosphor-fan-presence/control/json/actions/get_managed_objects.cpp (revision d0ba86a3a5deb0157bddee5cbc254ad248615e9c)
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 #include <iostream>
22 
23 namespace phosphor::fan::control::json
24 {
25 
26 using json = nlohmann::json;
27 
28 GetManagedObjects::GetManagedObjects(const json& jsonObj,
29                                      const std::vector<Group>& groups) :
30     ActionBase(jsonObj, groups)
31 {
32     setActions(jsonObj);
33 }
34 
35 void GetManagedObjects::run(Zone& zone)
36 {
37     std::set<std::string> services;
38 
39     // Call Manager::addObjects to refresh the values of the group members.
40     // If there is an ObjectManager interface that handles them, then
41     // the code can combine all members in the same service down to one call.
42     // If no ObjectManager, then still need addObjects calls for each.
43     for (const auto& group : _groups)
44     {
45         for (const auto& member : group.getMembers())
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 =
64                 std::any_of(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     }
81 
82     // Perform the actions
83     std::for_each(_actions.begin(), _actions.end(),
84                   [](auto& action) { action->run(); });
85 }
86 
87 void GetManagedObjects::setZones(
88     std::vector<std::reference_wrapper<Zone>>& zones)
89 {
90     for (auto& zone : zones)
91     {
92         this->addZone(zone);
93         // Add zone to _actions
94         std::for_each(_actions.begin(), _actions.end(),
95                       [&zone](std::unique_ptr<ActionBase>& action) {
96                           action->addZone(zone);
97                       });
98     }
99 }
100 
101 void GetManagedObjects::setActions(const json& jsonObj)
102 {
103     if (!jsonObj.contains("actions"))
104     {
105         return;
106     }
107 
108     for (const auto& jsonAct : jsonObj["actions"])
109     {
110         if (!jsonAct.contains("name"))
111         {
112             throw ActionParseError{getName(), "Missing required action name"};
113         }
114 
115         // Get any configured profile restrictions on the action
116         std::vector<std::string> profiles;
117         if (jsonAct.contains("profiles"))
118         {
119             profiles = jsonAct["profiles"].get<std::vector<std::string>>();
120         }
121 
122         // Set the groups configured for each action run when the timer expires
123         std::vector<Group> groups;
124         Event::setGroups(jsonAct, profiles, groups);
125 
126         // If no groups on that action, use our own groups instead
127         const std::vector<Group>* groupPtr = &groups;
128         if (groups.empty())
129         {
130             groupPtr = &_groups;
131         }
132 
133         // List of zones is set on these actions by overriden setZones()
134         auto actObj = ActionFactory::getAction(
135             jsonAct["name"].get<std::string>(), jsonAct, *groupPtr, {});
136         if (actObj)
137         {
138             _actions.emplace_back(std::move(actObj));
139         }
140     }
141 }
142 
143 } // namespace phosphor::fan::control::json
144