Remove Redfish Node class

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 https://github.com/openbmc/bmcweb/issues/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
diff --git a/redfish-core/lib/message_registries.hpp b/redfish-core/lib/message_registries.hpp
index 455bf70..d0757b3 100644
--- a/redfish-core/lib/message_registries.hpp
+++ b/redfish-core/lib/message_registries.hpp
@@ -15,257 +15,215 @@
 */
 #pragma once
 
-#include "node.hpp"
 #include "registries.hpp"
 #include "registries/base_message_registry.hpp"
 #include "registries/openbmc_message_registry.hpp"
 #include "registries/resource_event_message_registry.hpp"
 #include "registries/task_event_message_registry.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
 
-class MessageRegistryFileCollection : public Node
+inline void requestRoutesMessageRegistryFileCollection(App& app)
 {
-  public:
-    MessageRegistryFileCollection(App& app) :
-        Node(app, "/redfish/v1/Registries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
 
-        asyncResp->res.jsonValue = {
-            {"@odata.type",
-             "#MessageRegistryFileCollection.MessageRegistryFileCollection"},
-            {"@odata.id", "/redfish/v1/Registries"},
-            {"Name", "MessageRegistryFile Collection"},
-            {"Description", "Collection of MessageRegistryFiles"},
-            {"Members@odata.count", 4},
-            {"Members",
-             {{{"@odata.id", "/redfish/v1/Registries/Base"}},
-              {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
-              {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
-              {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}}};
-    }
-};
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#MessageRegistryFileCollection."
+                                    "MessageRegistryFileCollection"},
+                    {"@odata.id", "/redfish/v1/Registries"},
+                    {"Name", "MessageRegistryFile Collection"},
+                    {"Description", "Collection of MessageRegistryFiles"},
+                    {"Members@odata.count", 4},
+                    {"Members",
+                     {{{"@odata.id", "/redfish/v1/Registries/Base"}},
+                      {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
+                      {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
+                      {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}}};
+            });
+}
 
-class MessageRegistryFile : public Node
+inline void requestRoutesMessageRegistryFile(App& app)
 {
-  public:
-    MessageRegistryFile(App& app) :
-        Node(app, "/redfish/v1/Registries/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& registry) {
+                const message_registries::Header* header;
+                std::string dmtf = "DMTF ";
+                const char* url = nullptr;
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& registry = params[0];
-        const message_registries::Header* header;
-        std::string dmtf = "DMTF ";
-        const char* url = nullptr;
-
-        if (registry == "Base")
-        {
-            header = &message_registries::base::header;
-            url = message_registries::base::url;
-        }
-        else if (registry == "TaskEvent")
-        {
-            header = &message_registries::task_event::header;
-            url = message_registries::task_event::url;
-        }
-        else if (registry == "OpenBMC")
-        {
-            header = &message_registries::openbmc::header;
-            dmtf.clear();
-        }
-        else if (registry == "ResourceEvent")
-        {
-            header = &message_registries::resource_event::header;
-            url = message_registries::resource_event::url;
-        }
-        else
-        {
-            messages::resourceNotFound(
-                asyncResp->res,
-                "#MessageRegistryFile.v1_1_0.MessageRegistryFile", registry);
-            return;
-        }
-
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/Registries/" + registry},
-            {"@odata.type", "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
-            {"Name", registry + " Message Registry File"},
-            {"Description",
-             dmtf + registry + " Message Registry File Location"},
-            {"Id", header->registryPrefix},
-            {"Registry", header->id},
-            {"Languages", {"en"}},
-            {"Languages@odata.count", 1},
-            {"Location",
-             {{{"Language", "en"},
-               {"Uri",
-                "/redfish/v1/Registries/" + registry + "/" + registry}}}},
-            {"Location@odata.count", 1}};
-
-        if (url != nullptr)
-        {
-            asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url;
-        }
-    }
-};
-
-class MessageRegistry : public Node
-{
-  public:
-    MessageRegistry(App& app) :
-        Node(app, "/redfish/v1/Registries/<str>/<str>/", std::string(),
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& registry = params[0];
-        const std::string& registry1 = params[1];
-
-        const message_registries::Header* header;
-        std::vector<const message_registries::MessageEntry*> registryEntries;
-        if (registry == "Base")
-        {
-            header = &message_registries::base::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::base::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "TaskEvent")
-        {
-            header = &message_registries::task_event::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::task_event::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "OpenBMC")
-        {
-            header = &message_registries::openbmc::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::openbmc::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "ResourceEvent")
-        {
-            header = &message_registries::resource_event::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::resource_event::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else
-        {
-            messages::resourceNotFound(
-                asyncResp->res,
-                "#MessageRegistryFile.v1_1_0.MessageRegistryFile", registry);
-            return;
-        }
-
-        if (registry != registry1)
-        {
-            messages::resourceNotFound(asyncResp->res, header->type, registry1);
-            return;
-        }
-
-        asyncResp->res.jsonValue = {
-            {"@Redfish.Copyright", header->copyright},
-            {"@odata.type", header->type},
-            {"Id", header->id},
-            {"Name", header->name},
-            {"Language", header->language},
-            {"Description", header->description},
-            {"RegistryPrefix", header->registryPrefix},
-            {"RegistryVersion", header->registryVersion},
-            {"OwningEntity", header->owningEntity}};
-
-        nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
-
-        // Go through the Message Registry and populate each Message
-        for (const message_registries::MessageEntry* message : registryEntries)
-        {
-            nlohmann::json& obj = messageObj[message->first];
-            obj = {{"Description", message->second.description},
-                   {"Message", message->second.message},
-                   {"Severity", message->second.severity},
-                   {"MessageSeverity", message->second.messageSeverity},
-                   {"NumberOfArgs", message->second.numberOfArgs},
-                   {"Resolution", message->second.resolution}};
-            if (message->second.numberOfArgs > 0)
-            {
-                nlohmann::json& messageParamArray = obj["ParamTypes"];
-                for (const char* str : message->second.paramTypes)
+                if (registry == "Base")
                 {
-                    if (str == nullptr)
-                    {
-                        break;
-                    }
-                    messageParamArray.push_back(str);
+                    header = &message_registries::base::header;
+                    url = message_registries::base::url;
                 }
-            }
-        }
-    }
-};
+                else if (registry == "TaskEvent")
+                {
+                    header = &message_registries::task_event::header;
+                    url = message_registries::task_event::url;
+                }
+                else if (registry == "OpenBMC")
+                {
+                    header = &message_registries::openbmc::header;
+                    dmtf.clear();
+                }
+                else if (registry == "ResourceEvent")
+                {
+                    header = &message_registries::resource_event::header;
+                    url = message_registries::resource_event::url;
+                }
+                else
+                {
+                    messages::resourceNotFound(
+                        asyncResp->res,
+                        "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
+                        registry);
+                    return;
+                }
+
+                asyncResp->res.jsonValue = {
+                    {"@odata.id", "/redfish/v1/Registries/" + registry},
+                    {"@odata.type",
+                     "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
+                    {"Name", registry + " Message Registry File"},
+                    {"Description",
+                     dmtf + registry + " Message Registry File Location"},
+                    {"Id", header->registryPrefix},
+                    {"Registry", header->id},
+                    {"Languages", {"en"}},
+                    {"Languages@odata.count", 1},
+                    {"Location",
+                     {{{"Language", "en"},
+                       {"Uri", "/redfish/v1/Registries/" + registry + "/" +
+                                   registry}}}},
+                    {"Location@odata.count", 1}};
+
+                if (url != nullptr)
+                {
+                    asyncResp->res.jsonValue["Location"][0]["PublicationUri"] =
+                        url;
+                }
+            });
+}
+
+inline void requestRoutesMessageRegistry(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& registry, const std::string& registry1)
+
+            {
+                const message_registries::Header* header;
+                std::vector<const message_registries::MessageEntry*>
+                    registryEntries;
+                if (registry == "Base")
+                {
+                    header = &message_registries::base::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::base::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "TaskEvent")
+                {
+                    header = &message_registries::task_event::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::task_event::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "OpenBMC")
+                {
+                    header = &message_registries::openbmc::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::openbmc::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "ResourceEvent")
+                {
+                    header = &message_registries::resource_event::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::resource_event::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else
+                {
+                    messages::resourceNotFound(
+                        asyncResp->res,
+                        "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
+                        registry);
+                    return;
+                }
+
+                if (registry != registry1)
+                {
+                    messages::resourceNotFound(asyncResp->res, header->type,
+                                               registry1);
+                    return;
+                }
+
+                asyncResp->res.jsonValue = {
+                    {"@Redfish.Copyright", header->copyright},
+                    {"@odata.type", header->type},
+                    {"Id", header->id},
+                    {"Name", header->name},
+                    {"Language", header->language},
+                    {"Description", header->description},
+                    {"RegistryPrefix", header->registryPrefix},
+                    {"RegistryVersion", header->registryVersion},
+                    {"OwningEntity", header->owningEntity}};
+
+                nlohmann::json& messageObj =
+                    asyncResp->res.jsonValue["Messages"];
+
+                // Go through the Message Registry and populate each Message
+                for (const message_registries::MessageEntry* message :
+                     registryEntries)
+                {
+                    nlohmann::json& obj = messageObj[message->first];
+                    obj = {{"Description", message->second.description},
+                           {"Message", message->second.message},
+                           {"Severity", message->second.severity},
+                           {"MessageSeverity", message->second.messageSeverity},
+                           {"NumberOfArgs", message->second.numberOfArgs},
+                           {"Resolution", message->second.resolution}};
+                    if (message->second.numberOfArgs > 0)
+                    {
+                        nlohmann::json& messageParamArray = obj["ParamTypes"];
+                        for (const char* str : message->second.paramTypes)
+                        {
+                            if (str == nullptr)
+                            {
+                                break;
+                            }
+                            messageParamArray.push_back(str);
+                        }
+                    }
+                }
+            });
+}
 
 } // namespace redfish