/** * Copyright © 2018 IBM Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "manager.hpp" #include "policy_find.hpp" namespace ibm { namespace logging { Manager::Manager(sdbusplus::bus::bus& bus) : bus(bus), addMatch(bus, sdbusplus::bus::match::rules::interfacesAdded() + sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), std::bind(std::mem_fn(&Manager::interfaceAdded), this, std::placeholders::_1)), removeMatch(bus, sdbusplus::bus::match::rules::interfacesRemoved() + sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), std::bind(std::mem_fn(&Manager::interfaceRemoved), this, std::placeholders::_1)) #ifdef USE_POLICY_INTERFACE , policies(POLICY_JSON_PATH) #endif { createAll(); } void Manager::createAll() { auto objects = getManagedObjects(bus, LOGGING_BUSNAME, LOGGING_PATH); for (const auto& object : objects) { const auto& interfaces = object.second; auto propertyMap = std::find_if( interfaces.begin(), interfaces.end(), [](const auto& i) { return i.first == LOGGING_IFACE; }); if (propertyMap != interfaces.end()) { create(object.first, propertyMap->second); } } } void Manager::create(const std::string& objectPath, const DbusPropertyMap& properties) { #ifdef USE_POLICY_INTERFACE createPolicyInterface(objectPath, properties); #endif } void Manager::erase(EntryID id) { childEntries.erase(id); entries.erase(id); } void Manager::addInterface(const std::string& objectPath, InterfaceType type, std::experimental::any& object) { auto id = getEntryID(objectPath); auto entry = entries.find(id); if (entry == entries.end()) { InterfaceMap interfaces; interfaces.emplace(type, object); entries.emplace(id, std::move(interfaces)); } else { entry->second.emplace(type, object); } } void Manager::addChildInterface(const std::string& objectPath, InterfaceType type, std::experimental::any& object) { auto id = getEntryID(objectPath); auto entry = childEntries.find(id); // childEntries is: // A map of error log entry IDs to: // a map of interface types to: // a vector of interface objects if (entry == childEntries.end()) { ObjectList objects{object}; InterfaceMapMulti interfaces; interfaces.emplace(type, std::move(objects)); childEntries.emplace(id, std::move(interfaces)); } else { auto i = entry->second.find(type); if (i == entry->second.end()) { ObjectList objects{objects}; entry->second.emplace(type, objects); } else { i->second.emplace_back(object); } } } #ifdef USE_POLICY_INTERFACE void Manager::createPolicyInterface(const std::string& objectPath, const DbusPropertyMap& properties) { auto values = policy::find(policies, properties); auto object = std::make_shared(bus, objectPath.c_str(), true); object->eventID(std::get(values)); object->description(std::get(values)); object->emit_object_added(); std::experimental::any anyObject = object; addInterface(objectPath, InterfaceType::POLICY, anyObject); } #endif void Manager::interfaceAdded(sdbusplus::message::message& msg) { sdbusplus::message::object_path path; DbusInterfaceMap interfaces; msg.read(path, interfaces); // Find the Logging.Entry interface with all of its properties // to pass to create(). auto propertyMap = std::find_if(interfaces.begin(), interfaces.end(), [](const auto& i) { return i.first == LOGGING_IFACE; }); if (propertyMap != interfaces.end()) { create(path, propertyMap->second); } } void Manager::interfaceRemoved(sdbusplus::message::message& msg) { sdbusplus::message::object_path path; DbusInterfaceList interfaces; msg.read(path, interfaces); // If the Logging.Entry interface was removed, then remove // our object auto i = std::find(interfaces.begin(), interfaces.end(), LOGGING_IFACE); if (i != interfaces.end()) { erase(getEntryID(path)); } } } }