blob: c01cdc537be9f40b67e6ee42008cb291a503e19d [file] [log] [blame]
/**
* 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<PolicyObject>(bus, objectPath.c_str(), true);
object->eventID(std::get<policy::EIDField>(values));
object->description(std::get<policy::MsgField>(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));
}
}
}
}