xref: /openbmc/ibm-logging/manager.cpp (revision a3c33e77)
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