Dependency Injection for redfish-codegen, Part 4
Status of the project
I just released v0.3.1 of the redfish-codegen project. This release brings the new dependency-injection-based API that we have been working so hard on throughout this series, and it also brings support for the 2023.1 version of the Redfish data model. This version is stable enough to use for application development, though it is missing some bells and whistles–which we’ll be working towards from now on in this series.
Events
The first great missing link in the framework is a suitable solution for events. Let’s quickly review Redfish events so that we can design a solution that works in the best interest of the implementors, and meets the requirements in the standard. The Redfish Resource and Schema Guide (DSP2046) and the Redfish Data Model Specification (DSP0268) are critical documents for understanding the use within the specification.
Events are defined in a MessageRegistry. The DMTF defines a set of standard
message registries, which are available as part of DSP8011. The
redfish-codegen crate generates Rust code from these registries, which are
currently implemented as enumerations. Registries can also be provided by
a Redfish service, usually at the URL /redfish/v1/Registries
.
These events can appear in multiple locations, but the common thread is the
existence of a MessageId
property:
- A service may respond to an HTTP operation with a RedfishError. This
struct contains a
MessageId
, but it may also contain one or more Message instances, which each also contain aMessageId
property. - Events: These can be sent asynchronously to destinations configured through the EventService, or across an SSE stream.
- Log entries: From the Redfish Resource and Schema Guide (DSO2046), “The LogEntry schema defines the record format for a log. It is designed for Redfish event logs, OEM-specific log formats, and the IPMI System Event Log (SEL).” A LogService can be mounted on a compute resource–e.g. a Chassis, ComputerSystem, or Manager–via a LogServiceCollection, or at the service level by mounting on a JobService or TelemetryService instance.
Knowing now where log entries will appear in the service, let’s clarify our use cases:
- As a Redfish implementor, I want to be able to generate events from any location in the service, without needing to inject dependencies for log entry creation–logging is a cross-cutting concern, so we want to avoid polluting our code with passing around logging-related dependencies.
- As a Redfish implementor, I want the event generation mechanism to integrate seamlessly with the Rust tracing subsystem, so that I can get tracing for free (even from the standard components available in Seuss) in the applications where I choose to leverage tracing.
- As a Redfish implementor, I want to be able to write components that can receive and handle events generated by the service, so that I can dispatch Redfish events in ways not supported by the Seuss framework–e.g. by writing a custom SMTP event dispatcher or LogService.
Unfortunately, we can’t leverage the tracing
crate for this directly,
because even though the tracing macros accept structured data, this data is
converted to a string before being dispatched to the logger.
Our next available move is to take a look at how the tracing crate works, and to reason about a solution that would fulfill our use cases by potentially leveraging some similar mechanisms.