Update CollectionMembers to use UrlFromPieces

Refactor getCollectionMembers to make sure all Url created with dbus
paths are generated via UrlFromPieces helper function. This allow us to
manage all URL generated from dbus in one place and allow us to make
future changes to affect all resources.

We can make changes to all resources easier if they are all managed by
one function.

Tested:
Redfish Validator Passed. All Collections working as expected and match
previous implmentation.

Change-Id: I5d3b2b32f047ce4f20a2287a36a3e099efd6eace
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/redfish-core/include/utils/collection.hpp b/redfish-core/include/utils/collection.hpp
index 7a845d1..97f622d 100644
--- a/redfish-core/include/utils/collection.hpp
+++ b/redfish-core/include/utils/collection.hpp
@@ -24,11 +24,12 @@
  */
 inline void
     getCollectionMembers(std::shared_ptr<bmcweb::AsyncResp> aResp,
-                         const std::string& collectionPath,
+                         const boost::urls::url& collectionPath,
                          const std::vector<const char*>& interfaces,
                          const char* subtree = "/xyz/openbmc_project/inventory")
 {
-    BMCWEB_LOG_DEBUG << "Get collection members for: " << collectionPath;
+    BMCWEB_LOG_DEBUG << "Get collection members for: "
+                     << collectionPath.string();
     crow::connections::systemBus->async_method_call(
         [collectionPath, aResp{std::move(aResp)}](
             const boost::system::error_code ec,
@@ -65,11 +66,10 @@
         members = nlohmann::json::array();
         for (const std::string& leaf : pathNames)
         {
-            std::string newPath = collectionPath;
-            newPath += '/';
-            newPath += leaf;
+            boost::urls::url url = collectionPath;
+            crow::utility::appendUrlPieces(url, leaf);
             nlohmann::json::object_t member;
-            member["@odata.id"] = std::move(newPath);
+            member["@odata.id"] = std::move(url);
             members.push_back(std::move(member));
         }
         aResp->res.jsonValue["Members@odata.count"] = members.size();
diff --git a/redfish-core/lib/cable.hpp b/redfish-core/lib/cable.hpp
index 0b8cd0f..89f41e2 100644
--- a/redfish-core/lib/cable.hpp
+++ b/redfish-core/lib/cable.hpp
@@ -179,7 +179,7 @@
         asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
 
         collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Cables",
+            asyncResp, boost::urls::url("/redfish/v1/Cables"),
             {"xyz.openbmc_project.Inventory.Item.Cable"});
         });
 }
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index 2614115..4c4a9c4 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -148,7 +148,7 @@
     asyncResp->res.jsonValue["Name"] = "Chassis Collection";
 
     collection_util::getCollectionMembers(
-        asyncResp, "/redfish/v1/Chassis",
+        asyncResp, boost::urls::url("/redfish/v1/Chassis"),
         {"xyz.openbmc_project.Inventory.Item.Board",
          "xyz.openbmc_project.Inventory.Item.Chassis"});
 }
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index dd535f7..f8af707 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -793,7 +793,7 @@
             "/redfish/v1/Systems/system/Memory";
 
         collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Systems/system/Memory",
+            asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
             {"xyz.openbmc_project.Inventory.Item.Dimm"});
         });
 }
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
index 6b79c51..33c8c9c 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -16,9 +16,6 @@
 namespace telemetry
 {
 
-constexpr const char* metricReportUri =
-    "/redfish/v1/TelemetryService/MetricReports";
-
 using Readings =
     std::vector<std::tuple<std::string, std::string, double, uint64_t>>;
 using TimestampReadings = std::tuple<uint64_t, Readings>;
@@ -77,11 +74,14 @@
 
         asyncResp->res.jsonValue["@odata.type"] =
             "#MetricReportCollection.MetricReportCollection";
-        asyncResp->res.jsonValue["@odata.id"] = telemetry::metricReportUri;
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/TelemetryService/MetricReports";
         asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
         const std::vector<const char*> interfaces{telemetry::reportInterface};
         collection_util::getCollectionMembers(
-            asyncResp, telemetry::metricReportUri, interfaces,
+            asyncResp,
+            boost::urls::url("/redfish/v1/TelemetryService/MetricReports"),
+            interfaces,
             "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
         });
 }
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index e15e920..bc1b894 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -23,9 +23,6 @@
 namespace telemetry
 {
 
-constexpr const char* metricReportDefinitionUri =
-    "/redfish/v1/TelemetryService/MetricReportDefinitions";
-
 using ReadingParameters =
     std::vector<std::tuple<sdbusplus::message::object_path, std::string,
                            std::string, std::string>>;
@@ -363,11 +360,14 @@
             "#MetricReportDefinitionCollection."
             "MetricReportDefinitionCollection";
         asyncResp->res.jsonValue["@odata.id"] =
-            telemetry::metricReportDefinitionUri;
+            "/redfish/v1/TelemetryService/MetricReportDefinitions";
         asyncResp->res.jsonValue["Name"] = "Metric Definition Collection";
         const std::vector<const char*> interfaces{telemetry::reportInterface};
         collection_util::getCollectionMembers(
-            asyncResp, telemetry::metricReportDefinitionUri, interfaces,
+            asyncResp,
+            boost::urls::url(
+                "/redfish/v1/TelemetryService/MetricReportDefinitions"),
+            interfaces,
             "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
         });
 
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index 8bc8cf0..ecf1c65 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -1074,8 +1074,9 @@
                 // Collection of all Config objects under this CPU.
                 collection_util::getCollectionMembers(
                     asyncResp,
-                    "/redfish/v1/Systems/system/Processors/" + cpuName +
-                        "/OperatingConfigs",
+                    crow::utility::urlFromPieces("redfish", "v1", "Systems",
+                                                 "system", "Processors",
+                                                 cpuName, "OperatingConfigs"),
                     {"xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"},
                     object.c_str());
                 return;
@@ -1181,7 +1182,8 @@
             "/redfish/v1/Systems/system/Processors";
 
         collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Systems/system/Processors",
+            asyncResp,
+            boost::urls::url("/redfish/v1/Systems/system/Processors"),
             std::vector<const char*>(processorInterfaces.begin(),
                                      processorInterfaces.end()));
         });
diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp
index 811d355..ad38556 100644
--- a/redfish-core/lib/trigger.hpp
+++ b/redfish-core/lib/trigger.hpp
@@ -20,7 +20,6 @@
 {
 constexpr const char* triggerInterface =
     "xyz.openbmc_project.Telemetry.Trigger";
-constexpr const char* triggerUri = "/redfish/v1/TelemetryService/Triggers";
 
 using NumericThresholdParams =
     std::tuple<std::string, uint64_t, std::string, double>;
@@ -302,11 +301,14 @@
         }
         asyncResp->res.jsonValue["@odata.type"] =
             "#TriggersCollection.TriggersCollection";
-        asyncResp->res.jsonValue["@odata.id"] = telemetry::triggerUri;
+        asyncResp->res.jsonValue["@odata.id"] =
+            "/redfish/v1/TelemetryService/Triggers";
         asyncResp->res.jsonValue["Name"] = "Triggers Collection";
         const std::vector<const char*> interfaces{telemetry::triggerInterface};
         collection_util::getCollectionMembers(
-            asyncResp, telemetry::triggerUri, interfaces,
+            asyncResp,
+            boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
+            interfaces,
             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
         });
 }