xref: /openbmc/docs/architecture/object-mapper.md (revision 67032dffe31f98a8638927f74a7a35990d6a1fbc)
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### GetAssociatedSubTreeById
192
193Use this method to find the objects, services, and interfaces in the specified
194subtree that implement certain interfaces and endpoints that end by input `id`.
195If no interfaces are passed in, then all objects/services/interfaces in the
196subtree and associated endpoint are returned. If interfaces are passed in, then
197only those interfaces are returned in the output.
198
199Inputs:
200
201- param: id - The leaf name of the dbus path, uniquely identifying a specific
202  component or entity within the system.
203- param: objectPath - The object path for which the result should be fetched.
204- param: subtreeInterfaces - a list of interfaces to constrain the search to
205- param: association - The endpoint association.
206- param: endpointInterfaces - An array of interfaces used to filter associated
207  endpoint paths.
208
209Output:
210
211- Map of object paths to a map of service names to their interfaces that are in
212  the associated endpoints that end with `id`
213
214```text
215ID="chassis"
216ASSOCIATION="powered_by"
217dbus-send --system --print-reply \
218--dest=xyz.openbmc_project.ObjectMapper \
219/xyz/openbmc_project/object_mapper \
220xyz.openbmc_project.ObjectMapper.GetAssociatedSubTreeById \
221string:"${ID}" string:"/xyz/openbmc_project/inventory" \
222array:string:"xyz.openbmc_project.Inventory.Item.Chassis" \
223string:"${ASSOCIATION}" \
224array:string:"xyz.openbmc_project.Inventory.Item.PowerSupply"
225
226   array [
227      dict entry(
228         string "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
229         array [
230            dict entry(
231               string "xyz.openbmc_project.Inventory.Manager"
232               array [
233                  ...
234                  string "xyz.openbmc_project.Inventory.Item"
235                  string "xyz.openbmc_project.Inventory.Item.PowerSupply"
236                  ...
237               ]
238            )
239         ]
240      )
241      dict entry(
242         string "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1"
243         array [
244            dict entry(
245               string "xyz.openbmc_project.Inventory.Manager"
246               array [
247                  ...
248                  string "xyz.openbmc_project.Inventory.Item"
249                  string "xyz.openbmc_project.Inventory.Item.PowerSupply"
250                  ...
251               ]
252            )
253         ]
254      )
255      ....
256...
257
258# All output must be in the association endpoints that ends with the given `id`
259CHASSIS_PATH=/xyz/openbmc_project/inventory/system/chassis
260busctl get-property  xyz.openbmc_project.ObjectMapper \
261   /xyz/openbmc_project/inventory/system/chassis/${ASSOCIATION} \
262  xyz.openbmc_project.Association endpoints
263as N "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0" \
264"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1" \
265 ...
266```
267
268#### Example Use Case
269
270Find all object paths and services that implement a specific interface and
271endpoint of the input associationPath.
272
273### GetSubTreePaths
274
275This is the same as GetSubTree, but only returns object paths
276
277Inputs:
278
279- param: subtree - the root of the tree. Using "/" will search the whole tree
280- param: depth - the maximum depth of the tree past the root to search. Use 0 to
281  search all
282- param: interfaces - an optional list of interfaces to constrain the search to
283
284Output:
285
286- array of object paths in that subtree
287
288```
289dbus-send --system --print-reply \
290--dest=xyz.openbmc_project.ObjectMapper \
291/xyz/openbmc_project/object_mapper \
292xyz.openbmc_project.ObjectMapper.GetSubTreePaths \
293string:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
294
295   array [
296      string "/xyz/openbmc_project/sensors/current/ps0_output_current"
297      string "/xyz/openbmc_project/sensors/current/ps1_output_current"
298      string "/xyz/openbmc_project/sensors/power/ps0_input_power"
299...
300   ]
301```
302
303#### Example Use Case
304
305Find all object paths that implement a specific interface.
306
307### GetAssociatedSubTreePaths
308
309This is the same as GetAssociatedSubTreePaths, but only returns object paths
310
311Inputs:
312
313- param: associationPath - the path to look for the association endpoints.
314- param: subtree - the root of the tree. Using "/" will search the whole tree
315- param: depth - the maximum depth of the tree past the root to search. Use 0 to
316  search all
317- param: interfaces - an optional list of interfaces to constrain the search to
318
319Output:
320
321- array of object paths in that subtree that is in the associated endpoints
322
323```
324dbus-send --system --print-reply \
325--dest=xyz.openbmc_project.ObjectMapper \
326/xyz/openbmc_project/object_mapper \
327xyz.openbmc_project.ObjectMapper.GetAssociatedSubTreePaths \
328objpath:"/${ASSOCIATED_PATH}" objpath:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
329
330   array [
331      string "/xyz/openbmc_project/sensors/current/ps0_output_current"
332      string "/xyz/openbmc_project/sensors/current/ps1_output_current"
333      string "/xyz/openbmc_project/sensors/power/ps0_input_power"
334...
335   ]
336
337# All output must be in the association endpoints
338busctl get-property  xyz.openbmc_project.ObjectMapper \
339   /${ASSOCIATED_PATH} \
340  xyz.openbmc_project.Association endpoints
341as N "/xyz/openbmc_project/sensors/current/ps0_output_current" \
342  "/xyz/openbmc_project/sensors/current/ps1_output_current" \
343  "/xyz/openbmc_project/sensors/power/ps0_input_power" \
344  ...
345```
346
347#### Example Use Case
348
349Find all object paths that implement a specific interface and endpoint of the
350input associationPath.
351
352### GetAssociatedSubTreePathsById
353
354This is the same as GetAssociatedSubTreePathsById, but only returns object paths
355
356Inputs:
357
358- param: id - The leaf name of the dbus path, uniquely identifying a specific
359  component or entity within the system.
360- param: objectPath - The object path for which the result should be fetched.
361- param: subtreeInterfaces - a list of interfaces to constrain the search to
362- param: association - The endpoint association.
363- param: endpointInterfaces - An array of interfaces used to filter associated
364  endpoint paths.
365
366Output:
367
368- Map of object paths to a map of service names to their interfaces that are in
369  the associated endpoints that ends with `id`
370
371```text
372ID="chassis"
373ASSOCIATION="powered_by"
374dbus-send --system --print-reply \
375--dest=xyz.openbmc_project.ObjectMapper \
376/xyz/openbmc_project/object_mapper \
377xyz.openbmc_project.ObjectMapper.GetAssociatedSubTreePathsById \
378string:"${ID}" string:"/xyz/openbmc_project/inventory" \
379array:string:"xyz.openbmc_project.Inventory.Item.Chassis" \
380string:"${ASSOCIATION}" \
381array:string:"xyz.openbmc_project.Inventory.Item.PowerSupply"
382
383   array [
384      string "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
385      string "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1"
386       ...
387   ]
388...
389
390# All output must be in the association endpoints that ends with the given `id`
391CHASSIS_PATH=/xyz/openbmc_project/inventory/system/chassis
392busctl get-property  xyz.openbmc_project.ObjectMapper \
393   /xyz/openbmc_project/inventory/system/chassis/${ASSOCIATION} \
394  xyz.openbmc_project.Association endpoints
395as N "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0" \
396"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1" \
397 ...
398```
399
400#### Example Use Case
401
402Find all object paths that implement a specific interface and endpoint of the
403input associationPath.
404
405### GetAncestors
406
407Use this method to find all ancestors of an object that implement a specific
408interface. If no interfaces are passed in, then all ancestor
409paths/services/interfaces are returned.
410
411Inputs:
412
413- param: path - the object path to find the ancestors of
414- param: interfaces - an optional list of interfaces to constrain the search to
415
416Output:
417
418- A map of object paths to a map of services names to their interfaces
419
420```
421
422dbus-send --system --print-reply \
423--dest=xyz.openbmc_project.ObjectMapper \
424/xyz/openbmc_project/object_mapper \
425xyz.openbmc_project.ObjectMapper.GetAncestors \
426string:"/xyz/openbmc_project/inventory/system" array:string:
427
428   array [
429      dict entry(
430         string "/xyz/openbmc_project"
431         array [
432            dict entry(
433               string "xyz.openbmc_project.ObjectMapper"
434               array [
435                  string "org.freedesktop.DBus.ObjectManager"
436               ]
437            )
438         ]
439      )
440      dict entry(
441         string "/xyz/openbmc_project/inventory"
442         array [
443            dict entry(
444               string "xyz.openbmc_project.Inventory.Manager"
445               array [
446                  string "xyz.openbmc_project.Inventory.Manager"
447                  string "org.freedesktop.DBus.ObjectManager"
448               ]
449            )
450         ]
451      )
452      dict entry(
453         string "/"
454         array [
455            dict entry(
456               string "xyz.openbmc_project.Settings"
457               array [
458                  string "org.freedesktop.DBus.ObjectManager"
459               ]
460            )
461         ]
462      )
463   ]
464```
465
466#### Example Use Case
467
468Find a parent object that implements a specific interface.
469
470## Associations
471
472Associations are special D-Bus objects created by the mapper to associate two
473objects with each other. For this to occur, some application must implement the
474`xyz.openbmc_project.Association.Definitions` interface, and then when an
475association is desired, the `Associations` property on that interface needs to
476be written.
477
478This `Associations` property is an array of tuples of the form:
479
480```
481[forward, reverse, object path]
482```
483
484- forward: this is the name of the forward association object
485- reverse: this is the name of the reverse association object
486- object path: this is the other object to associate with
487
488When an object with, for example, an object path of `pathA` uses the following
489values:
490
491```
492["foo", "bar", "pathB"]
493```
494
495The mapper will create 2 new objects:
496
4971. `pathA/foo`
4982. `pathB/bar`
499
500On each of these objects, the interface `xyz.openbmc_project.Association` will
501be implemented, which has a single `endpoints` property. This property is an
502array that holds the object paths to the other end of the association.
503
504So, `pathA/foo->endpoints` will contain `pathB`, and `pathB/bar->endpoints` will
505contain `pathA`.
506
507If another object, say `pathC`, also has an association to `pathB`, then a
508second entry, `pathC`, will be added into `pathB`\'s endpoints property.
509
510These new objects will match the lifetime of the associated objects. For
511example, if `pathA` is deleted, then `pathA/foo` will also be deleted, and
512`pathA` will be removed from the endpoints property of `pathB/bar`. If that was
513the last entry in that property, then `pathB/bar` will also be deleted. In
514addition, if the endpoint path is removed from D-Bus, in this case `pathB`, then
515the mapper will remove the 2 association paths until `pathB` shows back up
516again.
517
518Note: The original name of the association definition interface was
519`org.openbmc.Associations`. While the mapper still supports this interface as
520well for the time being, new code should use the `xyz` version.
521
522#### Example Use Case
523
524Associate an error log with the inventory item that caused it.
525
526```
527# Error log
528"/xyz/openbmc_project/logging/entry/3": {
529...
530 "associations": [
531   [
532     "callout",
533     "fault",
534     "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
535   ]
536 ]
537}
538
539# Newly created forward association object
540"/xyz/openbmc_project/logging/entry/3/callout": {
541    "endpoints": [
542    "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
543    ]
544}
545
546# Newly created reverse association object
547"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0/fault": {
548    "endpoints": [
549    "/xyz/openbmc_project/logging/entry/3"
550    ]
551}
552
553```
554
555[1]:
556  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/ObjectMapper.interface.yaml
557