Sensors: Add enum for chassis sub nodes
Added ChassisSubNode enum for defining the different chassis subNode
paths to retrieving sensor data.
Modified path building sensor data to use the enum. Other paths were
left still using the string. Specifically the paths using
SensorsAsyncResp as these primarily use the strings for human readable
output.
Added utility functions to convert to/from enum to string value.
Added unit tests for new utility functions.
Tested:
- Verified sensor paths before and after change had no change:
- /redfish/v1/Chassis/chassis/Sensors
- /redfish/v1/Chassis/chassis/Thermal
- /redfish/v1/Chassis/chassis/Power
- Selection of: /redfish/v1/Chassis/chassis/Sensors/<sensor>
- /redfish/v1/Chassis/chassis/Sensors?\$expand=*
- Redfish Validator passes
Change-Id: I02bb5f3c0c49d85dbd1dff911d9f1a8467d6b1db
Signed-off-by: Janet Adkins <janeta@us.ibm.com>
diff --git a/redfish-core/include/utils/sensor_utils.hpp b/redfish-core/include/utils/sensor_utils.hpp
index dbbe697..5c6b592 100644
--- a/redfish-core/include/utils/sensor_utils.hpp
+++ b/redfish-core/include/utils/sensor_utils.hpp
@@ -24,9 +24,50 @@
namespace sensor_utils
{
-static constexpr std::string_view powerNode = "Power";
-static constexpr std::string_view sensorsNode = "Sensors";
-static constexpr std::string_view thermalNode = "Thermal";
+enum class ChassisSubNode
+{
+ powerNode,
+ sensorsNode,
+ thermalNode,
+ unknownNode,
+};
+
+constexpr std::string_view chassisSubNodeToString(ChassisSubNode subNode)
+{
+ switch (subNode)
+ {
+ case ChassisSubNode::powerNode:
+ return "Power";
+ case ChassisSubNode::sensorsNode:
+ return "Sensors";
+ case ChassisSubNode::thermalNode:
+ return "Thermal";
+ case ChassisSubNode::unknownNode:
+ default:
+ return "";
+ }
+}
+
+inline ChassisSubNode chassisSubNodeFromString(const std::string& subNodeStr)
+{
+ // If none match unknownNode is returned
+ ChassisSubNode subNode = ChassisSubNode::unknownNode;
+
+ if (subNodeStr == "Power")
+ {
+ subNode = ChassisSubNode::powerNode;
+ }
+ else if (subNodeStr == "Sensors")
+ {
+ subNode = ChassisSubNode::sensorsNode;
+ }
+ else if (subNodeStr == "Thermal")
+ {
+ subNode = ChassisSubNode::thermalNode;
+ }
+
+ return subNode;
+}
/**
* Possible states for physical inventory leds
@@ -333,11 +374,11 @@
*/
inline void objectPropertiesToJson(
std::string_view sensorName, std::string_view sensorType,
- std::string_view chassisSubNode,
+ ChassisSubNode chassisSubNode,
const dbus::utility::DBusPropertiesMap& propertiesDict,
nlohmann::json& sensorJson, InventoryItem* inventoryItem)
{
- if (chassisSubNode == sensorsNode)
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
{
std::string subNodeEscaped = getSensorId(sensorName, sensorType);
// For sensors in SensorCollection we set Id instead of MemberId,
@@ -382,7 +423,7 @@
bool forceToInt = false;
nlohmann::json::json_pointer unit("/Reading");
- if (chassisSubNode == sensorsNode)
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
{
sensorJson["@odata.type"] = "#Sensor.v1_2_0.Sensor";
@@ -472,7 +513,7 @@
properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
- if (chassisSubNode == sensorsNode)
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
{
properties.emplace_back(
"xyz.openbmc_project.Sensor.Threshold.Warning", "WarningHigh",
@@ -505,7 +546,7 @@
// TODO Need to get UpperThresholdFatal and LowerThresholdFatal
- if (chassisSubNode == sensorsNode)
+ if (chassisSubNode == ChassisSubNode::sensorsNode)
{
properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
"/ReadingRangeMin"_json_pointer);
diff --git a/redfish-core/lib/power.hpp b/redfish-core/lib/power.hpp
index ea1e00a..14a2b46 100644
--- a/redfish-core/lib/power.hpp
+++ b/redfish-core/lib/power.hpp
@@ -269,7 +269,8 @@
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::powerPaths,
- sensor_utils::powerNode);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode));
getChassisData(sensorAsyncResp);
@@ -298,7 +299,8 @@
}
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::powerPaths,
- sensor_utils::powerNode);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode));
std::optional<std::vector<nlohmann::json::object_t>> voltageCollections;
std::optional<std::vector<nlohmann::json::object_t>> powerCtlCollections;
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 367f0d0..dc1b0a0 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -93,12 +93,21 @@
} // namespace dbus
// clang-format on
+constexpr std::string_view powerNodeStr = sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::powerNode);
+constexpr std::string_view sensorsNodeStr =
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::sensorsNode);
+constexpr std::string_view thermalNodeStr =
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode);
+
using sensorPair =
std::pair<std::string_view, std::span<const std::string_view>>;
static constexpr std::array<sensorPair, 3> paths = {
- {{sensor_utils::powerNode, dbus::powerPaths},
- {sensor_utils::sensorsNode, dbus::sensorPaths},
- {sensor_utils::thermalNode, dbus::thermalPaths}}};
+ {{sensors::powerNodeStr, dbus::powerPaths},
+ {sensors::sensorsNodeStr, dbus::sensorPaths},
+ {sensors::thermalNodeStr, dbus::thermalPaths}}};
} // namespace sensors
@@ -325,7 +334,7 @@
if ((allSensors == nullptr) || (activeSensors == nullptr))
{
messages::resourceNotFound(res, chassisSubNode,
- chassisSubNode == sensor_utils::thermalNode
+ chassisSubNode == sensors::thermalNodeStr
? "Temperatures"
: "Voltages");
@@ -357,17 +366,17 @@
inline void populateChassisNode(nlohmann::json& jsonValue,
std::string_view chassisSubNode)
{
- if (chassisSubNode == sensor_utils::powerNode)
+ if (chassisSubNode == sensors::powerNodeStr)
{
jsonValue["@odata.type"] = "#Power.v1_5_2.Power";
}
- else if (chassisSubNode == sensor_utils::thermalNode)
+ else if (chassisSubNode == sensors::thermalNodeStr)
{
jsonValue["@odata.type"] = "#Thermal.v1_4_0.Thermal";
jsonValue["Fans"] = nlohmann::json::array();
jsonValue["Temperatures"] = nlohmann::json::array();
}
- else if (chassisSubNode == sensor_utils::sensorsNode)
+ else if (chassisSubNode == sensors::sensorsNodeStr)
{
jsonValue["@odata.type"] = "#SensorCollection.SensorCollection";
jsonValue["Description"] = "Collection of Sensors for this Chassis";
@@ -375,7 +384,7 @@
jsonValue["Members@odata.count"] = 0;
}
- if (chassisSubNode != sensor_utils::sensorsNode)
+ if (chassisSubNode != sensors::sensorsNodeStr)
{
jsonValue["Id"] = chassisSubNode;
}
@@ -484,7 +493,7 @@
*/
inline void objectInterfacesToJson(
const std::string& sensorName, const std::string& sensorType,
- const std::string& chassisSubNode,
+ const sensor_utils::ChassisSubNode chassisSubNode,
const dbus::utility::DBusInterfacesMap& interfacesDict,
nlohmann::json& sensorJson, InventoryItem* inventoryItem)
{
@@ -692,7 +701,7 @@
{
nlohmann::json& response = sensorsAsyncResp->asyncResp->res.jsonValue;
std::array<std::string, 2> sensorHeaders{"Temperatures", "Fans"};
- if (sensorsAsyncResp->chassisSubNode == sensor_utils::powerNode)
+ if (sensorsAsyncResp->chassisSubNode == sensors::powerNodeStr)
{
sensorHeaders = {"Voltages", "PowerSupplies"};
}
@@ -1569,7 +1578,7 @@
BMCWEB_LOG_DEBUG("getPowerSupplyAttributes enter");
// Only need the power supply attributes when the Power Schema
- if (sensorsAsyncResp->chassisSubNode != sensor_utils::powerNode)
+ if (sensorsAsyncResp->chassisSubNode != sensors::powerNodeStr)
{
BMCWEB_LOG_DEBUG("getPowerSupplyAttributes exit since not Power");
callback(inventoryItems);
@@ -1840,6 +1849,8 @@
messages::internalError(sensorsAsyncResp->asyncResp->res);
return;
}
+ auto chassisSubNode = sensor_utils::chassisSubNodeFromString(
+ sensorsAsyncResp->chassisSubNode);
// Go through all objects and update response with sensor data
for (const auto& objDictEntry : resp)
{
@@ -1881,7 +1892,7 @@
nlohmann::json* sensorJson = nullptr;
- if (sensorSchema == sensor_utils::sensorsNode &&
+ if (sensorSchema == sensors::sensorsNodeStr &&
!sensorsAsyncResp->efficientExpand)
{
std::string sensorId =
@@ -2005,10 +2016,9 @@
if (sensorJson != nullptr)
{
- objectInterfacesToJson(sensorName, sensorType,
- sensorsAsyncResp->chassisSubNode,
- objDictEntry.second, *sensorJson,
- inventoryItem);
+ objectInterfacesToJson(
+ sensorName, sensorType, chassisSubNode,
+ objDictEntry.second, *sensorJson, inventoryItem);
std::string path = "/xyz/openbmc_project/sensors/";
path += sensorType;
@@ -2020,8 +2030,8 @@
if (sensorsAsyncResp.use_count() == 1)
{
sortJSONResponse(sensorsAsyncResp);
- if (sensorsAsyncResp->chassisSubNode ==
- sensor_utils::sensorsNode &&
+ if (chassisSubNode ==
+ sensor_utils::ChassisSubNode::sensorsNode &&
sensorsAsyncResp->efficientExpand)
{
sensorsAsyncResp->asyncResp->res
@@ -2030,8 +2040,8 @@
.jsonValue["Members"]
.size();
}
- else if (sensorsAsyncResp->chassisSubNode ==
- sensor_utils::thermalNode)
+ else if (chassisSubNode ==
+ sensor_utils::ChassisSubNode::thermalNode)
{
populateFanRedundancy(sensorsAsyncResp);
}
@@ -2088,7 +2098,7 @@
BMCWEB_LOG_DEBUG("getChassisCb exit");
};
// SensorCollection doesn't contain the Redundancy property
- if (sensorsAsyncResp->chassisSubNode != sensor_utils::sensorsNode)
+ if (sensorsAsyncResp->chassisSubNode != sensors::sensorsNodeStr)
{
sensorsAsyncResp->asyncResp->res.jsonValue["Redundancy"] =
nlohmann::json::array();
@@ -2214,7 +2224,7 @@
objectsWithConnection.size(), overrideMap.size());
messages::resourceNotFound(
sensorAsyncResp->asyncResp->res,
- sensorAsyncResp->chassisSubNode == sensor_utils::thermalNode
+ sensorAsyncResp->chassisSubNode == sensors::thermalNodeStr
? "Temperatures"
: "Voltages",
"Count");
@@ -2354,7 +2364,7 @@
// we perform efficient expand.
auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisId, sensors::dbus::sensorPaths,
- sensor_utils::sensorsNode,
+ sensors::sensorsNodeStr,
/*efficientExpand=*/true);
getChassisData(sensorsAsyncResp);
@@ -2365,10 +2375,9 @@
// We get all sensors as hyperlinkes in the chassis (this
// implies we reply on the default query parameters handler)
- getChassis(asyncResp, chassisId, sensor_utils::sensorsNode,
- dbus::sensorPaths,
+ getChassis(asyncResp, chassisId, sensors::sensorsNodeStr, dbus::sensorPaths,
std::bind_front(sensors::getChassisCallback, asyncResp,
- chassisId, sensor_utils::sensorsNode));
+ chassisId, sensors::sensorsNodeStr));
}
inline void
@@ -2401,8 +2410,8 @@
path = path.parent_path();
std::string type = path.filename();
sensor_utils::objectPropertiesToJson(
- name, type, sensor_utils::sensorsNode, valuesDict,
- asyncResp->res.jsonValue, nullptr);
+ name, type, sensor_utils::ChassisSubNode::sensorsNode,
+ valuesDict, asyncResp->res.jsonValue, nullptr);
});
}
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
index 90a7b85..9a18591 100644
--- a/redfish-core/lib/thermal.hpp
+++ b/redfish-core/lib/thermal.hpp
@@ -40,7 +40,8 @@
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::thermalPaths,
- sensor_utils::thermalNode);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode));
// TODO Need to get Chassis Redundancy information.
getChassisData(sensorAsyncResp);
@@ -67,7 +68,8 @@
auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
asyncResp, chassisName, sensors::dbus::thermalPaths,
- sensor_utils::thermalNode);
+ sensor_utils::chassisSubNodeToString(
+ sensor_utils::ChassisSubNode::thermalNode));
if (!json_util::readJsonPatch(
req, sensorsAsyncResp->asyncResp->res, "Temperatures",
diff --git a/test/redfish-core/include/utils/sensor_utils_test.cpp b/test/redfish-core/include/utils/sensor_utils_test.cpp
index 54c3b9c..df944f2 100644
--- a/test/redfish-core/include/utils/sensor_utils_test.cpp
+++ b/test/redfish-core/include/utils/sensor_utils_test.cpp
@@ -47,5 +47,42 @@
EXPECT_EQ(sensorId, "temperature_temp2");
}
+TEST(ChassisSubNodeToString, Success)
+{
+ std::string subNodeStr;
+
+ subNodeStr = chassisSubNodeToString(ChassisSubNode::powerNode);
+ EXPECT_EQ(subNodeStr, "Power");
+
+ subNodeStr = chassisSubNodeToString(ChassisSubNode::sensorsNode);
+ EXPECT_EQ(subNodeStr, "Sensors");
+
+ subNodeStr = chassisSubNodeToString(ChassisSubNode::thermalNode);
+ EXPECT_EQ(subNodeStr, "Thermal");
+
+ subNodeStr = chassisSubNodeToString(ChassisSubNode::unknownNode);
+ EXPECT_EQ(subNodeStr, "");
+}
+
+TEST(ChassisSubNodeFromString, Success)
+{
+ ChassisSubNode subNode = ChassisSubNode::unknownNode;
+
+ subNode = chassisSubNodeFromString("Power");
+ EXPECT_EQ(subNode, ChassisSubNode::powerNode);
+
+ subNode = chassisSubNodeFromString("Sensors");
+ EXPECT_EQ(subNode, ChassisSubNode::sensorsNode);
+
+ subNode = chassisSubNodeFromString("Thermal");
+ EXPECT_EQ(subNode, ChassisSubNode::thermalNode);
+
+ subNode = chassisSubNodeFromString("BadNode");
+ EXPECT_EQ(subNode, ChassisSubNode::unknownNode);
+
+ subNode = chassisSubNodeFromString("");
+ EXPECT_EQ(subNode, ChassisSubNode::unknownNode);
+}
+
} // namespace
} // namespace redfish::sensor_utils