1 /** 2 * Copyright © 2018 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 "config.h" 17 #include "manager.hpp" 18 #include "policy_find.hpp" 19 20 namespace ibm 21 { 22 namespace logging 23 { 24 25 Manager::Manager(sdbusplus::bus::bus& bus) : 26 bus(bus), 27 addMatch(bus, 28 sdbusplus::bus::match::rules::interfacesAdded() + 29 sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), 30 std::bind(std::mem_fn(&Manager::interfaceAdded), this, 31 std::placeholders::_1)), 32 removeMatch(bus, 33 sdbusplus::bus::match::rules::interfacesRemoved() + 34 sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), 35 std::bind(std::mem_fn(&Manager::interfaceRemoved), this, 36 std::placeholders::_1)) 37 #ifdef USE_POLICY_INTERFACE 38 , 39 policies(POLICY_JSON_PATH) 40 #endif 41 { 42 createAll(); 43 } 44 45 void Manager::createAll() 46 { 47 auto objects = getManagedObjects(bus, LOGGING_BUSNAME, LOGGING_PATH); 48 49 for (const auto& object : objects) 50 { 51 const auto& interfaces = object.second; 52 53 auto propertyMap = std::find_if( 54 interfaces.begin(), interfaces.end(), 55 [](const auto& i) { return i.first == LOGGING_IFACE; }); 56 57 if (propertyMap != interfaces.end()) 58 { 59 create(object.first, propertyMap->second); 60 } 61 } 62 } 63 64 void Manager::create(const std::string& objectPath, 65 const DbusPropertyMap& properties) 66 { 67 68 #ifdef USE_POLICY_INTERFACE 69 createPolicyInterface(objectPath, properties); 70 #endif 71 } 72 73 void Manager::erase(EntryID id) 74 { 75 childEntries.erase(id); 76 entries.erase(id); 77 } 78 79 void Manager::addInterface(const std::string& objectPath, InterfaceType type, 80 std::experimental::any& object) 81 { 82 auto id = getEntryID(objectPath); 83 auto entry = entries.find(id); 84 85 if (entry == entries.end()) 86 { 87 InterfaceMap interfaces; 88 interfaces.emplace(type, object); 89 entries.emplace(id, std::move(interfaces)); 90 } 91 else 92 { 93 entry->second.emplace(type, object); 94 } 95 } 96 97 void Manager::addChildInterface(const std::string& objectPath, 98 InterfaceType type, 99 std::experimental::any& object) 100 { 101 auto id = getEntryID(objectPath); 102 auto entry = childEntries.find(id); 103 104 // childEntries is: 105 // A map of error log entry IDs to: 106 // a map of interface types to: 107 // a vector of interface objects 108 109 if (entry == childEntries.end()) 110 { 111 ObjectList objects{object}; 112 InterfaceMapMulti interfaces; 113 interfaces.emplace(type, std::move(objects)); 114 childEntries.emplace(id, std::move(interfaces)); 115 } 116 else 117 { 118 auto i = entry->second.find(type); 119 if (i == entry->second.end()) 120 { 121 ObjectList objects{objects}; 122 entry->second.emplace(type, objects); 123 } 124 else 125 { 126 i->second.emplace_back(object); 127 } 128 } 129 } 130 131 #ifdef USE_POLICY_INTERFACE 132 void Manager::createPolicyInterface(const std::string& objectPath, 133 const DbusPropertyMap& properties) 134 { 135 auto values = policy::find(policies, properties); 136 137 auto object = std::make_shared<PolicyObject>(bus, objectPath.c_str(), true); 138 139 object->eventID(std::get<policy::EIDField>(values)); 140 object->description(std::get<policy::MsgField>(values)); 141 142 object->emit_object_added(); 143 144 std::experimental::any anyObject = object; 145 146 addInterface(objectPath, InterfaceType::POLICY, anyObject); 147 } 148 #endif 149 150 void Manager::interfaceAdded(sdbusplus::message::message& msg) 151 { 152 sdbusplus::message::object_path path; 153 DbusInterfaceMap interfaces; 154 155 msg.read(path, interfaces); 156 157 // Find the Logging.Entry interface with all of its properties 158 // to pass to create(). 159 auto propertyMap = 160 std::find_if(interfaces.begin(), interfaces.end(), 161 [](const auto& i) { return i.first == LOGGING_IFACE; }); 162 163 if (propertyMap != interfaces.end()) 164 { 165 create(path, propertyMap->second); 166 } 167 } 168 169 void Manager::interfaceRemoved(sdbusplus::message::message& msg) 170 { 171 sdbusplus::message::object_path path; 172 DbusInterfaceList interfaces; 173 174 msg.read(path, interfaces); 175 176 // If the Logging.Entry interface was removed, then remove 177 // our object 178 179 auto i = std::find(interfaces.begin(), interfaces.end(), LOGGING_IFACE); 180 181 if (i != interfaces.end()) 182 { 183 erase(getEntryID(path)); 184 } 185 } 186 } 187 } 188