Move thermal interfaces to new schema
With the change to entity manager, move the thermal componets to the
proper inventory manager interfaces
Change-Id: I520e65b1df53ca8d3fbc12253882ae69b708bbbf
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index 03b9051..49a5a15 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -79,7 +79,7 @@
int user_index = 0;
for (auto& user : users) {
const std::string& path =
- static_cast<std::string>(user.first);
+ static_cast<const std::string&>(user.first);
std::size_t last_index = path.rfind("/");
if (last_index == std::string::npos) {
last_index = 0;
@@ -111,7 +111,7 @@
} else {
for (auto& user : users) {
const std::string& path =
- static_cast<std::string>(user.first);
+ static_cast<const std::string&>(user.first);
std::size_t last_index = path.rfind("/");
if (last_index == std::string::npos) {
last_index = 0;
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index 7db9357..c2ea91d 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -50,64 +50,22 @@
class OnDemandChassisProvider {
public:
/**
- * Function that retrieves all properties for given Chassis Object from
- * EntityManager
- * @param res_name a chassis resource name to query on DBus
- * @param callback a function that shall be called to convert Dbus output into
- * JSON
- */
- template <typename CallbackFunc>
- void get_chassis_data(const std::string &res_name, CallbackFunc &&callback) {
- crow::connections::system_bus->async_method_call(
- [callback{std::move(callback)}](
- const boost::system::error_code error_code,
- const PropertiesType &properties) {
- // Callback requires flat_map<string, string> so prepare one.
- boost::container::flat_map<std::string, std::string> output;
- if (error_code) {
- // Something wrong on DBus, the error_code is not important at this
- // moment, just return success=false, and empty output. Since size
- // of map may vary depending on Chassis type, an empty output could
- // not be treated same way as error.
- callback(false, output);
- return;
- }
- for (const std::pair<const char *, const char *> &p :
- std::array<std::pair<const char *, const char *>, 5>{
- {{"name", "Name"},
- {"manufacturer", "Manufacturer"},
- {"model", "Model"},
- {"part_number", "PartNumber"},
- {"serial_number", "SerialNumber"}}}) {
- PropertiesType::const_iterator it = properties.find(p.first);
- if (it != properties.end()) {
- const std::string *s =
- mapbox::get_ptr<const std::string>(it->second);
- if (s != nullptr) {
- output[p.second] = *s;
- }
- }
- }
- // Callback with success, and hopefully data.
- callback(true, output);
- },
- "xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
- "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Configuration.Chassis");
- }
-
- /**
* Function that retrieves all Chassis available through EntityManager.
* @param callback a function that shall be called to convert Dbus output into
* JSON.
*/
template <typename CallbackFunc>
void get_chassis_list(CallbackFunc &&callback) {
+ const std::array<const char *, 4> interfaces = {
+ "xyz.openbmc_project.Inventory.Item.Board",
+ "xyz.openbmc_project.Inventory.Item.Chassis",
+ "xyz.openbmc_project.Inventory.Item.PowerSupply",
+ "xyz.openbmc_project.Inventory.Item.System",
+ };
crow::connections::system_bus->async_method_call(
[callback{std::move(callback)}](
const boost::system::error_code error_code,
- const ManagedObjectsType &resp) {
+ const std::vector<std::string> &resp) {
// Callback requires vector<string> to retrieve all available chassis
// list.
std::vector<std::string> chassis_list;
@@ -119,31 +77,21 @@
callback(false, chassis_list);
return;
}
-
// Iterate over all retrieved ObjectPaths.
- for (auto &objpath : resp) {
- // And all interfaces available for certain ObjectPath.
- for (auto &interface : objpath.second) {
- // If interface is xyz.openbmc_project.Configuration.Chassis, this
- // is Chassis.
- if (interface.first ==
- "xyz.openbmc_project.Configuration.Chassis") {
- // Cut out everything until last "/", ...
- const std::string &chassis_id = objpath.first.str;
- std::size_t last_pos = chassis_id.rfind("/");
- if (last_pos != std::string::npos) {
- // and put it into output vector.
- chassis_list.emplace_back(chassis_id.substr(last_pos + 1));
- }
- }
+ for (const std::string &objpath : resp) {
+ std::size_t last_pos = objpath.rfind("/");
+ if (last_pos != std::string::npos) {
+ // and put it into output vector.
+ chassis_list.emplace_back(objpath.substr(last_pos + 1));
}
}
// Finally make a callback with useful data
callback(true, chassis_list);
},
- "xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+ "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
};
};
@@ -239,41 +187,73 @@
res.end();
return;
}
- const std::string &chassis_id = params[0];
- // Get certain Chassis Data, and call the below callback for JSON
- // preparation lambda requires everything as reference, and chassis_id,
- // which is local by copy
- chassis_provider.get_chassis_data(
- chassis_id,
- [&, chassis_id](const bool &success,
- const boost::container::flat_map<std::string,
- std::string> &output) {
- // Create JSON copy based on Node::json, this is to avoid possible
- // race condition
- nlohmann::json json_response(Node::json);
- json_response["Thermal"] = {
- {"@odata.id", "/redfish/v1/Chassis/" + chassis_id + "/Thermal"}};
- // If success...
- if (success) {
- // prepare all the schema required fields.
- json_response["@odata.id"] = "/redfish/v1/Chassis/" + chassis_id;
- // also the one from dbus
- for (const std::pair<std::string, std::string> &chassis_item :
- output) {
- json_response[chassis_item.first] = chassis_item.second;
- }
- json_response["Id"] = chassis_id;
- // prepare respond, and send
- res.json_value = json_response;
- } else {
- // ... otherwise return error
- // TODO(Pawel)consider distinguish between non existing object, and
- // other errors
- res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
+ res.json_value = Node::json;
+ const std::string &chassis_id = params[0];
+ crow::connections::system_bus->async_method_call(
+ [&res, chassis_id(std::string(chassis_id)) ](
+ const boost::system::error_code error_code,
+ const std::vector<std::pair<
+ std::string,
+ std::vector<std::pair<std::string, std::vector<std::string>>>>>
+ &subtree) {
+ if (error_code) {
+ res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+ res.json_value = {};
+ res.end();
+ return;
}
+ // 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;
+ if (!boost::ends_with(path, chassis_id)) {
+ continue;
+ }
+ if (connectionNames.size() < 1) {
+ res.code = static_cast<int>(HttpRespCode::INTERNAL_ERROR);
+ res.end();
+ return;
+ }
+ const std::string connectionName = connectionNames[0].first;
+ crow::connections::system_bus->async_method_call(
+ [&res, chassis_id(std::string(chassis_id)) ](
+ const boost::system::error_code error_code,
+ const std::vector<std::pair<std::string, VariantType>>
+ &propertiesList) {
+ for (const std::pair<std::string, VariantType> &property :
+ propertiesList) {
+ const std::string *value =
+ mapbox::get_ptr<const std::string>(property.second);
+ if (value != nullptr) {
+ res.json_value[property.first] = *value;
+ }
+ }
+ res.json_value["Name"] = chassis_id;
+ res.json_value["Thermal"] = {
+ {"@odata.id",
+ "/redfish/v1/Chassis/" + chassis_id + "/Thermal"}};
+ res.end();
+ },
+ connectionName, path, "org.freedesktop.DBus.Properties",
+ "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
+ // Found the connection we were looking for, return
+ return;
+ }
+ // Couldn't find an object with that name. return an error
+ res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
res.end();
- });
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", int32_t(0),
+ std::array<const char *, 1>{
+ "xyz.openbmc_project.Inventory.Decorator.Asset"});
}
// Chassis Provider object
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index ea465fb..ba69728 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -182,7 +182,7 @@
for (auto &objpath : dbus_data) {
// Check if proper patter for object path appears
if (boost::starts_with(
- static_cast<std::string>(objpath.first),
+ static_cast<const std::string&>(objpath.first),
"/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/")) {
// and get approrpiate interface
const auto &interface =
@@ -316,8 +316,8 @@
if (interface.first ==
"xyz.openbmc_project.Network.EthernetInterface") {
// Cut out everyting until last "/", ...
- const std::string iface_id =
- static_cast<std::string>(objpath.first);
+ const std::string& iface_id =
+ static_cast<const std::string&>(objpath.first);
std::size_t last_pos = iface_id.rfind("/");
if (last_pos != std::string::npos) {
// and put it into output vector.
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index b0cbbe1..4ba63e7 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -88,7 +88,7 @@
const boost::system::error_code ec, const GetSubTreeType& subtree) {
if (ec != 0) {
asyncResp->setErrorStatus();
- CROW_LOG_ERROR << "Dbus error " << ec;
+ CROW_LOG_ERROR << "resp_handler: Dbus error " << ec;
return;
}
@@ -133,7 +133,7 @@
// Make call to ObjectMapper to find all sensors objects
crow::connections::system_bus->async_method_call(
- resp_handler, "xyz.openbmc_project.ObjectMapper",
+ std::move(resp_handler), "xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
"GetSubTree", path, 2, interfaces);
}
@@ -158,25 +158,33 @@
return;
}
boost::container::flat_set<std::string> sensorNames;
- const std::string chassis_prefix =
- "/xyz/openbmc_project/Inventory/Item/Chassis/" + asyncResp->chassisId +
- '/';
- CROW_LOG_DEBUG << "Chassis Prefix " << chassis_prefix;
- bool foundChassis = false;
- for (const auto& objDictEntry : resp) {
- if (boost::starts_with(static_cast<std::string>(objDictEntry.first),
- chassis_prefix)) {
- foundChassis = true;
- const std::string sensorName =
- std::string(objDictEntry.first).substr(chassis_prefix.size());
- // Make sure this isn't a subobject (like a threshold)
- const std::size_t sensorPos = sensorName.find('/');
- if (sensorPos == std::string::npos) {
- CROW_LOG_DEBUG << "Adding sensor " << sensorName;
- sensorNames.emplace(sensorName);
- }
+ // asyncResp->chassisId
+ bool foundChassis = false;
+ std::vector<std::string> split;
+ // Reserve space for
+ // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
+ split.reserve(8);
+
+ for (const auto& objDictEntry : resp) {
+ const std::string& objectPath =
+ static_cast<const std::string&>(objDictEntry.first);
+ boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
+ if (split.size() < 2) {
+ CROW_LOG_ERROR << "Got path that isn't long enough " << objectPath;
+ split.clear();
+ continue;
}
+ const std::string& sensorName = split.end()[-1];
+ const std::string& chassisName = split.end()[-2];
+
+ if (chassisName != asyncResp->chassisId) {
+ split.clear();
+ continue;
+ }
+ foundChassis = true;
+ sensorNames.emplace(sensorName);
+ split.clear();
};
CROW_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
@@ -191,8 +199,8 @@
// Make call to EntityManager to find all chassis objects
crow::connections::system_bus->async_method_call(
resp_handler, "xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ "/xyz/openbmc_project/inventory", "org.freedesktop.DBus.ObjectManager",
+ "GetManagedObjects");
}
/**
@@ -245,7 +253,7 @@
unit = "ReadingCelsius";
// TODO(ed) Documentation says that path should be type fan_tach,
// implementation seems to implement fan
- } else if (sensorType == "fan" || sensorType == "fan_tach") {
+ } else if (sensorType == "fan" || sensorType == "fan_type") {
unit = "Reading";
sensor_json["ReadingUnits"] = "RPM";
forceToInt = true;
@@ -343,7 +351,7 @@
// sensor data
for (const auto& objDictEntry : resp) {
const std::string& objPath =
- static_cast<std::string>(objDictEntry.first);
+ static_cast<const std::string&>(objDictEntry.first);
CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
<< objPath;
if (!boost::starts_with(objPath, DBUS_SENSOR_PREFIX)) {