summaryrefslogtreecommitdiff
path: root/include/openbmc_dbus_rest.hpp
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2018-12-06 00:53:16 +0300
committerEd Tanous <ed.tanous@intel.com>2018-12-14 00:55:28 +0300
commit2df1e7db0277e661ab01f76258343d1ec2f0ae50 (patch)
treedff24706f9fc4c524a5f2e5fe391cf5a653461fc /include/openbmc_dbus_rest.hpp
parent3ae4ba7ba4f24462b55d1d5aa7846a2564b22d00 (diff)
downloadbmcweb-2df1e7db0277e661ab01f76258343d1ec2f0ae50.tar.xz
REST: For enumerate, try GetAll as last resort
If there are no ObjectManager instances covering a path that came back from the GetSubTree call, the only other way to get that path's properties is by directly reading them. So, after all of the GetManagedObjects calls are done, on any of the paths that were in the GetSubTree results but not in the enumerate results, make a GetAll call to get the properties and add them to the output. The code knows when all of the asynchronous GetManagedObjects calls are done because it is called from the destructor of the InProgressEnumerateData struct which is passed to all of the other asio ops via a shared pointer. Tested: Run on paths that weren't in object managers, such as the physical LED objects. Change-Id: I5a62b9a0ee27a68127e6f216625ce93c9ac58d08 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Diffstat (limited to 'include/openbmc_dbus_rest.hpp')
-rw-r--r--include/openbmc_dbus_rest.hpp75
1 files changed, 74 insertions, 1 deletions
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 73c6f37ce2..2e338bbff3 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -96,6 +96,79 @@ void introspectObjects(const std::string &processName,
"Introspect");
}
+void getPropertiesForEnumerate(const std::string &objectPath,
+ const std::string &service,
+ const std::string &interface,
+ std::shared_ptr<bmcweb::AsyncResp> asyncResp)
+{
+ BMCWEB_LOG_DEBUG << "getPropertiesForEnumerate " << objectPath << " "
+ << service << " " << interface;
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, objectPath, service,
+ interface](const boost::system::error_code ec,
+ const std::vector<
+ std::pair<std::string, dbus::utility::DbusVariantType>>
+ &propertiesList) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "GetAll on path " << objectPath << " iface "
+ << interface << " service " << service
+ << " failed with code " << ec;
+ return;
+ }
+
+ nlohmann::json &dataJson = asyncResp->res.jsonValue["data"];
+ nlohmann::json &objectJson = dataJson[objectPath];
+ if (objectJson.is_null())
+ {
+ objectJson = nlohmann::json::object();
+ }
+
+ for (const auto &[name, value] : propertiesList)
+ {
+ nlohmann::json &propertyJson = objectJson[name];
+ sdbusplus::message::variant_ns::visit(
+ [&propertyJson](auto &&val) { propertyJson = val; }, value);
+ }
+ },
+ service, objectPath, "org.freedesktop.DBus.Properties", "GetAll",
+ interface);
+}
+
+// Find any results that weren't picked up by ObjectManagers, to be
+// called after all ObjectManagers are searched for and called.
+void findRemainingObjectsForEnumerate(
+ const std::string &objectPath, std::shared_ptr<GetSubTreeType> subtree,
+ std::shared_ptr<bmcweb::AsyncResp> asyncResp)
+{
+ BMCWEB_LOG_DEBUG << "findRemainingObjectsForEnumerate";
+ const nlohmann::json &dataJson = asyncResp->res.jsonValue["data"];
+
+ for (const auto &[path, interface_map] : *subtree)
+ {
+ if (path == objectPath)
+ {
+ // An enumerate does not return the target path's properties
+ continue;
+ }
+ if (dataJson.find(path) == dataJson.end())
+ {
+ for (const auto &[service, interfaces] : interface_map)
+ {
+ for (const auto &interface : interfaces)
+ {
+ if (!boost::starts_with(interface, "org.freedesktop.DBus"))
+ {
+ getPropertiesForEnumerate(path, service, interface,
+ asyncResp);
+ }
+ }
+ }
+ }
+ }
+}
+
struct InProgressEnumerateData
{
InProgressEnumerateData(const std::string &objectPath,
@@ -107,7 +180,7 @@ struct InProgressEnumerateData
~InProgressEnumerateData()
{
- // TODO
+ findRemainingObjectsForEnumerate(objectPath, subtree, asyncResp);
}
const std::string objectPath;