Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Redfish Node class should be removed #181

Closed
edtanous opened this issue Feb 7, 2021 · 1 comment
Closed

The Redfish Node class should be removed #181

edtanous opened this issue Feb 7, 2021 · 1 comment
Labels
enhancement New feature or request

Comments

@edtanous
Copy link
Contributor

edtanous commented Feb 7, 2021

The redfish Node class at one point had grand ambitions of being a central spot for putting Redfish specific routing code, but as the future came and went, most of the abstractions it provided ended up getting rolled into the core, and today, all it is is a thin wrapper around app.routeDynamic().

The key reason the Node class existed originally was because the internal route handler couldn't declare duplicate routes with different verbs, nor could it handle permissions. Both of these issues have been solved for some time now.

Because of the inheritance-based API the Node class provides, almost every route handler has boilerplate like.

if (params.size() != 1)
{
    messages::internalError(asyncResp->res);
    return;
}

At the top of every handler, which is problematic, and removes a lot of the compile-time routing magic that BMCWEB_ROUTE can do. It also requires construction and copy of a new string for every invocation.

The core of this enhancement will mostly be splitting up all the various doGet, doPatch, doPut, and other methods into their own BMCWEB_ROUTE declarations,

For example, this code from certificate service

class HTTPSCertificate : public Node
{
  public:
    HTTPSCertificate(App& app) :
        Node(app,
             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"
             "<str>/",
             std::string())
    {
        entityPrivileges = {
            {boost::beast::http::verb::get, {{"Login"}}},
            {boost::beast::http::verb::head, {{"Login"}}},
            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
    }

    void doGet(crow::Response& res, const crow::Request& req,
               const std::vector<std::string>& params) override
    {
        if (params.size() != 1)
        {
            messages::internalError(asyncResp->res);
            return;
        }
       const std::string& id = params[0];
      // existing implementation
};

Would turn into

BMCWEB_ROUTE("/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
.privileges({"ConfigureComponents"})
.methods(boost::beast::http::verb::get)(
    [](const crow::Request& req, crow::Response& res, const std::string& id) {
        // existing implementation
    });

Just looking the two blocks of code is motivation enough to do this, the second has less boilerplate, and many more coding errors are caught at compile time instead of runtime.

While the Node class is mostly dead, there is one exception that got added recently in the form of the isAllowedWithoutConfigureSelf, which got added to the node class. So far as I'm able to discern, it's a static method that has no interaction with the node class whatsoever, and can easily be moved to a non-member method without any changes.

@edtanous edtanous added the enhancement New feature or request label Feb 7, 2021
@jebr224
Copy link
Contributor

jebr224 commented Apr 13, 2021

Work in progress
(see https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/42083/)

bradbishop pushed a commit that referenced this issue Jun 3, 2021
Reduces the total number of lines and will allow for easier testing of
the redfish responses.

A main purpose of the node class was to set app.routeDynamic(). However
now app.routeDynamic can handle the complexity that was once in critical
to node. The macro app.routeDynamic() provides a shorter cleaner
interface to the unerlying app.routeDyanic call. The old pattern set
permissions for 6 interfaces (get, head, patch, put, delete_, and post)
even if only one interface is created. That pattern creates unneeded
code that can be safely removed with no effect.
Unit test for the responses would have to mock the node the class in
order to fully test responses.

see #181

The following files still need node to be extracted.

virtual_media.hpp
account_service.hpp
redfish_sessions.hpp
ethernet.hpp

The files above use a pattern that is not trivial to address. Often their
responses call an async lambda capturing the inherited class. ie
(https://github.com/openbmc/bmcweb/blob/ffed87b5ad1797ca966d030e7f979770
28d258fa/redfish-core/lib/account_service.hpp#L1393)
At a later point I plan to remove node from the files above.

Tested:
I ran the docker unit test with the following command.
WORKSPACE=$(pwd) UNIT_TEST_PKG=bmcweb
 ./openbmc-build-scripts/run-unit-test-docker.sh

I ran the validator and this change did not create any issues.
python3 RedfishServiceValidator.py -c config.ini

Signed-off-by: John Edward Broadbent <jebr@google.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I147a0289c52cb4198345b1ad9bfe6fdddf57f3df
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants