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