xref: /openbmc/bmcweb/features/redfish/lib/assembly.hpp (revision 83237dd618c38a54aaa91b9fe4968eeb454a5dfa)
1*83237dd6SSunnySrivastava1984 // SPDX-License-Identifier: Apache-2.0
2*83237dd6SSunnySrivastava1984 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*83237dd6SSunnySrivastava1984 #pragma once
4*83237dd6SSunnySrivastava1984 
5*83237dd6SSunnySrivastava1984 #include "app.hpp"
6*83237dd6SSunnySrivastava1984 #include "async_resp.hpp"
7*83237dd6SSunnySrivastava1984 #include "dbus_singleton.hpp"
8*83237dd6SSunnySrivastava1984 #include "dbus_utility.hpp"
9*83237dd6SSunnySrivastava1984 #include "error_messages.hpp"
10*83237dd6SSunnySrivastava1984 #include "generated/enums/resource.hpp"
11*83237dd6SSunnySrivastava1984 #include "http_request.hpp"
12*83237dd6SSunnySrivastava1984 #include "http_response.hpp"
13*83237dd6SSunnySrivastava1984 #include "logging.hpp"
14*83237dd6SSunnySrivastava1984 #include "query.hpp"
15*83237dd6SSunnySrivastava1984 #include "registries/privilege_registry.hpp"
16*83237dd6SSunnySrivastava1984 #include "utils/assembly_utils.hpp"
17*83237dd6SSunnySrivastava1984 #include "utils/asset_utils.hpp"
18*83237dd6SSunnySrivastava1984 #include "utils/chassis_utils.hpp"
19*83237dd6SSunnySrivastava1984 #include "utils/dbus_utils.hpp"
20*83237dd6SSunnySrivastava1984 
21*83237dd6SSunnySrivastava1984 #include <boost/beast/http/verb.hpp>
22*83237dd6SSunnySrivastava1984 #include <boost/system/error_code.hpp>
23*83237dd6SSunnySrivastava1984 #include <boost/url/format.hpp>
24*83237dd6SSunnySrivastava1984 #include <nlohmann/json.hpp>
25*83237dd6SSunnySrivastava1984 #include <sdbusplus/asio/property.hpp>
26*83237dd6SSunnySrivastava1984 #include <sdbusplus/unpack_properties.hpp>
27*83237dd6SSunnySrivastava1984 
28*83237dd6SSunnySrivastava1984 #include <cstddef>
29*83237dd6SSunnySrivastava1984 #include <functional>
30*83237dd6SSunnySrivastava1984 #include <memory>
31*83237dd6SSunnySrivastava1984 #include <ranges>
32*83237dd6SSunnySrivastava1984 #include <string>
33*83237dd6SSunnySrivastava1984 #include <string_view>
34*83237dd6SSunnySrivastava1984 #include <vector>
35*83237dd6SSunnySrivastava1984 
36*83237dd6SSunnySrivastava1984 namespace redfish
37*83237dd6SSunnySrivastava1984 {
38*83237dd6SSunnySrivastava1984 
39*83237dd6SSunnySrivastava1984 /**
40*83237dd6SSunnySrivastava1984  * @brief Get Location code for the given assembly.
41*83237dd6SSunnySrivastava1984  * @param[in] asyncResp - Shared pointer for asynchronous calls.
42*83237dd6SSunnySrivastava1984  * @param[in] serviceName - Service in which the assembly is hosted.
43*83237dd6SSunnySrivastava1984  * @param[in] assembly - Assembly object.
44*83237dd6SSunnySrivastava1984  * @param[in] assemblyJsonPtr - json-keyname on the assembly list output.
45*83237dd6SSunnySrivastava1984  * @return None.
46*83237dd6SSunnySrivastava1984  */
47*83237dd6SSunnySrivastava1984 inline void getAssemblyLocationCode(
48*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
49*83237dd6SSunnySrivastava1984     const std::string& serviceName, const std::string& assembly,
50*83237dd6SSunnySrivastava1984     const nlohmann::json::json_pointer& assemblyJsonPtr)
51*83237dd6SSunnySrivastava1984 {
52*83237dd6SSunnySrivastava1984     sdbusplus::asio::getProperty<std::string>(
53*83237dd6SSunnySrivastava1984         *crow::connections::systemBus, serviceName, assembly,
54*83237dd6SSunnySrivastava1984         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
55*83237dd6SSunnySrivastava1984         [asyncResp, assembly, assemblyJsonPtr](
56*83237dd6SSunnySrivastava1984             const boost::system::error_code& ec, const std::string& value) {
57*83237dd6SSunnySrivastava1984             if (ec)
58*83237dd6SSunnySrivastava1984             {
59*83237dd6SSunnySrivastava1984                 if (ec.value() != EBADR)
60*83237dd6SSunnySrivastava1984                 {
61*83237dd6SSunnySrivastava1984                     BMCWEB_LOG_ERROR("DBUS response error: {} for assembly {}",
62*83237dd6SSunnySrivastava1984                                      ec.value(), assembly);
63*83237dd6SSunnySrivastava1984                     messages::internalError(asyncResp->res);
64*83237dd6SSunnySrivastava1984                 }
65*83237dd6SSunnySrivastava1984                 return;
66*83237dd6SSunnySrivastava1984             }
67*83237dd6SSunnySrivastava1984 
68*83237dd6SSunnySrivastava1984             asyncResp->res.jsonValue[assemblyJsonPtr]["Location"]
69*83237dd6SSunnySrivastava1984                                     ["PartLocation"]["ServiceLabel"] = value;
70*83237dd6SSunnySrivastava1984         });
71*83237dd6SSunnySrivastava1984 }
72*83237dd6SSunnySrivastava1984 
73*83237dd6SSunnySrivastava1984 inline void getAssemblyState(
74*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
75*83237dd6SSunnySrivastava1984     const auto& serviceName, const auto& assembly,
76*83237dd6SSunnySrivastava1984     const nlohmann::json::json_pointer& assemblyJsonPtr)
77*83237dd6SSunnySrivastava1984 {
78*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue[assemblyJsonPtr]["Status"]["State"] =
79*83237dd6SSunnySrivastava1984         resource::State::Enabled;
80*83237dd6SSunnySrivastava1984 
81*83237dd6SSunnySrivastava1984     dbus::utility::getProperty<bool>(
82*83237dd6SSunnySrivastava1984         serviceName, assembly, "xyz.openbmc_project.Inventory.Item", "Present",
83*83237dd6SSunnySrivastava1984         [asyncResp, assemblyJsonPtr,
84*83237dd6SSunnySrivastava1984          assembly](const boost::system::error_code& ec, const bool value) {
85*83237dd6SSunnySrivastava1984             if (ec)
86*83237dd6SSunnySrivastava1984             {
87*83237dd6SSunnySrivastava1984                 if (ec.value() != EBADR)
88*83237dd6SSunnySrivastava1984                 {
89*83237dd6SSunnySrivastava1984                     BMCWEB_LOG_ERROR("DBUS response error: {}", ec.value());
90*83237dd6SSunnySrivastava1984                     messages::internalError(asyncResp->res);
91*83237dd6SSunnySrivastava1984                 }
92*83237dd6SSunnySrivastava1984                 return;
93*83237dd6SSunnySrivastava1984             }
94*83237dd6SSunnySrivastava1984 
95*83237dd6SSunnySrivastava1984             if (!value)
96*83237dd6SSunnySrivastava1984             {
97*83237dd6SSunnySrivastava1984                 asyncResp->res.jsonValue[assemblyJsonPtr]["Status"]["State"] =
98*83237dd6SSunnySrivastava1984                     resource::State::Absent;
99*83237dd6SSunnySrivastava1984             }
100*83237dd6SSunnySrivastava1984         });
101*83237dd6SSunnySrivastava1984 }
102*83237dd6SSunnySrivastava1984 
103*83237dd6SSunnySrivastava1984 void getAssemblyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
104*83237dd6SSunnySrivastava1984                        const auto& serviceName, const auto& assembly,
105*83237dd6SSunnySrivastava1984                        const nlohmann::json::json_pointer& assemblyJsonPtr)
106*83237dd6SSunnySrivastava1984 {
107*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue[assemblyJsonPtr]["Status"]["Health"] =
108*83237dd6SSunnySrivastava1984         resource::Health::OK;
109*83237dd6SSunnySrivastava1984 
110*83237dd6SSunnySrivastava1984     dbus::utility::getProperty<bool>(
111*83237dd6SSunnySrivastava1984         serviceName, assembly,
112*83237dd6SSunnySrivastava1984         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
113*83237dd6SSunnySrivastava1984         [asyncResp, assemblyJsonPtr](const boost::system::error_code& ec,
114*83237dd6SSunnySrivastava1984                                      bool functional) {
115*83237dd6SSunnySrivastava1984             if (ec)
116*83237dd6SSunnySrivastava1984             {
117*83237dd6SSunnySrivastava1984                 if (ec.value() != EBADR)
118*83237dd6SSunnySrivastava1984                 {
119*83237dd6SSunnySrivastava1984                     BMCWEB_LOG_ERROR("DBUS response error {}", ec.value());
120*83237dd6SSunnySrivastava1984                     messages::internalError(asyncResp->res);
121*83237dd6SSunnySrivastava1984                 }
122*83237dd6SSunnySrivastava1984                 return;
123*83237dd6SSunnySrivastava1984             }
124*83237dd6SSunnySrivastava1984 
125*83237dd6SSunnySrivastava1984             if (!functional)
126*83237dd6SSunnySrivastava1984             {
127*83237dd6SSunnySrivastava1984                 asyncResp->res.jsonValue[assemblyJsonPtr]["Status"]["Health"] =
128*83237dd6SSunnySrivastava1984                     resource::Health::Critical;
129*83237dd6SSunnySrivastava1984             }
130*83237dd6SSunnySrivastava1984         });
131*83237dd6SSunnySrivastava1984 }
132*83237dd6SSunnySrivastava1984 
133*83237dd6SSunnySrivastava1984 inline void afterGetDbusObject(
134*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
135*83237dd6SSunnySrivastava1984     const std::string& assembly,
136*83237dd6SSunnySrivastava1984     const nlohmann::json::json_pointer& assemblyJsonPtr,
137*83237dd6SSunnySrivastava1984     const boost::system::error_code& ec,
138*83237dd6SSunnySrivastava1984     const dbus::utility::MapperGetObject& object)
139*83237dd6SSunnySrivastava1984 {
140*83237dd6SSunnySrivastava1984     if (ec)
141*83237dd6SSunnySrivastava1984     {
142*83237dd6SSunnySrivastava1984         BMCWEB_LOG_ERROR("DBUS response error : {} for assembly {}", ec.value(),
143*83237dd6SSunnySrivastava1984                          assembly);
144*83237dd6SSunnySrivastava1984         messages::internalError(asyncResp->res);
145*83237dd6SSunnySrivastava1984         return;
146*83237dd6SSunnySrivastava1984     }
147*83237dd6SSunnySrivastava1984 
148*83237dd6SSunnySrivastava1984     for (const auto& [serviceName, interfaceList] : object)
149*83237dd6SSunnySrivastava1984     {
150*83237dd6SSunnySrivastava1984         for (const auto& interface : interfaceList)
151*83237dd6SSunnySrivastava1984         {
152*83237dd6SSunnySrivastava1984             if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
153*83237dd6SSunnySrivastava1984             {
154*83237dd6SSunnySrivastava1984                 asset_utils::getAssetInfo(asyncResp, serviceName, assembly,
155*83237dd6SSunnySrivastava1984                                           assemblyJsonPtr, true, false);
156*83237dd6SSunnySrivastava1984             }
157*83237dd6SSunnySrivastava1984             else if (interface ==
158*83237dd6SSunnySrivastava1984                      "xyz.openbmc_project.Inventory.Decorator.LocationCode")
159*83237dd6SSunnySrivastava1984             {
160*83237dd6SSunnySrivastava1984                 getAssemblyLocationCode(asyncResp, serviceName, assembly,
161*83237dd6SSunnySrivastava1984                                         assemblyJsonPtr);
162*83237dd6SSunnySrivastava1984             }
163*83237dd6SSunnySrivastava1984             else if (interface == "xyz.openbmc_project.Inventory.Item")
164*83237dd6SSunnySrivastava1984             {
165*83237dd6SSunnySrivastava1984                 getAssemblyState(asyncResp, serviceName, assembly,
166*83237dd6SSunnySrivastava1984                                  assemblyJsonPtr);
167*83237dd6SSunnySrivastava1984             }
168*83237dd6SSunnySrivastava1984             else if (interface ==
169*83237dd6SSunnySrivastava1984                      "xyz.openbmc_project.State.Decorator.OperationalStatus")
170*83237dd6SSunnySrivastava1984             {
171*83237dd6SSunnySrivastava1984                 getAssemblyHealth(asyncResp, serviceName, assembly,
172*83237dd6SSunnySrivastava1984                                   assemblyJsonPtr);
173*83237dd6SSunnySrivastava1984             }
174*83237dd6SSunnySrivastava1984         }
175*83237dd6SSunnySrivastava1984     }
176*83237dd6SSunnySrivastava1984 }
177*83237dd6SSunnySrivastava1984 
178*83237dd6SSunnySrivastava1984 /**
179*83237dd6SSunnySrivastava1984  * @brief Get properties for the assemblies associated to given chassis
180*83237dd6SSunnySrivastava1984  * @param[in] asyncResp - Shared pointer for asynchronous calls.
181*83237dd6SSunnySrivastava1984  * @param[in] chassisId - Chassis the assemblies are associated with.
182*83237dd6SSunnySrivastava1984  * @param[in] assemblies - list of all the assemblies associated with the
183*83237dd6SSunnySrivastava1984  * chassis.
184*83237dd6SSunnySrivastava1984  * @return None.
185*83237dd6SSunnySrivastava1984  */
186*83237dd6SSunnySrivastava1984 inline void getAssemblyProperties(
187*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
188*83237dd6SSunnySrivastava1984     const std::string& chassisId, const std::vector<std::string>& assemblies)
189*83237dd6SSunnySrivastava1984 {
190*83237dd6SSunnySrivastava1984     BMCWEB_LOG_DEBUG("Get properties for assembly associated");
191*83237dd6SSunnySrivastava1984 
192*83237dd6SSunnySrivastava1984     std::size_t assemblyIndex = 0;
193*83237dd6SSunnySrivastava1984     for (const std::string& assembly : assemblies)
194*83237dd6SSunnySrivastava1984     {
195*83237dd6SSunnySrivastava1984         nlohmann::json::object_t item;
196*83237dd6SSunnySrivastava1984         item["@odata.type"] = "#Assembly.v1_5_1.AssemblyData";
197*83237dd6SSunnySrivastava1984         item["@odata.id"] = boost::urls::format(
198*83237dd6SSunnySrivastava1984             "/redfish/v1/Chassis/{}/Assembly#/Assemblies/{}", chassisId,
199*83237dd6SSunnySrivastava1984             std::to_string(assemblyIndex));
200*83237dd6SSunnySrivastava1984         item["MemberId"] = std::to_string(assemblyIndex);
201*83237dd6SSunnySrivastava1984         item["Name"] = sdbusplus::message::object_path(assembly).filename();
202*83237dd6SSunnySrivastava1984 
203*83237dd6SSunnySrivastava1984         asyncResp->res.jsonValue["Assemblies"].emplace_back(item);
204*83237dd6SSunnySrivastava1984 
205*83237dd6SSunnySrivastava1984         nlohmann::json::json_pointer assemblyJsonPtr(
206*83237dd6SSunnySrivastava1984             "/Assemblies/" + std::to_string(assemblyIndex));
207*83237dd6SSunnySrivastava1984 
208*83237dd6SSunnySrivastava1984         dbus::utility::getDbusObject(
209*83237dd6SSunnySrivastava1984             assembly, assemblyInterfaces,
210*83237dd6SSunnySrivastava1984             std::bind_front(afterGetDbusObject, asyncResp, assembly,
211*83237dd6SSunnySrivastava1984                             assemblyJsonPtr));
212*83237dd6SSunnySrivastava1984 
213*83237dd6SSunnySrivastava1984         nlohmann::json& assemblyArray = asyncResp->res.jsonValue["Assemblies"];
214*83237dd6SSunnySrivastava1984         asyncResp->res.jsonValue["Assemblies@odata.count"] =
215*83237dd6SSunnySrivastava1984             assemblyArray.size();
216*83237dd6SSunnySrivastava1984 
217*83237dd6SSunnySrivastava1984         assemblyIndex++;
218*83237dd6SSunnySrivastava1984     }
219*83237dd6SSunnySrivastava1984 }
220*83237dd6SSunnySrivastava1984 
221*83237dd6SSunnySrivastava1984 inline void afterHandleChassisAssemblyGet(
222*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
223*83237dd6SSunnySrivastava1984     const std::string& chassisID, const boost::system::error_code& ec,
224*83237dd6SSunnySrivastava1984     const std::vector<std::string>& assemblyList)
225*83237dd6SSunnySrivastava1984 {
226*83237dd6SSunnySrivastava1984     if (ec)
227*83237dd6SSunnySrivastava1984     {
228*83237dd6SSunnySrivastava1984         BMCWEB_LOG_WARNING("Chassis {} not found", chassisID);
229*83237dd6SSunnySrivastava1984         messages::resourceNotFound(asyncResp->res, "Chassis", chassisID);
230*83237dd6SSunnySrivastava1984         return;
231*83237dd6SSunnySrivastava1984     }
232*83237dd6SSunnySrivastava1984 
233*83237dd6SSunnySrivastava1984     asyncResp->res.addHeader(
234*83237dd6SSunnySrivastava1984         boost::beast::http::field::link,
235*83237dd6SSunnySrivastava1984         "</redfish/v1/JsonSchemas/Assembly/Assembly.json>; rel=describedby");
236*83237dd6SSunnySrivastava1984 
237*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["@odata.type"] = "#Assembly.v1_5_1.Assembly";
238*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["@odata.id"] =
239*83237dd6SSunnySrivastava1984         boost::urls::format("/redfish/v1/Chassis/{}/Assembly", chassisID);
240*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["Name"] = "Assembly Collection";
241*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["Id"] = "Assembly";
242*83237dd6SSunnySrivastava1984 
243*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["Assemblies"] = nlohmann::json::array();
244*83237dd6SSunnySrivastava1984     asyncResp->res.jsonValue["Assemblies@odata.count"] = 0;
245*83237dd6SSunnySrivastava1984 
246*83237dd6SSunnySrivastava1984     if (!assemblyList.empty())
247*83237dd6SSunnySrivastava1984     {
248*83237dd6SSunnySrivastava1984         getAssemblyProperties(asyncResp, chassisID, assemblyList);
249*83237dd6SSunnySrivastava1984     }
250*83237dd6SSunnySrivastava1984 }
251*83237dd6SSunnySrivastava1984 
252*83237dd6SSunnySrivastava1984 /**
253*83237dd6SSunnySrivastava1984  * @param[in] asyncResp - Shared pointer for asynchronous calls.
254*83237dd6SSunnySrivastava1984  * @param[in] chassisID - Chassis to which the assemblies are
255*83237dd6SSunnySrivastava1984  * associated.
256*83237dd6SSunnySrivastava1984  *
257*83237dd6SSunnySrivastava1984  * @return None.
258*83237dd6SSunnySrivastava1984  */
259*83237dd6SSunnySrivastava1984 inline void handleChassisAssemblyGet(
260*83237dd6SSunnySrivastava1984     App& app, const crow::Request& req,
261*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
262*83237dd6SSunnySrivastava1984     const std::string& chassisID)
263*83237dd6SSunnySrivastava1984 {
264*83237dd6SSunnySrivastava1984     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
265*83237dd6SSunnySrivastava1984     {
266*83237dd6SSunnySrivastava1984         return;
267*83237dd6SSunnySrivastava1984     }
268*83237dd6SSunnySrivastava1984 
269*83237dd6SSunnySrivastava1984     BMCWEB_LOG_DEBUG("Get chassis Assembly");
270*83237dd6SSunnySrivastava1984     assembly_utils::getChassisAssembly(
271*83237dd6SSunnySrivastava1984         asyncResp, chassisID,
272*83237dd6SSunnySrivastava1984         std::bind_front(afterHandleChassisAssemblyGet, asyncResp, chassisID));
273*83237dd6SSunnySrivastava1984 }
274*83237dd6SSunnySrivastava1984 
275*83237dd6SSunnySrivastava1984 inline void handleChassisAssemblyHead(
276*83237dd6SSunnySrivastava1984     crow::App& app, const crow::Request& req,
277*83237dd6SSunnySrivastava1984     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
278*83237dd6SSunnySrivastava1984     const std::string& chassisID)
279*83237dd6SSunnySrivastava1984 {
280*83237dd6SSunnySrivastava1984     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
281*83237dd6SSunnySrivastava1984     {
282*83237dd6SSunnySrivastava1984         return;
283*83237dd6SSunnySrivastava1984     }
284*83237dd6SSunnySrivastava1984 
285*83237dd6SSunnySrivastava1984     assembly_utils::getChassisAssembly(
286*83237dd6SSunnySrivastava1984         asyncResp, chassisID,
287*83237dd6SSunnySrivastava1984         [asyncResp,
288*83237dd6SSunnySrivastava1984          chassisID](const boost::system::error_code& ec,
289*83237dd6SSunnySrivastava1984                     const std::vector<std::string>& /*assemblyList*/) {
290*83237dd6SSunnySrivastava1984             if (ec)
291*83237dd6SSunnySrivastava1984             {
292*83237dd6SSunnySrivastava1984                 BMCWEB_LOG_WARNING("Chassis {} not found", chassisID);
293*83237dd6SSunnySrivastava1984                 messages::resourceNotFound(asyncResp->res, "Chassis",
294*83237dd6SSunnySrivastava1984                                            chassisID);
295*83237dd6SSunnySrivastava1984                 return;
296*83237dd6SSunnySrivastava1984             }
297*83237dd6SSunnySrivastava1984             asyncResp->res.addHeader(
298*83237dd6SSunnySrivastava1984                 boost::beast::http::field::link,
299*83237dd6SSunnySrivastava1984                 "</redfish/v1/JsonSchemas/Assembly.json>; rel=describedby");
300*83237dd6SSunnySrivastava1984         });
301*83237dd6SSunnySrivastava1984 }
302*83237dd6SSunnySrivastava1984 
303*83237dd6SSunnySrivastava1984 inline void requestRoutesAssembly(App& app)
304*83237dd6SSunnySrivastava1984 {
305*83237dd6SSunnySrivastava1984     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Assembly/")
306*83237dd6SSunnySrivastava1984         .privileges(redfish::privileges::headAssembly)
307*83237dd6SSunnySrivastava1984         .methods(boost::beast::http::verb::head)(
308*83237dd6SSunnySrivastava1984             std::bind_front(handleChassisAssemblyHead, std::ref(app)));
309*83237dd6SSunnySrivastava1984 
310*83237dd6SSunnySrivastava1984     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Assembly/")
311*83237dd6SSunnySrivastava1984         .privileges(redfish::privileges::getAssembly)
312*83237dd6SSunnySrivastava1984         .methods(boost::beast::http::verb::get)(
313*83237dd6SSunnySrivastava1984             std::bind_front(handleChassisAssemblyGet, std::ref(app)));
314*83237dd6SSunnySrivastava1984 }
315*83237dd6SSunnySrivastava1984 
316*83237dd6SSunnySrivastava1984 } // namespace redfish
317