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