REST: Add DELETE support
Add support for the DELETE verb. This verb will cause the
Delete method on the xyz.openbmc_project.Object.Delete interface
to be called on the specified object path. An error will be
returned if that interface/method doesn't exist on that path.
The code is similar to the method handling code, except it
doesn't need to parse any argument JSON, and it is looking only
at a specific interface. It does share the code path that
introspects the object to find a method and call it.
Tested: Used it to delete error logs.
Change-Id: Ica90b0d80049e6bc59fe2b8456948696054f4a8b
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 4a34f5c..c3908ca 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -417,6 +417,7 @@
crow::Response &res;
std::string path;
std::string methodName;
+ std::string interfaceName;
nlohmann::json arguments;
};
@@ -783,6 +784,14 @@
interfaceNode->Attribute("name");
if (thisInterfaceName != nullptr)
{
+ if (!transaction->interfaceName.empty() &&
+ (transaction->interfaceName != thisInterfaceName))
+ {
+ interfaceNode =
+ interfaceNode->NextSiblingElement("interface");
+ continue;
+ }
+
tinyxml2::XMLElement *methodNode =
interfaceNode->FirstChildElement("method");
while (methodNode != nullptr)
@@ -939,6 +948,42 @@
std::array<std::string, 0>());
}
+void handleDelete(const crow::Request &req, crow::Response &res,
+ const std::string &objectPath)
+{
+ BMCWEB_LOG_DEBUG << "handleDelete on path: " << objectPath;
+
+ crow::connections::systemBus->async_method_call(
+ [&res, objectPath](
+ const boost::system::error_code ec,
+ const std::vector<std::pair<std::string, std::vector<std::string>>>
+ &interfaceNames) {
+ if (ec || interfaceNames.size() <= 0)
+ {
+ BMCWEB_LOG_ERROR << "Can't find object";
+ setErrorResponse(res, boost::beast::http::status::not_found,
+ notFoundDesc, notFoundMsg);
+ res.end();
+ return;
+ }
+
+ auto transaction = std::make_shared<InProgressActionData>(res);
+ transaction->path = objectPath;
+ transaction->methodName = "Delete";
+ transaction->interfaceName = "xyz.openbmc_project.Object.Delete";
+
+ for (const std::pair<std::string, std::vector<std::string>>
+ &object : interfaceNames)
+ {
+ findActionOnInterface(transaction, object.first);
+ }
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject", objectPath,
+ std::array<const char *, 0>());
+}
+
void handleList(crow::Response &res, const std::string &objectPath,
int32_t depth = 0)
{
@@ -1393,6 +1438,11 @@
handlePut(req, res, objectPath, destProperty);
return;
}
+ else if (req.method() == "DELETE"_method)
+ {
+ handleDelete(req, res, objectPath);
+ return;
+ }
setErrorResponse(res, boost::beast::http::status::method_not_allowed,
methodNotAllowedDesc, methodNotAllowedMsg);
@@ -1444,7 +1494,7 @@
});
BMCWEB_ROUTE(app, "/xyz/<path>")
- .methods("GET"_method, "PUT"_method, "POST"_method)(
+ .methods("GET"_method, "PUT"_method, "POST"_method, "DELETE"_method)(
[](const crow::Request &req, crow::Response &res,
const std::string &path) {
std::string objectPath = "/xyz/" + path;
@@ -1452,7 +1502,7 @@
});
BMCWEB_ROUTE(app, "/org/<path>")
- .methods("GET"_method, "PUT"_method, "POST"_method)(
+ .methods("GET"_method, "PUT"_method, "POST"_method, "DELETE"_method)(
[](const crow::Request &req, crow::Response &res,
const std::string &path) {
std::string objectPath = "/org/" + path;