nv_redfish_core/bmc.rs
1// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Baseboard Management Controller (BMC) client abstraction
17//!
18//! This module defines the transport-agnostic [`Bmc`] trait — a minimal
19//! interface for interacting with Redfish services. Implementors provide
20//! asynchronous operations to retrieve and expand entities, create/update
21//! resources, delete entities, and invoke actions.
22//!
23//! Key concepts:
24//! - Entity identity: Every entity is identified by an `@odata.id` ([`crate::ODataId`]).
25//! - Entity reference: Generated types implement [`crate::EntityTypeRef`], which
26//! exposes `id()` and optional `etag()` accessors.
27//! - Arc-based sharing: Read operations return `Arc<T>` to enable cheap sharing
28//! and caching while keeping values immutable.
29//! - Expansion: [`crate::Expandable`] entities can request inline expansion using
30//! [`crate::query::ExpandQuery`], matching Redfish DSP0266 semantics for `$expand`.
31//! - Actions: Actions are described by [`crate::Action<T, R>`] and are invoked via
32//! the `action` method.
33//!
34//! Operation semantics:
35//! - `get` fetches the entity at the given `@odata.id`.
36//! - `expand` fetches the entity with the provided `$expand` query.
37//! - `create` typically performs a POST to a collection identified by `id` and
38//! returns the server-provided representation (`R`).
39//! - `update` typically performs a PATCH on an entity identified by `id` and
40//! returns the updated representation (`R`).
41//! - `delete` removes the entity at `id`.
42//! - `action` posts to an action endpoint (`Action.target`).
43//!
44//! Notes for implementors:
45//! - The trait is `Send + Sync` and returns `Send` futures to support use in
46//! async runtimes and multithreaded contexts.
47//! - Implementations may include client-side caching or conditional requests;
48//! these details are intentionally abstracted behind the trait.
49//! - Errors should implement `std::error::Error` and be safely transferable
50//! across threads.
51
52use serde::Deserialize;
53use serde::Serialize;
54
55use crate::query::ExpandQuery;
56use crate::Action;
57use crate::Empty;
58use crate::EntityTypeRef;
59use crate::Expandable;
60use crate::FilterQuery;
61use crate::ODataETag;
62use crate::ODataId;
63use std::error::Error as StdError;
64use std::future::Future;
65use std::sync::Arc;
66
67/// BMC trait defines access to a Baseboard Management Controller using
68/// the Redfish protocol.
69pub trait Bmc: Send + Sync {
70 /// BMC Error.
71 type Error: StdError + Send + Sync;
72
73 /// Expand any expandable object (navigation property or entity).
74 ///
75 /// `T` is structure that is used for return type.
76 fn expand<T: Expandable + Send + Sync + 'static>(
77 &self,
78 id: &ODataId,
79 query: ExpandQuery,
80 ) -> impl Future<Output = Result<Arc<T>, Self::Error>> + Send;
81
82 /// Get data of the object (navigation property or entity).
83 ///
84 /// `T` is structure that is used for return type.
85 fn get<T: EntityTypeRef + Sized + for<'a> Deserialize<'a> + 'static + Send + Sync>(
86 &self,
87 id: &ODataId,
88 ) -> impl Future<Output = Result<Arc<T>, Self::Error>> + Send;
89
90 /// Get and filters data of the object (navigation property or entity).
91 ///
92 /// `T` is structure that is used for return type.
93 fn filter<T: EntityTypeRef + Sized + for<'a> Deserialize<'a> + 'static + Send + Sync>(
94 &self,
95 id: &ODataId,
96 query: FilterQuery,
97 ) -> impl Future<Output = Result<Arc<T>, Self::Error>> + Send;
98
99 /// Creates element of the collection.
100 ///
101 /// `V` is structure that is used for create.
102 /// `R` is structure that is used for return type.
103 fn create<V: Sync + Send + Serialize, R: Send + Sync + Sized + for<'a> Deserialize<'a>>(
104 &self,
105 id: &ODataId,
106 query: &V,
107 ) -> impl Future<Output = Result<R, Self::Error>> + Send;
108
109 /// Update entity.
110 ///
111 /// `V` is structure that is used for update.
112 /// `R` is structure that is used for return type (updated entity).
113 fn update<V: Sync + Send + Serialize, R: Send + Sync + Sized + for<'a> Deserialize<'a>>(
114 &self,
115 id: &ODataId,
116 etag: Option<&ODataETag>,
117 query: &V,
118 ) -> impl Future<Output = Result<R, Self::Error>> + Send;
119
120 /// Delete entity.
121 fn delete(&self, id: &ODataId) -> impl Future<Output = Result<Empty, Self::Error>> + Send;
122
123 /// Run action.
124 ///
125 /// `T` is structure that contains action parameters.
126 /// `R` is structure with return type.
127 fn action<T: Send + Sync + Serialize, R: Send + Sync + Sized + for<'a> Deserialize<'a>>(
128 &self,
129 action: &Action<T, R>,
130 params: &T,
131 ) -> impl Future<Output = Result<R, Self::Error>> + Send;
132}