bmcweb: Redfish away from json cache

In the original incarnation of bmcweb, route registration was done
automatically.  This has proved to be a terrible idea, wraught with
corner cases and issues.

The route registration is currently the only user of the
redfish::Node::json element.  Unfortunately, as written, this structure
consumes a lot of memory that's duplicated and not very useful.  From a
performance perspective, there is almost no difference between
rebuilding the structure for each GET request, and having the "cache"
that needs to be copied into the response and modified before it can be
useful.

In the programming tradeoffs for bmc, lower memory usage is more important
than latency, especially at these levels.

Change-Id: I785e8352123e5e886acf05cd59cb23648f93839d
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 2dda752..cf4af02 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -617,9 +617,6 @@
     BMCLogServiceCollection(CrowApp &app) :
         Node(app, "/redfish/v1/Managers/bmc/LogServices/")
     {
-        // Collections use static ID for SubRoute to add to its parent, but only
-        // load dynamic data so the duplicate static members don't get displayed
-        Node::json["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices";
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
             {boost::beast::http::verb::head, {{"Login"}}},
@@ -670,9 +667,6 @@
     BMCJournalLogService(CrowApp &app) :
         Node(app, "/redfish/v1/Managers/bmc/LogServices/Journal/")
     {
-        // Set the id for SubRoute
-        Node::json["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Journal";
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
             {boost::beast::http::verb::head, {{"Login"}}},
@@ -687,10 +681,10 @@
                const std::vector<std::string> &params) override
     {
         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-        // Copy over the static data to include the entries added by SubRoute
-        asyncResp->res.jsonValue = Node::json;
         asyncResp->res.jsonValue["@odata.type"] =
             "#LogService.v1_1_0.LogService";
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/Managers/bmc/LogServices/Journal";
         asyncResp->res.jsonValue["@odata.context"] =
             "/redfish/v1/$metadata#LogService.LogService";
         asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service";
@@ -756,10 +750,6 @@
     BMCJournalLogEntryCollection(CrowApp &app) :
         Node(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/")
     {
-        // Collections use static ID for SubRoute to add to its parent, but only
-        // load dynamic data so the duplicate static members don't get displayed
-        Node::json["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
             {boost::beast::http::verb::head, {{"Login"}}},
@@ -789,6 +779,8 @@
         // it has a duplicate entry for members
         asyncResp->res.jsonValue["@odata.type"] =
             "#LogEntryCollection.LogEntryCollection";
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
         asyncResp->res.jsonValue["@odata.context"] =
             "/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection";
         asyncResp->res.jsonValue["@odata.id"] =
@@ -796,6 +788,8 @@
         asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
         asyncResp->res.jsonValue["Description"] =
             "Collection of BMC Journal Entries";
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/Managers/bmc/LogServices/BmcLog/Entries";
         nlohmann::json &logEntryArray = asyncResp->res.jsonValue["Members"];
         logEntryArray = nlohmann::json::array();
 
@@ -924,8 +918,6 @@
     CPULogService(CrowApp &app) :
         Node(app, "/redfish/v1/Managers/bmc/LogServices/CpuLog/")
     {
-        // Set the id for SubRoute
-        Node::json["@odata.id"] = "/redfish/v1/Managers/bmc/LogServices/CpuLog";
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
             {boost::beast::http::verb::head, {{"Login"}}},
@@ -944,7 +936,8 @@
     {
         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
         // Copy over the static data to include the entries added by SubRoute
-        asyncResp->res.jsonValue = Node::json;
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/Managers/bmc/LogServices/CpuLog";
         asyncResp->res.jsonValue["@odata.type"] =
             "#LogService.v1_1_0.LogService";
         asyncResp->res.jsonValue["@odata.context"] =
@@ -976,10 +969,6 @@
     CPULogEntryCollection(CrowApp &app) :
         Node(app, "/redfish/v1/Managers/bmc/LogServices/CpuLog/Entries/")
     {
-        // Collections use static ID for SubRoute to add to its parent, but only
-        // load dynamic data so the duplicate static members don't get displayed
-        Node::json["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/CpuLog/Entries";
         entityPrivileges = {
             {boost::beast::http::verb::get, {{"Login"}}},
             {boost::beast::http::verb::head, {{"Login"}}},
@@ -1015,6 +1004,8 @@
             }
             asyncResp->res.jsonValue["@odata.type"] =
                 "#LogEntryCollection.LogEntryCollection";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Managers/bmc/LogServices/CpuLog/Entries";
             asyncResp->res.jsonValue["@odata.context"] =
                 "/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection";
             asyncResp->res.jsonValue["@odata.id"] =