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 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(objMgrPaths.begin(), 64 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 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 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