summaryrefslogtreecommitdiff
path: root/redfish-core/lib/sensors.hpp
diff options
context:
space:
mode:
authorRichard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>2019-02-13 21:05:05 +0300
committerJames Feist <james.feist@linux.intel.com>2019-03-12 19:57:47 +0300
commitf65af9e8c0d28a4b725c0d05ecbeb3007e2a09cf (patch)
tree5f99e155f7799057bf855e70d7786c7fcf5adfaf /redfish-core/lib/sensors.hpp
parentadd6133b61dca3568063f1b564f24e8cee0ba578 (diff)
downloadbmcweb-f65af9e8c0d28a4b725c0d05ecbeb3007e2a09cf.tar.xz
Support for overriding multiple sensor
Support added for overriding multiple sensor, in single patch method. Can accept Thermal (Temperatures/Fans) and Power (Voltages) collections. Unit-Test: 1. Verified sensor values are getting updated by doing PATCH method to a known sensor. Verified the value got updated using ipmitool sensor list. 2. Verified negative cases of making PATCH call on invalid chasisId, Invalid MemberId etc. Testedeby: Used Postman tool to issue the PATCH call to the 1. https://xx.xx.xx.xx/redfish/v1/Chassis/XXYYZZ/Thermal with content { "Temperatures": [ { "MemberId" : "SensorNameXX", "ReadingCelsius" : valueXX } ] "Fans": [ { "MemberId" : "SensorNameYY", "Reading" : valueYY } ] } 2. https://xx.xx.xx.xx/redfish/v1/Chassis/XXYYZZ/Power with content { "Voltages": [ { "MemberId" : "SensorNameXX", "ReadingVolts" : valueXX }, { "MemberId" : "SensorNameYY", "ReadingVolts" : valueYY } ] } Change-Id: Ie30a7dff421f1a459dfe7bac262ae29e98754810 Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
Diffstat (limited to 'redfish-core/lib/sensors.hpp')
-rw-r--r--redfish-core/lib/sensors.hpp180
1 files changed, 119 insertions, 61 deletions
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 34f8f53ba8..5a0cf75926 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -589,17 +589,46 @@ void setSensorOverride(crow::Response& res, const crow::Request& req,
res.end();
return;
}
- const char* collectionName;
- const char* propertyValueName;
+
+ std::unordered_map<std::string, std::vector<nlohmann::json>> allCollections;
+ std::optional<std::vector<nlohmann::json>> temperatureCollections;
+ std::optional<std::vector<nlohmann::json>> fanCollections;
+ std::vector<nlohmann::json> voltageCollections;
+ BMCWEB_LOG_INFO << "setSensorOverride for subNode" << chassisSubNode
+ << "\n";
+
if (chassisSubNode == "Thermal")
{
- collectionName = "Temperatures";
- propertyValueName = "ReadingCelsius";
+ if (!json_util::readJson(req, res, "Temperatures",
+ temperatureCollections, "Fans",
+ fanCollections))
+ {
+ return;
+ }
+ if (!temperatureCollections && !fanCollections)
+ {
+ messages::resourceNotFound(res, "Thermal",
+ "Temperatures / Voltages");
+ res.end();
+ return;
+ }
+ if (temperatureCollections)
+ {
+ allCollections.emplace("Temperatures",
+ *std::move(temperatureCollections));
+ }
+ if (fanCollections)
+ {
+ allCollections.emplace("Fans", *std::move(fanCollections));
+ }
}
else if (chassisSubNode == "Power")
{
- collectionName = "Voltages";
- propertyValueName = "ReadingVolts";
+ if (!json_util::readJson(req, res, "Voltages", voltageCollections))
+ {
+ return;
+ }
+ allCollections.emplace("Voltages", std::move(voltageCollections));
}
else
{
@@ -607,88 +636,117 @@ void setSensorOverride(crow::Response& res, const crow::Request& req,
res.end();
return;
}
- std::vector<nlohmann::json> collections;
- if (!json_util::readJson(req, res, collectionName, collections))
- {
- return;
- }
- if (collections.size() != 1)
- {
- messages::malformedJSON(res);
- res.end();
- return;
- }
+ const char* propertyValueName;
+ std::unordered_map<std::string, std::pair<double, std::string>> overrideMap;
std::string memberId;
double value;
- if (!json_util::readJson(collections[0], res, "MemberId", memberId,
- propertyValueName, value))
+ for (auto& collectionItems : allCollections)
{
- return;
+ if (collectionItems.first == "Temperatures")
+ {
+ propertyValueName = "ReadingCelsius";
+ }
+ else if (collectionItems.first == "Fans")
+ {
+ propertyValueName = "Reading";
+ }
+ else
+ {
+ propertyValueName = "ReadingVolts";
+ }
+ for (auto& item : collectionItems.second)
+ {
+ if (!json_util::readJson(item, res, "MemberId", memberId,
+ propertyValueName, value))
+ {
+ return;
+ }
+ overrideMap.emplace(memberId,
+ std::make_pair(value, collectionItems.first));
+ }
}
const std::string& chassisName = params[0];
auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
res, chassisName, typeList, chassisSubNode);
- BMCWEB_LOG_INFO << "setSensorOverride for " << memberId
- << "with value: " << value << "\n";
// first check for valid chassis id & sensor in requested chassis.
- auto getChassisSensorListCb =
- [sensorAsyncResp, memberId,
- value](const boost::container::flat_set<std::string>& sensorLists) {
- if (sensorLists.find(memberId) == sensorLists.end())
+ auto getChassisSensorListCb = [sensorAsyncResp, overrideMap](
+ const boost::container::flat_set<
+ std::string>& sensorLists) {
+ boost::container::flat_set<std::string> sensorNames;
+ for (const auto& item : overrideMap)
+ {
+ const auto& sensor = item.first;
+ if (sensorLists.find(item.first) == sensorLists.end())
{
- BMCWEB_LOG_INFO << "Unable to find memberId " << memberId;
+ BMCWEB_LOG_INFO << "Unable to find memberId " << item.first;
messages::resourceNotFound(sensorAsyncResp->res,
- sensorAsyncResp->chassisSubNode ==
- "Thermal"
- ? "Temperatures"
- : "Voltages",
- memberId);
+ item.second.second, item.first);
return;
}
- boost::container::flat_set<std::string> sensorNames;
- sensorNames.emplace(memberId);
- // Get the connection to which the memberId belongs
- auto getObjectsWithConnectionCb =
- [sensorAsyncResp, memberId, value](
- const boost::container::flat_set<std::string>& connections,
- const std::set<std::pair<std::string, std::string>>&
- objectsWithConnection) {
- if (objectsWithConnection.size() != 1)
+ sensorNames.emplace(sensor);
+ }
+ // Get the connection to which the memberId belongs
+ auto getObjectsWithConnectionCb =
+ [sensorAsyncResp, overrideMap](
+ const boost::container::flat_set<std::string>& connections,
+ const std::set<std::pair<std::string, std::string>>&
+ objectsWithConnection) {
+ if (objectsWithConnection.size() != overrideMap.size())
+ {
+ BMCWEB_LOG_INFO
+ << "Unable to find all objects with proper connection "
+ << objectsWithConnection.size() << " requested "
+ << overrideMap.size() << "\n";
+ messages::resourceNotFound(
+ sensorAsyncResp->res,
+ sensorAsyncResp->chassisSubNode == "Thermal"
+ ? "Temperatures"
+ : "Voltages",
+ "Count");
+ return;
+ }
+ for (const auto& item : objectsWithConnection)
+ {
+
+ auto lastPos = item.first.rfind('/');
+ if (lastPos == std::string::npos)
{
- BMCWEB_LOG_INFO
- << "Unable to find object with proper connection "
- << objectsWithConnection.size() << "\n";
- messages::resourceNotFound(
- sensorAsyncResp->res,
- sensorAsyncResp->chassisSubNode == "Thermal"
- ? "Temperatures"
- : "Voltages",
- memberId);
+ messages::internalError(sensorAsyncResp->res);
+ return;
+ }
+ std::string sensorName = item.first.substr(lastPos + 1);
+
+ const auto& iterator = overrideMap.find(sensorName);
+ if (iterator == overrideMap.end())
+ {
+ BMCWEB_LOG_INFO << "Unable to find sensor object"
+ << item.first << "\n";
+ messages::internalError(sensorAsyncResp->res);
return;
}
crow::connections::systemBus->async_method_call(
- [sensorAsyncResp, memberId,
- value](const boost::system::error_code ec) {
+ [sensorAsyncResp](const boost::system::error_code ec) {
if (ec)
{
BMCWEB_LOG_DEBUG
- << "getOverrideValueStatus DBUS error: "
+ << "setOverrideValueStatus DBUS error: "
<< ec;
messages::internalError(sensorAsyncResp->res);
return;
}
},
- objectsWithConnection.begin()->second,
- objectsWithConnection.begin()->first,
+ item.second, item.first,
"org.freedesktop.DBus.Properties", "Set",
"xyz.openbmc_project.Sensor.Value", "Value",
- sdbusplus::message::variant<double>(value));
- };
- // Get object with connection for the given sensor name
- getObjectsWithConnection(sensorAsyncResp, sensorNames,
- std::move(getObjectsWithConnectionCb));
- };
+ sdbusplus::message::variant<double>(
+ iterator->second.first));
+ }
+ };
+ // Get object with connection for the given sensor name
+ getObjectsWithConnection(sensorAsyncResp, sensorNames,
+ std::move(getObjectsWithConnectionCb));
+ };
// get full sensor list for the given chassisId and cross verify the sensor.
getChassis(sensorAsyncResp, std::move(getChassisSensorListCb));
}