|  | /** | 
|  | * 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 "delete.hpp" | 
|  | #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 | 
|  |  | 
|  | // Emits the interfaces added signal. | 
|  | createDeleteInterface(objectPath); | 
|  | } | 
|  |  | 
|  | void Manager::erase(const std::string& objectPath) | 
|  | { | 
|  | auto entry = entries.find(getEntryID(objectPath)); | 
|  |  | 
|  | if (entry != entries.end()) | 
|  | { | 
|  | entries.erase(entry); | 
|  | } | 
|  | } | 
|  |  | 
|  | 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::createDeleteInterface(const std::string& objectPath) | 
|  | { | 
|  | std::experimental::any object = | 
|  | std::make_shared<Delete>(bus, objectPath, *this, false); | 
|  |  | 
|  | addInterface(objectPath, InterfaceType::DELETE, 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<PolicyObject>(bus, objectPath.c_str(), true); | 
|  |  | 
|  | object->eventID(std::get<policy::EIDField>(values)); | 
|  | object->description(std::get<policy::MsgField>(values)); | 
|  |  | 
|  | 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()) | 
|  | { | 
|  | auto id = getEntryID(path); | 
|  |  | 
|  | auto entry = entries.find(id); | 
|  | if (entry != entries.end()) | 
|  | { | 
|  | entries.erase(entry); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } |