1# The ObjectMapper
2
3The `xyz.openbmc_project.ObjectMapper` service, commonly referred to as just the
4mapper, is an OpenBMC application that attempts to ease the pain of using D-Bus
5by providing APIs that help in discovering and associating other D-Bus objects.
6
7The mapper has two major pieces of functionality:
8
9- [Methods](#methods) - Provides D-Bus discovery related functionality.
10- [Associations](#associations) - Associates two different objects with each
11  other.
12
13## Methods
14
15The official YAML interface definition can be found [here][1].
16
17### GetObject
18
19Use this method to find the services, with their interfaces, that implement a
20certain object path. The output is a map of service names to their implemented
21interfaces. An optional list of interfaces may also be passed in to constrain
22the output to services that implement those specific interfaces.
23
24Inputs:
25
26- path: object path
27- param: interfaces - an optional list of interfaces to constrain the search to
28
29Output:
30
31- Map of service names to their interfaces
32
33```
34dbus-send --system --print-reply \
35--dest=xyz.openbmc_project.ObjectMapper \
36/xyz/openbmc_project/object_mapper \
37xyz.openbmc_project.ObjectMapper.GetObject \
38string:"/xyz/openbmc_project/sensors/voltage/ps1_input_voltage" array:string:
39
40   array [
41      dict entry(
42         string "xyz.openbmc_project.Hwmon-1025936882.Hwmon1"
43         array [
44            string "xyz.openbmc_project.Sensor.Threshold.Critical"
45            string "xyz.openbmc_project.Sensor.Threshold.Warning"
46            string "xyz.openbmc_project.Sensor.Value"
47         ]
48      )
49   ]
50```
51
52#### Example Use Case
53
54Find the service name that has the desired object path so it can be passed into
55a get property call.
56
57### GetSubTree
58
59Use this method to find the objects, services, and interfaces in the specified
60subtree that implement a certain interface. If no interfaces are passed in, then
61all objects/services/interfaces in the subtree are returned. If interfaces are
62passed in, then only those interfaces are returned in the output.
63
64Inputs:
65
66- param: subtree - the root of the tree. Using "/" will search the whole tree
67- param: depth - the maximum depth of the tree past the root to search. Use 0 to
68  search all
69- param: interfaces - an optional list of interfaces to constrain the search to
70
71Output:
72
73- Map of object paths to a map of service names to their interfaces
74
75```
76dbus-send --system --print-reply \
77--dest=xyz.openbmc_project.ObjectMapper \
78/xyz/openbmc_project/object_mapper \
79xyz.openbmc_project.ObjectMapper.GetSubTree \
80string:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
81
82   array [
83      dict entry(
84         string "/xyz/openbmc_project/sensors/current/ps0_output_current"
85         array [
86            dict entry(
87               string "xyz.openbmc_project.Hwmon-1040041051.Hwmon1"
88               array [
89                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
90                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
91                  string "xyz.openbmc_project.Sensor.Value"
92               ]
93            )
94         ]
95      )
96      dict entry(
97         string "/xyz/openbmc_project/sensors/current/ps1_output_current"
98         array [
99            dict entry(
100               string "xyz.openbmc_project.Hwmon-1025936882.Hwmon1"
101               array [
102                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
103                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
104                  string "xyz.openbmc_project.Sensor.Value"
105               ]
106            )
107         ]
108      )
109...
110
111```
112
113#### Example Use Case
114
115Find all object paths and services that implement a specific interface.
116
117### GetAssociatedSubTree
118
119Use this method to find the objects, services, and interfaces in the specified
120subtree that implement a certain interface and an endpoint of the input
121associationPath. If no interfaces are passed in, then all
122objects/services/interfaces in the subtree and associated endpoint are returned.
123If interfaces are passed in, then only those interfaces are returned in the
124output.
125
126Inputs:
127
128- param: associationPath - the path to look for the association endpoints.
129- param: subtree - the root of the tree. Using "/" will search the whole tree
130- param: depth - the maximum depth of the tree past the root to search. Use 0 to
131  search all
132- param: interfaces - an optional list of interfaces to constrain the search to
133
134Output:
135
136- Map of object paths to a map of service names to their interfaces that is in
137  the associated endpoints
138
139```
140dbus-send --system --print-reply \
141--dest=xyz.openbmc_project.ObjectMapper \
142/xyz/openbmc_project/object_mapper \
143xyz.openbmc_project.ObjectMapper.GetAssociatedSubTree \
144objpath:"/${ASSOCIATED_PATH}" \
145objpath:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
146
147   array [
148      dict entry(
149         string "/xyz/openbmc_project/sensors/current/ps0_output_current"
150         array [
151            dict entry(
152               string "xyz.openbmc_project.Hwmon-1040041051.Hwmon1"
153               array [
154                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
155                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
156                  string "xyz.openbmc_project.Sensor.Value"
157               ]
158            )
159         ]
160      )
161      dict entry(
162         string "/xyz/openbmc_project/sensors/current/ps1_output_current"
163         array [
164            dict entry(
165               string "xyz.openbmc_project.Hwmon-1025936882.Hwmon1"
166               array [
167                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
168                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
169                  string "xyz.openbmc_project.Sensor.Value"
170               ]
171            )
172         ]
173      )
174...
175
176
177# All output must be in the association endpoints
178busctl get-property  xyz.openbmc_project.ObjectMapper \
179   /${ASSOCIATED_PATH} \
180  xyz.openbmc_project.Association endpoints
181as N "/xyz/openbmc_project/sensors/current/ps0_output_current" \
182  "/xyz/openbmc_project/sensors/current/ps1_output_current" \
183  ...
184```
185
186#### Example Use Case
187
188Find all object paths and services that implement a specific interface and
189endpoint of the input associationPath.
190
191### GetSubTreePaths
192
193This is the same as GetSubTree, but only returns object paths
194
195Inputs:
196
197- param: subtree - the root of the tree. Using "/" will search the whole tree
198- param: depth - the maximum depth of the tree past the root to search. Use 0 to
199  search all
200- param: interfaces - an optional list of interfaces to constrain the search to
201
202Output:
203
204- array of object paths in that subtree
205
206```
207dbus-send --system --print-reply \
208--dest=xyz.openbmc_project.ObjectMapper \
209/xyz/openbmc_project/object_mapper \
210xyz.openbmc_project.ObjectMapper.GetSubTreePaths \
211string:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
212
213   array [
214      string "/xyz/openbmc_project/sensors/current/ps0_output_current"
215      string "/xyz/openbmc_project/sensors/current/ps1_output_current"
216      string "/xyz/openbmc_project/sensors/power/ps0_input_power"
217...
218   ]
219```
220
221#### Example Use Case
222
223Find all object paths that implement a specific interface.
224
225### GetAssociatedSubTreePaths
226
227This is the same as GetAssociatedSubTreePaths, but only returns object paths
228
229Inputs:
230
231- param: associationPath - the path to look for the association endpoints.
232- param: subtree - the root of the tree. Using "/" will search the whole tree
233- param: depth - the maximum depth of the tree past the root to search. Use 0 to
234  search all
235- param: interfaces - an optional list of interfaces to constrain the search to
236
237Output:
238
239- array of object paths in that subtree that is in the associated endpoints
240
241```
242dbus-send --system --print-reply \
243--dest=xyz.openbmc_project.ObjectMapper \
244/xyz/openbmc_project/object_mapper \
245xyz.openbmc_project.ObjectMapper.GetAssociatedSubTreePaths \
246objpath:"/${ASSOCIATED_PATH}" objpath:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
247
248   array [
249      string "/xyz/openbmc_project/sensors/current/ps0_output_current"
250      string "/xyz/openbmc_project/sensors/current/ps1_output_current"
251      string "/xyz/openbmc_project/sensors/power/ps0_input_power"
252...
253   ]
254
255# All output must be in the association endpoints
256busctl get-property  xyz.openbmc_project.ObjectMapper \
257   /${ASSOCIATED_PATH} \
258  xyz.openbmc_project.Association endpoints
259as N "/xyz/openbmc_project/sensors/current/ps0_output_current" \
260  "/xyz/openbmc_project/sensors/current/ps1_output_current" \
261  "/xyz/openbmc_project/sensors/power/ps0_input_power" \
262  ...
263```
264
265#### Example Use Case
266
267Find all object paths that implement a specific interface and endpoint of the
268input associationPath.
269
270### GetAncestors
271
272Use this method to find all ancestors of an object that implement a specific
273interface. If no interfaces are passed in, then all ancestor
274paths/services/interfaces are returned.
275
276Inputs:
277
278- param: path - the object path to find the ancestors of
279- param: interfaces - an optional list of interfaces to constrain the search to
280
281Output:
282
283- A map of object paths to a map of services names to their interfaces
284
285```
286
287dbus-send --system --print-reply \
288--dest=xyz.openbmc_project.ObjectMapper \
289/xyz/openbmc_project/object_mapper \
290xyz.openbmc_project.ObjectMapper.GetAncestors \
291string:"/xyz/openbmc_project/inventory/system" array:string:
292
293   array [
294      dict entry(
295         string "/xyz/openbmc_project"
296         array [
297            dict entry(
298               string "xyz.openbmc_project.ObjectMapper"
299               array [
300                  string "org.freedesktop.DBus.ObjectManager"
301               ]
302            )
303         ]
304      )
305      dict entry(
306         string "/xyz/openbmc_project/inventory"
307         array [
308            dict entry(
309               string "xyz.openbmc_project.Inventory.Manager"
310               array [
311                  string "xyz.openbmc_project.Inventory.Manager"
312                  string "org.freedesktop.DBus.ObjectManager"
313               ]
314            )
315         ]
316      )
317      dict entry(
318         string "/"
319         array [
320            dict entry(
321               string "xyz.openbmc_project.Settings"
322               array [
323                  string "org.freedesktop.DBus.ObjectManager"
324               ]
325            )
326         ]
327      )
328   ]
329```
330
331#### Example Use Case
332
333Find a parent object that implements a specific interface.
334
335## Associations
336
337Associations are special D-Bus objects created by the mapper to associate two
338objects with each other. For this to occur, some application must implement the
339`xyz.openbmc_project.Association.Definitions` interface, and then when an
340association is desired, the `Associations` property on that interface needs to
341be written.
342
343This `Associations` property is an array of tuples of the form:
344
345```
346[forward, reverse, object path]
347```
348
349- forward: this is the name of the forward association object
350- reverse: this is the name of the reverse association object
351- object path: this is the other object to associate with
352
353When an object with, for example, an object path of `pathA` uses the following
354values:
355
356```
357["foo", "bar", "pathB"]
358```
359
360The mapper will create 2 new objects:
361
3621. `pathA/foo`
3632. `pathB/bar`
364
365On each of these objects, the interface `xyz.openbmc_project.Association` will
366be implemented, which has a single `endpoints` property. This property is an
367array that holds the object paths to the other end of the association.
368
369So, `pathA/foo->endpoints` will contain `pathB`, and `pathB/bar->endpoints` will
370contain `pathA`.
371
372If another object, say `pathC`, also has an association to `pathB`, then a
373second entry, `pathC`, will be added into `pathB`\'s endpoints property.
374
375These new objects will match the lifetime of the associated objects. For
376example, if `pathA` is deleted, then `pathA/foo` will also be deleted, and
377`pathA` will be removed from the endpoints property of `pathB/bar`. If that was
378the last entry in that property, then `pathB/bar` will also be deleted. In
379addition, if the endpoint path is removed from D-Bus, in this case `pathB`, then
380the mapper will remove the 2 association paths until `pathB` shows back up
381again.
382
383Note: The original name of the association definition interface was
384`org.openbmc.Associations`. While the mapper still supports this interface as
385well for the time being, new code should use the `xyz` version.
386
387#### Example Use Case
388
389Associate an error log with the inventory item that caused it.
390
391```
392# Error log
393"/xyz/openbmc_project/logging/entry/3": {
394...
395 "associations": [
396   [
397     "callout",
398     "fault",
399     "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
400   ]
401 ]
402}
403
404# Newly created forward association object
405"/xyz/openbmc_project/logging/entry/3/callout": {
406    "endpoints": [
407    "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
408    ]
409}
410
411# Newly created reverse association object
412"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0/fault": {
413    "endpoints": [
414    "/xyz/openbmc_project/logging/entry/3"
415    ]
416}
417
418```
419
420[1]:
421  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/ObjectMapper.interface.yaml
422