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