-
Notifications
You must be signed in to change notification settings - Fork 11
/
association_manager.hpp
238 lines (208 loc) · 7.05 KB
/
association_manager.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#pragma once
#include "config.h"
#include "types.hpp"
#include <nlohmann/json.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <any>
#include <filesystem>
namespace phosphor
{
namespace inventory
{
namespace manager
{
namespace associations
{
static constexpr auto forwardTypePos = 0;
static constexpr auto reverseTypePos = 1;
using Types = std::tuple<std::string, std::string>;
using Paths = std::vector<std::string>;
static constexpr auto typesPos = 0;
static constexpr auto pathsPos = 1;
using EndpointsEntry = std::vector<std::tuple<Types, Paths>>;
using AssociationMap = std::map<std::string, EndpointsEntry>;
using AssociationObject = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Association::server::Definitions>;
using AssociationIfaceMap =
std::map<std::string, std::unique_ptr<AssociationObject>>;
/**
* @class Manager
*
* @brief This class provides the ability to add org.openbmc.Associations
* interfaces on inventory D-Bus objects, based on a definition in a
* JSON file.
*
* The purpose for this is to be able to associate other D-Bus paths
* with the inventory items they relate to.
*
* For example, a card temperature sensor D-Bus object can be associated
* with the D-Bus object for that card's inventory entry so that some
* code can tie them together.
*/
class Manager
{
public:
struct Condition
{
std::string path;
std::string interface;
std::string property;
std::vector<InterfaceVariantType> values;
std::filesystem::path file;
InterfaceVariantType actualValue;
};
Manager() = delete;
~Manager() = default;
Manager(const Manager&) = delete;
Manager& operator=(const Manager&) = delete;
Manager(Manager&&) = delete;
Manager& operator=(Manager&&) = delete;
/**
* @brief Constructor
*
* @param[in] bus - sdbusplus object
* @param[in] jsonPath - path to the JSON File that contains associations
*/
Manager(sdbusplus::bus_t& bus, const std::string& jsonPath);
/**
* @brief Constructor
*
* @param[in] bus - sdbusplus object
*/
explicit Manager(sdbusplus::bus_t& bus) :
Manager(bus, ASSOCIATIONS_FILE_PATH)
{}
/**
* @brief Creates any association D-Bus interfaces required based on
* the JSON associations definition for the object path passed
* in.
*
* Called after PIM creates a new inventory D-Bus interface on objectPath.
*
* @param[in] objectPath - the D-Bus object path to check for associations
* @param[in] deferSignal - whether or not to send a Properties or
* ObjectManager signal
*/
void createAssociations(const std::string& objectPath, bool deferSignal);
/**
* @brief Returned the association configuration.
* Used for testing.
*
* @return AssociationMap& - the association config
*/
const AssociationMap& getAssociationsConfig()
{
return _associations;
}
/**
* @brief Returns the list of conditions
*
* @return vector<Condition>& - The conditions
*/
std::vector<Condition>& getConditions()
{
return _conditions;
}
/**
* @brief Says if there are conditions that need to be met
* before an associations file is valid.
*
* @return bool - If there are pending conditions
*/
bool pendingCondition() const
{
return !_conditions.empty();
}
/**
* @brief Checks if a pending condition is satisfied based on the
* path, interface, and property value of the object passed
* in.
*
* If it is valid, it will load the associations pointed to
* by that condition and erase the _conditions vector as
* there are no longer any pending conditions.
*
* @param[in] objectPath - The D-Bus path of the object to check
* @param[in] in object - The interface and properties of the object
*
* @return bool - If the object matched a condition
*/
bool conditionMatch(const sdbusplus::message::object_path& objectPath,
const Object& object);
/**
* @brief Checks if a pending condition is satisfied based on if the
* actualValue field in the condition matches one of the values
* in the values field.
*
* The actualValue field was previously set by code based on the
* real property value of the specified interface on the specified
* path.
*
* If it is valid, it will load the associations pointed to
* by that condition and erase the _conditions vector as
* there are no longer any pending conditions.
*
* @return bool - If a condition was met
*/
bool conditionMatch();
private:
/**
* @brief Loads the association JSON into the _associations data
* structure.
*
* @param[in] json - The associations JSON
*/
void load(const nlohmann::json& json);
/**
* @brief Creates an instance of an org.openbmc.Associations
* interface using the passed in properties.
*
* @param[in] forwardPath - the path of the forward association
* @param[in] forwardType - the type of the forward association
* @param[in] reversePath - the path of the reverse association
* @param[in] reverseType - the type of the reverse association
* @param[in] deferSignal - whether or not to send a Properties or
* ObjectManager signal
*/
void createAssociation(const std::string& forwardPath,
const std::string& forwardType,
const std::string& reversePath,
const std::string& reverseType, bool deferSignal);
/**
* @brief Looks for all JSON files in the associations directory that
* contain a valid association condition, and loads the
* conditions into the _conditions vector.
*/
bool loadConditions();
/**
* @brief The map of association data that is loaded from its
* JSON definition. Association D-Bus objects will be
* created from this data.
*/
AssociationMap _associations;
/**
* @brief The map of org.openbmc_project.Associations D-Bus
* interfaces objects based on their object path.
*/
AssociationIfaceMap _associationIfaces;
/**
* @brief The sdbusplus bus object.
*/
sdbusplus::bus_t& _bus;
/**
* @brief The path to the associations JSON File.
*/
const std::filesystem::path _jsonFile;
/**
* A list of the inventory association paths that have already been handled.
*/
std::vector<std::string> _handled;
/**
* @brief Conditions that specify when an associations file is valid.
*/
std::vector<Condition> _conditions;
};
} // namespace associations
} // namespace manager
} // namespace inventory
} // namespace phosphor