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 26 GetManagedObjects::GetManagedObjects(const json& jsonObj, 27 const std::vector<Group>& groups) : 28 ActionBase(jsonObj, groups) 29 { 30 setActions(jsonObj); 31 } 32 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 std::vector<std::string> objMgrPaths; 46 47 const auto& service = 48 zone.getManager()->getService(member, group.getInterface()); 49 50 if (!service.empty()) 51 { 52 objMgrPaths = zone.getManager()->getPaths( 53 service, "org.freedesktop.DBus.ObjectManager"); 54 } 55 else 56 { 57 continue; 58 } 59 60 // Look for the ObjectManager as an ancestor of the path. 61 auto hasObjMgr = 62 std::any_of(objMgrPaths.begin(), objMgrPaths.end(), 63 [member](const auto& path) { 64 return member.find(path) != std::string::npos; 65 }); 66 67 if (!hasObjMgr || services.find(service) == services.end()) 68 { 69 if (hasObjMgr) 70 { 71 services.insert(service); 72 } 73 74 zone.getManager()->addObjects(member, group.getInterface(), 75 group.getProperty()); 76 } 77 } 78 } 79 80 // Perform the actions 81 std::for_each(_actions.begin(), _actions.end(), 82 [](auto& action) { action->run(); }); 83 } 84 85 void GetManagedObjects::setZones( 86 std::vector<std::reference_wrapper<Zone>>& zones) 87 { 88 for (auto& zone : zones) 89 { 90 this->addZone(zone); 91 // Add zone to _actions 92 std::for_each(_actions.begin(), _actions.end(), 93 [&zone](std::unique_ptr<ActionBase>& action) { 94 action->addZone(zone); 95 }); 96 } 97 } 98 99 void GetManagedObjects::setActions(const json& jsonObj) 100 { 101 if (!jsonObj.contains("actions")) 102 { 103 return; 104 } 105 106 for (const auto& jsonAct : jsonObj["actions"]) 107 { 108 if (!jsonAct.contains("name")) 109 { 110 throw ActionParseError{getName(), "Missing required action name"}; 111 } 112 113 // Get any configured profile restrictions on the action 114 std::vector<std::string> profiles; 115 if (jsonAct.contains("profiles")) 116 { 117 profiles = jsonAct["profiles"].get<std::vector<std::string>>(); 118 } 119 120 // Set the groups configured for each action run when the timer expires 121 std::vector<Group> groups; 122 Event::setGroups(jsonAct, profiles, groups); 123 124 // If no groups on that action, use our own groups instead 125 const std::vector<Group>* groupPtr = &groups; 126 if (groups.empty()) 127 { 128 groupPtr = &_groups; 129 } 130 131 // List of zones is set on these actions by overriden setZones() 132 auto actObj = ActionFactory::getAction( 133 jsonAct["name"].get<std::string>(), jsonAct, *groupPtr, {}); 134 if (actObj) 135 { 136 _actions.emplace_back(std::move(actObj)); 137 } 138 } 139 } 140 141 } // namespace phosphor::fan::control::json 142