summaryrefslogtreecommitdiffstats
path: root/include/openbmc_dbus_rest.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/openbmc_dbus_rest.hpp')
-rw-r--r--include/openbmc_dbus_rest.hpp114
1 files changed, 103 insertions, 11 deletions
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 9348808..4e29805 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -10,6 +10,11 @@
namespace crow {
namespace openbmc_mapper {
+
+// TODO(ed) having these as scope globals, and as simple as they are limits the
+// ability to queue multiple async operations at once. Being able to register
+// "done" callbacks to a queue here that also had a count attached would allow
+// multiple requests to be running at once
std::atomic<std::size_t> outstanding_async_calls(0);
nlohmann::json object_paths;
@@ -101,19 +106,104 @@ void request_routes(Crow<Middlewares...> &app) {
});
+ CROW_ROUTE(app, "/list/")
+ .methods("GET"_method)([](const crow::request &req, crow::response &res) {
+ crow::connections::system_bus->async_method_call(
+ [&](const boost::system::error_code ec,
+ const std::vector<std::string> &object_paths) {
+
+ if (ec) {
+ res.code = 500;
+ } else {
+ nlohmann::json j{{"status", "ok"},
+ {"message", "200 OK"},
+ {"data", object_paths}};
+ res.body = j.dump();
+ }
+ res.end();
+ },
+ {"xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"},
+ "", static_cast<int32_t>(99), std::array<std::string, 0>());
+ });
+
+ CROW_ROUTE(app, "/xyz/<path>")
+ .methods("GET"_method)([](const crow::request &req, crow::response &res,
+ const std::string &path) {
+ if (outstanding_async_calls != 0) {
+ res.code = 500;
+ res.body = "request in progress";
+ res.end();
+ return;
+ }
+ using GetObjectType =
+ std::vector<std::pair<std::string, std::vector<std::string>>>;
+
+ std::string object_path = "/xyz/" + path;
+ crow::connections::system_bus->async_method_call(
+ // object_path intentially captured by value
+ [&, object_path](const boost::system::error_code ec,
+ const GetObjectType &object_names) {
+
+ if (ec) {
+ res.code = 500;
+ res.end();
+ return;
+ }
+ if (object_names.size() != 1) {
+ res.code = 404;
+ res.end();
+ return;
+ }
+
+ for (auto &interface : object_names[0].second) {
+ outstanding_async_calls++;
+ crow::connections::system_bus->async_method_call(
+ [&](const boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string, dbus::dbus_variant>> &properties) {
+ outstanding_async_calls--;
+ if (ec) {
+ std::cerr << "Bad dbus request error: " << ec;
+ } else {
+ for (auto &property : properties) {
+ boost::apply_visitor(
+ [&](auto val) {
+ object_paths[property.first] = val;
+ },
+ property.second);
+ }
+ }
+ if (outstanding_async_calls == 0) {
+ nlohmann::json j{{"status", "ok"},
+ {"message", "200 OK"},
+ {"data", object_paths}};
+ res.body = j.dump();
+ res.end();
+ object_paths.clear();
+ }
+ },
+ {object_names[0].first, object_path,
+ "org.freedesktop.DBus.Properties", "GetAll"},
+ interface);
+ }
+ },
+ {"xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject"},
+ object_path, std::array<std::string, 0>());
+ });
CROW_ROUTE(app, "/bus/system/<str>/")
.methods("GET"_method)([](const crow::request &req, crow::response &res,
const std::string &connection) {
- // Can only do one call at a time (for now)
- if (outstanding_async_calls == 0) {
- // TODO(ed) sanitize paths
- introspect_objects(res, connection, "/");
- } else {
- nlohmann::json j{{"status", "failed"}};
+ if (outstanding_async_calls != 0) {
res.code = 500;
- res.write(j.dump());
+ res.body = "request in progress";
res.end();
+ return;
}
+ introspect_objects(res, connection, "/");
});
CROW_ROUTE(app, "/bus/system/<str>/<path>")
@@ -135,7 +225,8 @@ void request_routes(Crow<Middlewares...> &app) {
// interface
if ((*it).find(".") != std::string::npos) {
break;
- // THis check is neccesary as the trailing slash gets parsed as part
+ // THis check is neccesary as the trailing slash gets parsed as
+ // part
// of our <path> specifier above, which causes the normal trailing
// backslash redirector to fail.
} else if (!it->empty()) {
@@ -260,9 +351,10 @@ void request_routes(Crow<Middlewares...> &app) {
}
methods_array.push_back(
{{"name", methods->Attribute("name")},
- {"uri", "/bus/system/" + process_name +
- object_path + "/" + interface_name +
- "/" + methods->Attribute("name")},
+ {"uri",
+ "/bus/system/" + process_name + object_path +
+ "/" + interface_name + "/" +
+ methods->Attribute("name")},
{"args", args_array}});
methods = methods->NextSiblingElement("method");
}
OpenPOWER on IntegriCloud