Improved Refish subroutes

- getSubroutes() is now a method of the Node class
- getSubroutes() is called only once per node at construction time,
  not at each GET request
- template parameter removed from the Node class

Change-Id: Ie4eb8766717aae566c13c295458fe0dba8ab84c0
Signed-off-by: Borawski.Lukasz <lukasz.borawski@intel.com>
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 5cbc034..dafa605 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -33,31 +33,29 @@
   AccountService(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(accountServiceOpMap)),
              "/redfish/v1/AccountService/") {
-    nodeJson["@odata.id"] = "/redfish/v1/AccountService";
-    nodeJson["@odata.type"] = "#AccountService.v1_1_0.AccountService";
-    nodeJson["@odata.context"] =
+    Node::json["@odata.id"] = "/redfish/v1/AccountService";
+    Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
+    Node::json["@odata.context"] =
         "/redfish/v1/$metadata#AccountService.AccountService";
-    nodeJson["Id"] = "AccountService";
-    nodeJson["Description"] = "BMC User Accounts";
-    nodeJson["Name"] = "Account Service";
-    nodeJson["Status"]["State"] = "Enabled";
-    nodeJson["Status"]["Health"] = "OK";
-    nodeJson["Status"]["HealthRollup"] = "OK";
-    nodeJson["ServiceEnabled"] = true;
-    nodeJson["MinPasswordLength"] = 1;
-    nodeJson["MaxPasswordLength"] = 20;
-    nodeJson["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
-    nodeJson["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
+    Node::json["Id"] = "AccountService";
+    Node::json["Description"] = "BMC User Accounts";
+    Node::json["Name"] = "Account Service";
+    Node::json["Status"]["State"] = "Enabled";
+    Node::json["Status"]["Health"] = "OK";
+    Node::json["Status"]["HealthRollup"] = "OK";
+    Node::json["ServiceEnabled"] = true;
+    Node::json["MinPasswordLength"] = 1;
+    Node::json["MaxPasswordLength"] = 20;
+    Node::json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
+    Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
   }
 
  private:
   void doGet(crow::response& res, const crow::request& req,
              const std::vector<std::string>& params) override {
-    res.json_value = nodeJson;
+    res.json_value = Node::json;
     res.end();
   }
-
-  nlohmann::json nodeJson;
 };
 
 }  // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 58d5b94..75857a1 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -40,14 +40,13 @@
 
 class Sessions : public Node {
  public:
-  template <typename CrowApp>
   Sessions(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(sessionOpMap)),
              "/redfish/v1/SessionService/Sessions/<str>", std::string()) {
-    nodeJson["@odata.type"] = "#Session.v1_0_2.Session";
-    nodeJson["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
-    nodeJson["Name"] = "User Session";
-    nodeJson["Description"] = "Manager User Session";
+    Node::json["@odata.type"] = "#Session.v1_0_2.Session";
+    Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
+    Node::json["Name"] = "User Session";
+    Node::json["Description"] = "Manager User Session";
   }
 
  private:
@@ -62,12 +61,12 @@
       return;
     }
 
-    nodeJson["Id"] = session->unique_id;
-    nodeJson["UserName"] = session->username;
-    nodeJson["@odata.id"] =
+    Node::json["Id"] = session->unique_id;
+    Node::json["UserName"] = session->username;
+    Node::json["@odata.id"] =
         "/redfish/v1/SessionService/Sessions/" + session->unique_id;
 
-    res.json_value = nodeJson;
+    res.json_value = Node::json;
     res.end();
   }
 
@@ -100,25 +99,22 @@
    * data for created member which should match member's doGet result in 100%
    */
   friend SessionCollection;
-
-  nlohmann::json nodeJson;
 };
 
 class SessionCollection : public Node {
  public:
-  template <typename CrowApp>
   SessionCollection(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(sessionCollectionOpMap)),
              "/redfish/v1/SessionService/Sessions/"),
         memberSession(app) {
-    nodeJson["@odata.type"] = "#SessionCollection.SessionCollection";
-    nodeJson["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
-    nodeJson["@odata.context"] =
+    Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
+    Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
+    Node::json["@odata.context"] =
         "/redfish/v1/$metadata#SessionCollection.SessionCollection";
-    nodeJson["Name"] = "Session Collection";
-    nodeJson["Description"] = "Session Collection";
-    nodeJson["Members@odata.count"] = 0;
-    nodeJson["Members"] = nlohmann::json::array();
+    Node::json["Name"] = "Session Collection";
+    Node::json["Description"] = "Session Collection";
+    Node::json["Members@odata.count"] = 0;
+    Node::json["Members"] = nlohmann::json::array();
   }
 
  private:
@@ -128,14 +124,14 @@
         crow::PersistentData::session_store->get_unique_ids(
             false, crow::PersistentData::PersistenceType::TIMEOUT);
 
-    nodeJson["Members@odata.count"] = session_ids.size();
-    nodeJson["Members"] = nlohmann::json::array();
+    Node::json["Members@odata.count"] = session_ids.size();
+    Node::json["Members"] = nlohmann::json::array();
     for (const auto& uid : session_ids) {
-      nodeJson["Members"].push_back(
+      Node::json["Members"].push_back(
           {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
     }
 
-    res.json_value = nodeJson;
+    res.json_value = Node::json;
     res.end();
   }
 
@@ -235,7 +231,6 @@
    * member's doGet, as they should return 100% matching data
    */
   Sessions memberSession;
-  nlohmann::json nodeJson;
 };
 
 }  // namespace redfish
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index 6a3c0d7..f1a1c61 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -37,58 +37,52 @@
 
 class Roles : public Node {
  public:
-  template <typename CrowApp>
   Roles(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(roleOpMap)),
              "/redfish/v1/AccountService/Roles/Administrator/") {
-    nodeJson["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
-    nodeJson["@odata.type"] = "#Role.v1_0_2.Role";
-    nodeJson["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
-    nodeJson["Id"] = "Administrator";
-    nodeJson["Name"] = "User Role";
-    nodeJson["Description"] = "Administrator User Role";
-    nodeJson["IsPredefined"] = true;
-    nodeJson["AssignedPrivileges"] = {"Login", "ConfigureManager",
-                                      "ConfigureUsers", "ConfigureSelf",
-                                      "ConfigureComponents"};
-    nodeJson["OemPrivileges"] = nlohmann::json::array();
+    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
+    Node::json["@odata.type"] = "#Role.v1_0_2.Role";
+    Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
+    Node::json["Id"] = "Administrator";
+    Node::json["Name"] = "User Role";
+    Node::json["Description"] = "Administrator User Role";
+    Node::json["IsPredefined"] = true;
+    Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
+                                        "ConfigureUsers", "ConfigureSelf",
+                                        "ConfigureComponents"};
+    Node::json["OemPrivileges"] = nlohmann::json::array();
   }
 
  private:
   void doGet(crow::response& res, const crow::request& req,
              const std::vector<std::string>& params) override {
-    res.json_value = nodeJson;
+    res.json_value = Node::json;
     res.end();
   }
-
-  nlohmann::json nodeJson;
 };
 
 class RoleCollection : public Node {
  public:
-  template <typename CrowApp>
   RoleCollection(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(roleCollectionOpMap)),
              "/redfish/v1/AccountService/Roles/") {
-    nodeJson["@odata.id"] = "/redfish/v1/AccountService/Roles";
-    nodeJson["@odata.type"] = "#RoleCollection.RoleCollection";
-    nodeJson["@odata.context"] =
+    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
+    Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
+    Node::json["@odata.context"] =
         "/redfish/v1/$metadata#RoleCollection.RoleCollection";
-    nodeJson["Name"] = "Roles Collection";
-    nodeJson["Description"] = "BMC User Roles";
-    nodeJson["Members@odata.count"] = 1;
-    nodeJson["Members"] = {
-        {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
+    Node::json["Name"] = "Roles Collection";
+    Node::json["Description"] = "BMC User Roles";
+    Node::json["Members@odata.count"] = 1;
+    Node::json["Members"] = {
+        {"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}};
   }
 
  private:
   void doGet(crow::response& res, const crow::request& req,
              const std::vector<std::string>& params) override {
-    res.json_value = nodeJson;
+    res.json_value = Node::json;
     res.end();
   }
-
-  nlohmann::json nodeJson;
 };
 
 }  // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 24ad79d..129d58d 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -29,34 +29,30 @@
 
 class ServiceRoot : public Node {
  public:
-  template <typename CrowApp>
   ServiceRoot(CrowApp& app)
       : Node(app, EntityPrivileges(std::move(serviceRootOpMap)),
              "/redfish/v1/") {
-    nodeJson["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
-    nodeJson["@odata.id"] = "/redfish/v1";
-    nodeJson["@odata.context"] =
+    Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
+    Node::json["@odata.id"] = "/redfish/v1/";
+    Node::json["@odata.context"] =
         "/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
-    nodeJson["Id"] = "RootService";
-    nodeJson["Name"] = "Root Service";
-    nodeJson["RedfishVersion"] = "1.1.0";
-    nodeJson["Links"]["Sessions"] = {
-        {"@odata.id", "/redfish/v1/SessionService/Sessions/"}};
-    nodeJson["UUID"] =
+    Node::json["Id"] = "RootService";
+    Node::json["Name"] = "Root Service";
+    Node::json["RedfishVersion"] = "1.1.0";
+    Node::json["Links"]["Sessions"] = {
+        {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+    Node::json["UUID"] =
         app.template get_middleware<crow::PersistentData::Middleware>()
             .system_uuid;
-    getRedfishSubRoutes(app, "/redfish/v1/", nodeJson);
   }
 
  private:
   void doGet(crow::response& res, const crow::request& req,
              const std::vector<std::string>& params) override {
     res.add_header("Content-Type", "application/json");
-    res.body = nodeJson.dump();
+    res.json_value = Node::json;
     res.end();
   }
-
-  nlohmann::json nodeJson;
 };
 
 }  // namespace redfish