Refactor getCollectionMembers

- Add subtree parameter so that search can be restricted to arbitrary
  hierarchy.
- Use the simpler GetSubTreePaths instead of GetSubTree
- Fix object path string search to ensure the substr is at least 1
  character.

Tested: As part of child change Iab94b7fd49a9462cb0eca6f8ea0754f5fb241053

Signed-off-by: Jonathan Doman <jonathan.doman@intel.com>
Change-Id: I2db134738972926898c03b0340ef64ca7639e40e
diff --git a/redfish-core/include/utils/collection.hpp b/redfish-core/include/utils/collection.hpp
index 85a462a..bcf5c16 100644
--- a/redfish-core/include/utils/collection.hpp
+++ b/redfish-core/include/utils/collection.hpp
@@ -11,28 +11,28 @@
 {
 
 /**
- * @brief Populate the collection "Members" from a GetSubTree search of
+ * @brief Populate the collection "Members" from a GetSubTreePaths search of
  *        inventory
  *
  * @param[i,o] aResp  Async response object
  * @param[i]   collectionPath  Redfish collection path which is used for the
  *             Members Redfish Path
  * @param[i]   interfaces  List of interfaces to constrain the GetSubTree search
+ * @param[in]  subtree     D-Bus base path to constrain search to.
  *
  * @return void
  */
-inline void getCollectionMembers(std::shared_ptr<AsyncResp> aResp,
-                                 const std::string& collectionPath,
-                                 const std::vector<const char*>& interfaces)
+inline void
+    getCollectionMembers(std::shared_ptr<AsyncResp> aResp,
+                         const std::string& collectionPath,
+                         const std::vector<const char*>& interfaces,
+                         const char* subtree = "/xyz/openbmc_project/inventory")
 {
     BMCWEB_LOG_DEBUG << "Get collection members for: " << collectionPath;
     crow::connections::systemBus->async_method_call(
-        [collectionPath, aResp{std::move(aResp)}](
-            const boost::system::error_code ec,
-            const boost::container::flat_map<
-                std::string, boost::container::flat_map<
-                                 std::string, std::vector<std::string>>>&
-                subtree) {
+        [collectionPath,
+         aResp{std::move(aResp)}](const boost::system::error_code ec,
+                                  const std::vector<std::string>& objects) {
             if (ec)
             {
                 BMCWEB_LOG_DEBUG << "DBUS response error";
@@ -42,22 +42,22 @@
             nlohmann::json& members = aResp->res.jsonValue["Members"];
             members = nlohmann::json::array();
 
-            for (const auto& object : subtree)
+            for (const auto& object : objects)
             {
-                auto iter = object.first.rfind('/');
-                if ((iter != std::string::npos) && (iter < object.first.size()))
+                auto pos = object.rfind('/');
+                if ((pos != std::string::npos) && (pos < (object.size() - 1)))
                 {
                     members.push_back(
-                        {{"@odata.id", collectionPath + "/" +
-                                           object.first.substr(iter + 1)}});
+                        {{"@odata.id",
+                          collectionPath + "/" + object.substr(pos + 1)}});
                 }
             }
             aResp->res.jsonValue["Members@odata.count"] = members.size();
         },
         "xyz.openbmc_project.ObjectMapper",
         "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/inventory", 0, interfaces);
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", subtree, 0,
+        interfaces);
 }
 
 } // namespace collection_util