summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNan Zhou <nanzhoumails@gmail.com>2022-07-22 02:53:20 +0300
committerEd Tanous <ed@tanous.net>2022-07-22 03:50:39 +0300
commitcf7eba094fd41b2e5236af935a8113db387e647c (patch)
treec31b43c16ad74d47380d09348717d292ca40fc0a
parentce8ea743055f1b82c60790db40aa3295e03bdf9c (diff)
downloadbmcweb-cf7eba094fd41b2e5236af935a8113db387e647c.tar.xz
chassis: replace lambda with inline functions
It has been a convention that request route functions take inline functions instead of lambdas. The benifets include less indents, beging more readable + unit test-able (take a look at the unit test that this commit adds for example). This commit also fixed neccessary headers to make the test compile. The headers of the unit test source is a complete list. But headers of the core codes are not complete. These header clean up will be done in a separate effort once https://gerrit.openbmc.org/c/openbmc/bmcweb/+/55138 is submitted. Tested: 1. no service validator errors on real hardware. Signed-off-by: Nan Zhou <nanzhoumails@gmail.com> Change-Id: I4b23ba54707cea947b5db771c72aa64899041511
-rw-r--r--meson.build1
-rw-r--r--redfish-core/lib/chassis.hpp766
-rw-r--r--redfish-core/lib/chassis_test.cpp60
-rw-r--r--redfish-core/lib/redfish_util.hpp4
4 files changed, 453 insertions, 378 deletions
diff --git a/meson.build b/meson.build
index 54cd92a319..7be259b44f 100644
--- a/meson.build
+++ b/meson.build
@@ -393,6 +393,7 @@ srcfiles_unittest = [
'include/ut/openbmc_dbus_rest_test.cpp',
'redfish-core/include/utils/query_param_test.cpp',
'redfish-core/lib/ut/service_root_test.cpp',
+ 'redfish-core/lib/chassis_test.cpp',
'redfish-core/ut/configfile_test.cpp',
'redfish-core/ut/hex_utils_test.cpp',
'redfish-core/ut/ip_utils_test.cpp',
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index cfa1832d8c..7982281618 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -17,6 +17,7 @@
#include "health.hpp"
#include "led.hpp"
+#include "utils/json_utils.hpp"
#include <app.hpp>
#include <dbus_utility.hpp>
@@ -131,6 +132,25 @@ inline void getPhysicalSecurityData(std::shared_ptr<bmcweb::AsyncResp> aResp)
std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
}
+inline void handleChassisCollectionGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ChassisCollection.ChassisCollection";
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
+ asyncResp->res.jsonValue["Name"] = "Chassis Collection";
+
+ collection_util::getCollectionMembers(
+ asyncResp, "/redfish/v1/Chassis",
+ {"xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"});
+}
+
/**
* ChassisCollection derived class for delivering Chassis Collection Schema
* Functions triggers appropriate requests on DBus
@@ -140,22 +160,7 @@ inline void requestRoutesChassisCollection(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
.privileges(redfish::privileges::getChassisCollection)
.methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#ChassisCollection.ChassisCollection";
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
- asyncResp->res.jsonValue["Name"] = "Chassis Collection";
-
- collection_util::getCollectionMembers(
- asyncResp, "/redfish/v1/Chassis",
- {"xyz.openbmc_project.Inventory.Item.Board",
- "xyz.openbmc_project.Inventory.Item.Chassis"});
- });
+ std::bind_front(handleChassisCollectionGet, std::ref(app)));
}
inline void
@@ -199,379 +204,378 @@ inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
});
}
-/**
- * Chassis override class for delivering Chassis Schema
- * Functions triggers appropriate requests on DBus
- */
-inline void requestRoutesChassis(App& app)
+inline void
+ handleChassisGet(App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId)
{
- BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
- .privileges(redfish::privileges::getChassis)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ const std::array<const char*, 2> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, chassisId(std::string(chassisId))](
+ const boost::system::error_code ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ if (ec)
{
+ messages::internalError(asyncResp->res);
return;
}
- const std::array<const char*, 2> interfaces = {
- "xyz.openbmc_project.Inventory.Item.Board",
- "xyz.openbmc_project.Inventory.Item.Chassis"};
+ // Iterate over all retrieved ObjectPaths.
+ for (const std::pair<
+ std::string,
+ std::vector<std::pair<std::string, std::vector<std::string>>>>&
+ object : subtree)
+ {
+ const std::string& path = object.first;
+ const std::vector<std::pair<std::string, std::vector<std::string>>>&
+ connectionNames = object.second;
- crow::connections::systemBus->async_method_call(
- [asyncResp, chassisId(std::string(chassisId))](
- const boost::system::error_code ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
+ sdbusplus::message::object_path objPath(path);
+ if (objPath.filename() != chassisId)
{
- messages::internalError(asyncResp->res);
- return;
+ continue;
}
- // Iterate over all retrieved ObjectPaths.
- for (const std::pair<std::string,
- std::vector<std::pair<
- std::string, std::vector<std::string>>>>&
- object : subtree)
- {
- const std::string& path = object.first;
- const std::vector<
- std::pair<std::string, std::vector<std::string>>>&
- connectionNames = object.second;
- sdbusplus::message::object_path objPath(path);
- if (objPath.filename() != chassisId)
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
+
+ sdbusplus::asio::getProperty<std::vector<std::string>>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
+ "xyz.openbmc_project.Association", "endpoints",
+ [health](const boost::system::error_code ec2,
+ const std::vector<std::string>& resp) {
+ if (ec2)
{
- continue;
+ return; // no sensors = no failures
}
+ health->inventory = resp;
+ });
- auto health = std::make_shared<HealthPopulate>(asyncResp);
+ health->populate();
- sdbusplus::asio::getProperty<std::vector<std::string>>(
- *crow::connections::systemBus,
- "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
- "xyz.openbmc_project.Association", "endpoints",
- [health](const boost::system::error_code ec2,
- const std::vector<std::string>& resp) {
- if (ec2)
- {
- return; // no sensors = no failures
- }
- health->inventory = resp;
- });
-
- health->populate();
+ if (connectionNames.empty())
+ {
+ BMCWEB_LOG_ERROR << "Got 0 Connection names";
+ continue;
+ }
- if (connectionNames.empty())
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Chassis.v1_16_0.Chassis";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Chassis/" + chassisId;
+ asyncResp->res.jsonValue["Name"] = "Chassis Collection";
+ asyncResp->res.jsonValue["ChassisType"] = "RackMount";
+ asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
+ "/redfish/v1/Chassis/" + chassisId + "/Actions/Chassis.Reset";
+ asyncResp->res
+ .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
+ "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
+ asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
+ "/redfish/v1/Systems/system/PCIeDevices";
+
+ sdbusplus::asio::getProperty<std::vector<std::string>>(
+ *crow::connections::systemBus,
+ "xyz.openbmc_project.ObjectMapper", path + "/drive",
+ "xyz.openbmc_project.Association", "endpoints",
+ [asyncResp, chassisId](const boost::system::error_code ec3,
+ const std::vector<std::string>& resp) {
+ if (ec3 || resp.empty())
{
- BMCWEB_LOG_ERROR << "Got 0 Connection names";
- continue;
+ return; // no drives = no failures
}
- asyncResp->res.jsonValue["@odata.type"] =
- "#Chassis.v1_16_0.Chassis";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Chassis/" + chassisId;
- asyncResp->res.jsonValue["Name"] = "Chassis Collection";
- asyncResp->res.jsonValue["ChassisType"] = "RackMount";
- asyncResp->res
- .jsonValue["Actions"]["#Chassis.Reset"]["target"] =
- "/redfish/v1/Chassis/" + chassisId +
- "/Actions/Chassis.Reset";
- asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]
- ["@Redfish.ActionInfo"] =
- "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
- asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
- "/redfish/v1/Systems/system/PCIeDevices";
-
- sdbusplus::asio::getProperty<std::vector<std::string>>(
- *crow::connections::systemBus,
- "xyz.openbmc_project.ObjectMapper", path + "/drive",
- "xyz.openbmc_project.Association", "endpoints",
- [asyncResp,
- chassisId](const boost::system::error_code ec3,
- const std::vector<std::string>& resp) {
- if (ec3 || resp.empty())
- {
- return; // no drives = no failures
- }
+ nlohmann::json reference;
+ reference["odata.id"] = crow::utility::urlFromPieces(
+ "redfish", "v1", "Chassis", chassisId, "Drives");
+ asyncResp->res.jsonValue["Drives"] = std::move(reference);
+ });
- nlohmann::json reference;
- reference["odata.id"] = crow::utility::urlFromPieces(
- "redfish", "v1", "Chassis", chassisId, "Drives");
- asyncResp->res.jsonValue["Drives"] = std::move(reference);
- });
+ const std::string& connectionName = connectionNames[0].first;
- const std::string& connectionName = connectionNames[0].first;
+ const std::vector<std::string>& interfaces2 =
+ connectionNames[0].second;
+ const std::array<const char*, 2> hasIndicatorLed = {
+ "xyz.openbmc_project.Inventory.Item.Panel",
+ "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
- const std::vector<std::string>& interfaces2 =
- connectionNames[0].second;
- const std::array<const char*, 2> hasIndicatorLed = {
- "xyz.openbmc_project.Inventory.Item.Panel",
- "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
+ const std::string assetTagInterface =
+ "xyz.openbmc_project.Inventory.Decorator.AssetTag";
+ if (std::find(interfaces2.begin(), interfaces2.end(),
+ assetTagInterface) != interfaces2.end())
+ {
+ sdbusplus::asio::getProperty<std::string>(
+ *crow::connections::systemBus, connectionName, path,
+ assetTagInterface, "AssetTag",
+ [asyncResp, chassisId(std::string(chassisId))](
+ const boost::system::error_code ec2,
+ const std::string& property) {
+ if (ec2)
+ {
+ BMCWEB_LOG_DEBUG << "DBus response error for AssetTag";
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ asyncResp->res.jsonValue["AssetTag"] = property;
+ });
+ }
- const std::string assetTagInterface =
- "xyz.openbmc_project.Inventory.Decorator.AssetTag";
+ for (const char* interface : hasIndicatorLed)
+ {
if (std::find(interfaces2.begin(), interfaces2.end(),
- assetTagInterface) != interfaces2.end())
+ interface) != interfaces2.end())
{
- sdbusplus::asio::getProperty<std::string>(
- *crow::connections::systemBus, connectionName, path,
- assetTagInterface, "AssetTag",
- [asyncResp, chassisId(std::string(chassisId))](
- const boost::system::error_code ec2,
- const std::string& property) {
- if (ec2)
- {
- BMCWEB_LOG_DEBUG
- << "DBus response error for AssetTag";
- messages::internalError(asyncResp->res);
- return;
- }
- asyncResp->res.jsonValue["AssetTag"] = property;
- });
+ getIndicatorLedState(asyncResp);
+ getLocationIndicatorActive(asyncResp);
+ break;
}
+ }
- for (const char* interface : hasIndicatorLed)
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, chassisId(std::string(chassisId))](
+ const boost::system::error_code /*ec2*/,
+ const dbus::utility::DBusPropertiesMap& propertiesList) {
+ for (const std::pair<std::string,
+ dbus::utility::DbusVariantType>& property :
+ propertiesList)
{
- if (std::find(interfaces2.begin(), interfaces2.end(),
- interface) != interfaces2.end())
- {
- getIndicatorLedState(asyncResp);
- getLocationIndicatorActive(asyncResp);
- break;
- }
- }
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, chassisId(std::string(chassisId))](
- const boost::system::error_code /*ec2*/,
- const dbus::utility::DBusPropertiesMap&
- propertiesList) {
- for (const std::pair<std::string,
- dbus::utility::DbusVariantType>&
- property : propertiesList)
+ // Store DBus properties that are also
+ // Redfish properties with same name and a
+ // string value
+ const std::string& propertyName = property.first;
+ if ((propertyName == "PartNumber") ||
+ (propertyName == "SerialNumber") ||
+ (propertyName == "Manufacturer") ||
+ (propertyName == "Model") ||
+ (propertyName == "SparePartNumber"))
{
- // Store DBus properties that are also
- // Redfish properties with same name and a
- // string value
- const std::string& propertyName = property.first;
- if ((propertyName == "PartNumber") ||
- (propertyName == "SerialNumber") ||
- (propertyName == "Manufacturer") ||
- (propertyName == "Model") ||
- (propertyName == "SparePartNumber"))
+ const std::string* value =
+ std::get_if<std::string>(&property.second);
+ if (value == nullptr)
{
- const std::string* value =
- std::get_if<std::string>(&property.second);
- if (value == nullptr)
- {
- BMCWEB_LOG_ERROR << "Null value returned for "
- << propertyName;
- messages::internalError(asyncResp->res);
- return;
- }
- // SparePartNumber is optional on D-Bus
- // so skip if it is empty
- if (propertyName == "SparePartNumber")
+ BMCWEB_LOG_ERROR << "Null value returned for "
+ << propertyName;
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ // SparePartNumber is optional on D-Bus
+ // so skip if it is empty
+ if (propertyName == "SparePartNumber")
+ {
+ if (value->empty())
{
- if (value->empty())
- {
- continue;
- }
+ continue;
}
- asyncResp->res.jsonValue[propertyName] = *value;
}
+ asyncResp->res.jsonValue[propertyName] = *value;
}
- asyncResp->res.jsonValue["Name"] = chassisId;
- asyncResp->res.jsonValue["Id"] = chassisId;
+ }
+ asyncResp->res.jsonValue["Name"] = chassisId;
+ asyncResp->res.jsonValue["Id"] = chassisId;
#ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
- asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
- "/redfish/v1/Chassis/" + chassisId + "/Thermal";
- // Power object
- asyncResp->res.jsonValue["Power"]["@odata.id"] =
- "/redfish/v1/Chassis/" + chassisId + "/Power";
+ asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
+ "/redfish/v1/Chassis/" + chassisId + "/Thermal";
+ // Power object
+ asyncResp->res.jsonValue["Power"]["@odata.id"] =
+ "/redfish/v1/Chassis/" + chassisId + "/Power";
#endif
- // SensorCollection
- asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
- "/redfish/v1/Chassis/" + chassisId + "/Sensors";
- asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
- nlohmann::json::array_t computerSystems;
- nlohmann::json::object_t system;
- system["@odata.id"] = "/redfish/v1/Systems/system";
- computerSystems.push_back(std::move(system));
- asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
- std::move(computerSystems);
-
- nlohmann::json::array_t managedBy;
- nlohmann::json::object_t manager;
- manager["@odata.id"] = "/redfish/v1/Managers/bmc";
- managedBy.push_back(std::move(manager));
- asyncResp->res.jsonValue["Links"]["ManagedBy"] =
- std::move(managedBy);
- getChassisState(asyncResp);
- },
- connectionName, path, "org.freedesktop.DBus.Properties",
- "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-
- for (const auto& interface : interfaces2)
+ // SensorCollection
+ asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
+ "/redfish/v1/Chassis/" + chassisId + "/Sensors";
+ asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+ nlohmann::json::array_t computerSystems;
+ nlohmann::json::object_t system;
+ system["@odata.id"] = "/redfish/v1/Systems/system";
+ computerSystems.push_back(std::move(system));
+ asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
+ std::move(computerSystems);
+
+ nlohmann::json::array_t managedBy;
+ nlohmann::json::object_t manager;
+ manager["@odata.id"] = "/redfish/v1/Managers/bmc";
+ managedBy.push_back(std::move(manager));
+ asyncResp->res.jsonValue["Links"]["ManagedBy"] =
+ std::move(managedBy);
+ getChassisState(asyncResp);
+ },
+ connectionName, path, "org.freedesktop.DBus.Properties",
+ "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
+
+ for (const auto& interface : interfaces2)
+ {
+ if (interface == "xyz.openbmc_project.Common.UUID")
{
- if (interface == "xyz.openbmc_project.Common.UUID")
- {
- getChassisUUID(asyncResp, connectionName, path);
- }
- else if (
- interface ==
- "xyz.openbmc_project.Inventory.Decorator.LocationCode")
- {
- getChassisLocationCode(asyncResp, connectionName, path);
- }
+ getChassisUUID(asyncResp, connectionName, path);
+ }
+ else if (interface ==
+ "xyz.openbmc_project.Inventory.Decorator.LocationCode")
+ {
+ getChassisLocationCode(asyncResp, connectionName, path);
}
-
- return;
}
- // Couldn't find an object with that name. return an error
- messages::resourceNotFound(asyncResp->res,
- "#Chassis.v1_16_0.Chassis", chassisId);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree",
- "/xyz/openbmc_project/inventory", 0, interfaces);
-
- getPhysicalSecurityData(asyncResp);
- });
-
- BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
- .privileges(redfish::privileges::patchChassis)
- .methods(boost::beast::http::verb::patch)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
return;
}
- std::optional<bool> locationIndicatorActive;
- std::optional<std::string> indicatorLed;
- if (param.empty())
- {
- return;
- }
+ // Couldn't find an object with that name. return an error
+ messages::resourceNotFound(asyncResp->res, "#Chassis.v1_16_0.Chassis",
+ chassisId);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", 0, interfaces);
+
+ getPhysicalSecurityData(asyncResp);
+}
- if (!json_util::readJsonPatch(
- req, asyncResp->res, "LocationIndicatorActive",
- locationIndicatorActive, "IndicatorLED", indicatorLed))
+inline void
+ handleChassisPatch(App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& param)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::optional<bool> locationIndicatorActive;
+ std::optional<std::string> indicatorLed;
+
+ if (param.empty())
+ {
+ return;
+ }
+
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "LocationIndicatorActive",
+ locationIndicatorActive, "IndicatorLED", indicatorLed))
+ {
+ return;
+ }
+
+ // TODO (Gunnar): Remove IndicatorLED after enough time has passed
+ if (!locationIndicatorActive && !indicatorLed)
+ {
+ return; // delete this when we support more patch properties
+ }
+ if (indicatorLed)
+ {
+ asyncResp->res.addHeader(
+ boost::beast::http::field::warning,
+ "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
+ }
+
+ const std::array<const char*, 2> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+ const std::string& chassisId = param;
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, chassisId, locationIndicatorActive,
+ indicatorLed](const boost::system::error_code ec,
+ const dbus::utility::MapperGetSubTreeResponse& subtree) {
+ if (ec)
{
+ messages::internalError(asyncResp->res);
return;
}
- // TODO (Gunnar): Remove IndicatorLED after enough time has passed
- if (!locationIndicatorActive && !indicatorLed)
- {
- return; // delete this when we support more patch properties
- }
- if (indicatorLed)
+ // Iterate over all retrieved ObjectPaths.
+ for (const std::pair<
+ std::string,
+ std::vector<std::pair<std::string, std::vector<std::string>>>>&
+ object : subtree)
{
- asyncResp->res.addHeader(
- boost::beast::http::field::warning,
- "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
- }
+ const std::string& path = object.first;
+ const std::vector<std::pair<std::string, std::vector<std::string>>>&
+ connectionNames = object.second;
- const std::array<const char*, 2> interfaces = {
- "xyz.openbmc_project.Inventory.Item.Board",
- "xyz.openbmc_project.Inventory.Item.Chassis"};
-
- const std::string& chassisId = param;
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, chassisId, locationIndicatorActive, indicatorLed](
- const boost::system::error_code ec,
- const dbus::utility::MapperGetSubTreeResponse& subtree) {
- if (ec)
+ sdbusplus::message::object_path objPath(path);
+ if (objPath.filename() != chassisId)
{
- messages::internalError(asyncResp->res);
- return;
+ continue;
}
- // Iterate over all retrieved ObjectPaths.
- for (const std::pair<std::string,
- std::vector<std::pair<
- std::string, std::vector<std::string>>>>&
- object : subtree)
+ if (connectionNames.empty())
{
- const std::string& path = object.first;
- const std::vector<
- std::pair<std::string, std::vector<std::string>>>&
- connectionNames = object.second;
+ BMCWEB_LOG_ERROR << "Got 0 Connection names";
+ continue;
+ }
- sdbusplus::message::object_path objPath(path);
- if (objPath.filename() != chassisId)
+ const std::vector<std::string>& interfaces3 =
+ connectionNames[0].second;
+
+ const std::array<const char*, 2> hasIndicatorLed = {
+ "xyz.openbmc_project.Inventory.Item.Panel",
+ "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
+ bool indicatorChassis = false;
+ for (const char* interface : hasIndicatorLed)
+ {
+ if (std::find(interfaces3.begin(), interfaces3.end(),
+ interface) != interfaces3.end())
{
- continue;
+ indicatorChassis = true;
+ break;
}
-
- if (connectionNames.empty())
+ }
+ if (locationIndicatorActive)
+ {
+ if (indicatorChassis)
{
- BMCWEB_LOG_ERROR << "Got 0 Connection names";
- continue;
+ setLocationIndicatorActive(asyncResp,
+ *locationIndicatorActive);
}
-
- const std::vector<std::string>& interfaces3 =
- connectionNames[0].second;
-
- const std::array<const char*, 2> hasIndicatorLed = {
- "xyz.openbmc_project.Inventory.Item.Panel",
- "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
- bool indicatorChassis = false;
- for (const char* interface : hasIndicatorLed)
+ else
{
- if (std::find(interfaces3.begin(), interfaces3.end(),
- interface) != interfaces3.end())
- {
- indicatorChassis = true;
- break;
- }
+ messages::propertyUnknown(asyncResp->res,
+ "LocationIndicatorActive");
}
- if (locationIndicatorActive)
+ }
+ if (indicatorLed)
+ {
+ if (indicatorChassis)
{
- if (indicatorChassis)
- {
- setLocationIndicatorActive(asyncResp,
- *locationIndicatorActive);
- }
- else
- {
- messages::propertyUnknown(asyncResp->res,
- "LocationIndicatorActive");
- }
+ setIndicatorLedState(asyncResp, *indicatorLed);
}
- if (indicatorLed)
+ else
{
- if (indicatorChassis)
- {
- setIndicatorLedState(asyncResp, *indicatorLed);
- }
- else
- {
- messages::propertyUnknown(asyncResp->res,
- "IndicatorLED");
- }
+ messages::propertyUnknown(asyncResp->res, "IndicatorLED");
}
- return;
}
+ return;
+ }
- messages::resourceNotFound(asyncResp->res,
- "#Chassis.v1_14_0.Chassis", chassisId);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree",
- "/xyz/openbmc_project/inventory", 0, interfaces);
- });
+ messages::resourceNotFound(asyncResp->res, "#Chassis.v1_14_0.Chassis",
+ chassisId);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", 0, interfaces);
+}
+
+/**
+ * Chassis override class for delivering Chassis Schema
+ * Functions triggers appropriate requests on DBus
+ */
+inline void requestRoutesChassis(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
+ .privileges(redfish::privileges::getChassis)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handleChassisGet, std::ref(app)));
+
+ BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
+ .privileges(redfish::privileges::patchChassis)
+ .methods(boost::beast::http::verb::patch)(
+ std::bind_front(handleChassisPatch, std::ref(app)));
}
inline void
@@ -633,6 +637,36 @@ inline void
busName, path, interface, method, "/", 0, interfaces);
}
+inline void handleChassisResetActionInfoPost(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& /*chassisId*/)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
+
+ std::string resetType;
+
+ if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
+ {
+ return;
+ }
+
+ if (resetType != "PowerCycle")
+ {
+ BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
+ << resetType;
+ messages::actionParameterNotSupported(asyncResp->res, resetType,
+ "ResetType");
+
+ return;
+ }
+ doChassisPowerCycle(asyncResp);
+}
+
/**
* ChassisResetAction class supports the POST method for the Reset
* action.
@@ -645,34 +679,35 @@ inline void requestRoutesChassisResetAction(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
.privileges(redfish::privileges::postChassis)
.methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string&) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
-
- std::string resetType;
-
- if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
- resetType))
- {
- return;
- }
-
- if (resetType != "PowerCycle")
- {
- BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
- << resetType;
- messages::actionParameterNotSupported(asyncResp->res, resetType,
- "ResetType");
+ std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
+}
- return;
- }
- doChassisPowerCycle(asyncResp);
- });
+inline void handleChassisResetActionInfoGet(
+ App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
+ asyncResp->res.jsonValue["Name"] = "Reset Action Info";
+
+ asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ nlohmann::json::array_t allowed;
+ allowed.push_back("PowerCycle");
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.push_back(std::move(parameter));
+
+ asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
}
/**
@@ -684,32 +719,7 @@ inline void requestRoutesChassisResetActionInfo(App& app)
BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
.privileges(redfish::privileges::getActionInfo)
.methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& chassisId) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#ActionInfo.v1_1_2.ActionInfo";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
- asyncResp->res.jsonValue["Name"] = "Reset Action Info";
-
- asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
- nlohmann::json::array_t parameters;
- nlohmann::json::object_t parameter;
- parameter["Name"] = "ResetType";
- parameter["Required"] = true;
- parameter["DataType"] = "String";
- nlohmann::json::array_t allowed;
- allowed.push_back("PowerCycle");
- parameter["AllowableValues"] = std::move(allowed);
- parameters.push_back(std::move(parameter));
-
- asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
- });
+ std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
}
} // namespace redfish
diff --git a/redfish-core/lib/chassis_test.cpp b/redfish-core/lib/chassis_test.cpp
new file mode 100644
index 0000000000..a04385984e
--- /dev/null
+++ b/redfish-core/lib/chassis_test.cpp
@@ -0,0 +1,60 @@
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "chassis.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+
+#include <boost/beast/core/string_type.hpp>
+#include <boost/beast/http/message.hpp>
+#include <nlohmann/json.hpp>
+
+#include <system_error>
+
+#include <gtest/gtest.h>
+
+namespace redfish
+{
+namespace
+{
+
+void assertChassisResetActionInfoGet(const std::string& chassisId,
+ crow::Response& res)
+{
+ EXPECT_EQ(res.jsonValue["@odata.type"], "#ActionInfo.v1_1_2.ActionInfo");
+ EXPECT_EQ(res.jsonValue["@odata.id"],
+ "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo");
+ EXPECT_EQ(res.jsonValue["Name"], "Reset Action Info");
+
+ EXPECT_EQ(res.jsonValue["Id"], "ResetActionInfo");
+
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ nlohmann::json::array_t allowed;
+ allowed.push_back("PowerCycle");
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.push_back(std::move(parameter));
+
+ EXPECT_EQ(res.jsonValue["Parameters"], parameters);
+}
+
+TEST(HandleChassisResetActionInfoGet, StaticAttributesAreExpected)
+{
+
+ auto response = std::make_shared<bmcweb::AsyncResp>();
+ std::error_code err;
+ crow::Request request{{boost::beast::http::verb::get, "/whatever", 11},
+ err};
+
+ std::string fakeChassis = "fakeChassis";
+ response->res.setCompleteRequestHandler(
+ std::bind_front(assertChassisResetActionInfoGet, fakeChassis));
+
+ crow::App app;
+ handleChassisResetActionInfoGet(app, request, response, fakeChassis);
+}
+
+} // namespace
+} // namespace redfish \ No newline at end of file
diff --git a/redfish-core/lib/redfish_util.hpp b/redfish-core/lib/redfish_util.hpp
index e050594afa..04d6ceb303 100644
--- a/redfish-core/lib/redfish_util.hpp
+++ b/redfish-core/lib/redfish_util.hpp
@@ -17,6 +17,10 @@
#ifndef BMCWEB_ENABLE_REDFISH_ONE_CHASSIS
#include <dbus_utility.hpp>
+#include <sdbusplus/asio/property.hpp>
+
+#include <charconv>
+
namespace redfish
{