Break out dbus utilities into compile unit

ClangBuildAnalyzer shows that each of these dbus calls is relatively
expensive to compile, so put them in their own compile unit so they can
be compiled separately.

Tested: Redfish service validator passes

Change-Id: Ia383611182d8bc93c125248c4196898cb51fd807
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/include/dbus_privileges.hpp b/include/dbus_privileges.hpp
index a2bdd1f..9b12244 100644
--- a/include/dbus_privileges.hpp
+++ b/include/dbus_privileges.hpp
@@ -18,6 +18,7 @@
 #include <boost/url/format.hpp>
 #include <sdbusplus/unpack_properties.hpp>
 
+#include <functional>
 #include <memory>
 #include <optional>
 #include <string>
@@ -132,13 +133,14 @@
     return true;
 }
 
-template <typename CallbackFn>
-void requestUserInfo(const std::string& username,
-                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                     CallbackFn&& callback)
+inline void requestUserInfo(
+    const std::string& username,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    std::move_only_function<void(const dbus::utility::DBusPropertiesMap&)>&&
+        callback)
 {
     crow::connections::systemBus->async_method_call(
-        [asyncResp, callback = std::forward<CallbackFn>(callback)](
+        [asyncResp, callback = std::move(callback)](
             const boost::system::error_code& ec,
             const dbus::utility::DBusPropertiesMap& userInfoMap) mutable {
             if (ec)
@@ -154,10 +156,10 @@
         "xyz.openbmc_project.User.Manager", "GetUserInfo", username);
 }
 
-template <typename CallbackFn>
-void validatePrivilege(const std::shared_ptr<Request>& req,
-                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                       BaseRule& rule, CallbackFn&& callback)
+inline void validatePrivilege(
+    const std::shared_ptr<Request>& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, BaseRule& rule,
+    std::move_only_function<void()>&& callback)
 {
     if (req->session == nullptr)
     {
@@ -166,7 +168,7 @@
 
     requestUserInfo(
         req->session->username, asyncResp,
-        [req, asyncResp, &rule, callback = std::forward<CallbackFn>(callback)](
+        [req, asyncResp, &rule, callback = std::move(callback)](
             const dbus::utility::DBusPropertiesMap& userInfoMap) mutable {
             if (afterGetUserInfoValidate(*req, asyncResp, rule, userInfoMap))
             {
@@ -175,16 +177,15 @@
         });
 }
 
-template <typename CallbackFn>
-void getUserInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const std::string& username,
-                 std::shared_ptr<persistent_data::UserSession>& session,
-                 CallbackFn&& callback)
+inline void getUserInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                        const std::string& username,
+                        std::shared_ptr<persistent_data::UserSession>& session,
+                        std::move_only_function<void()>&& callback)
 {
     requestUserInfo(
         username, asyncResp,
-        [asyncResp, session, callback = std::forward<CallbackFn>(callback)](
-            const dbus::utility::DBusPropertiesMap& userInfoMap) {
+        [asyncResp, session, callback = std::move(callback)](
+            const dbus::utility::DBusPropertiesMap& userInfoMap) mutable {
             if (!populateUserInfo(*session, userInfoMap))
             {
                 BMCWEB_LOG_ERROR("Failed to populate user information");
diff --git a/include/dbus_utility.hpp b/include/dbus_utility.hpp
index b4a5e81..d1f4a84 100644
--- a/include/dbus_utility.hpp
+++ b/include/dbus_utility.hpp
@@ -5,19 +5,15 @@
 
 #include "boost_formatters.hpp"
 #include "dbus_singleton.hpp"
-#include "logging.hpp"
 
 #include <boost/system/error_code.hpp>
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/asio/property.hpp>
 #include <sdbusplus/message/native_types.hpp>
 
-#include <array>
 #include <cstddef>
 #include <cstdint>
-#include <filesystem>
 #include <functional>
-#include <regex>
 #include <span>
 #include <string>
 #include <string_view>
@@ -89,64 +85,25 @@
 
 using MapperEndPoints = std::vector<std::string>;
 
-inline void escapePathForDbus(std::string& path)
-{
-    const static std::regex reg("[^A-Za-z0-9_/]");
-    std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
-}
+void escapePathForDbus(std::string& path);
 
-inline void logError(const boost::system::error_code& ec)
-{
-    if (ec)
-    {
-        BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec);
-    }
-}
+void logError(const boost::system::error_code& ec);
 
 // gets the string N strings deep into a path
 // i.e.  /0th/1st/2nd/3rd
-inline bool getNthStringFromPath(const std::string& path, int index,
-                                 std::string& result)
-{
-    if (index < 0)
-    {
-        return false;
-    }
+bool getNthStringFromPath(const std::string& path, int index,
+                          std::string& result);
 
-    std::filesystem::path p1(path);
-    int count = -1;
-    for (const auto& element : p1)
-    {
-        if (element.has_filename())
-        {
-            ++count;
-            if (count == index)
-            {
-                result = element.stem().string();
-                break;
-            }
-        }
-    }
-    return count >= index;
-}
-
-inline void getAllProperties(
-    const std::string& service, const std::string& objectPath,
-    const std::string& interface,
-    std::function<void(const boost::system::error_code&,
-                       const DBusPropertiesMap&)>&& callback)
-{
-    sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service,
-                                      objectPath, interface,
-                                      std::move(callback));
-}
+void getAllProperties(const std::string& service, const std::string& objectPath,
+                      const std::string& interface,
+                      std::function<void(const boost::system::error_code&,
+                                         const DBusPropertiesMap&)>&& callback);
 
 template <typename PropertyType>
-inline void getProperty(
-    const std::string& service, const std::string& objectPath,
-    const std::string& interface, const std::string& propertyName,
-    std::function<void(const boost::system::error_code&, const PropertyType&)>&&
-        callback)
+void getProperty(const std::string& service, const std::string& objectPath,
+                 const std::string& interface, const std::string& propertyName,
+                 std::function<void(const boost::system::error_code&,
+                                    const PropertyType&)>&& callback)
 {
     sdbusplus::asio::getProperty<PropertyType>(
         *crow::connections::systemBus, service, objectPath, interface,
@@ -154,186 +111,80 @@
 }
 
 template <typename PropertyType>
-inline void getProperty(
-    sdbusplus::asio::connection& /*conn*/, const std::string& service,
-    const std::string& objectPath, const std::string& interface,
-    const std::string& propertyName,
-    std::function<void(const boost::system::error_code&, const PropertyType&)>&&
-        callback)
+void getProperty(sdbusplus::asio::connection& /*conn*/,
+                 const std::string& service, const std::string& objectPath,
+                 const std::string& interface, const std::string& propertyName,
+                 std::function<void(const boost::system::error_code&,
+                                    const PropertyType&)>&& callback)
 {
     getProperty(service, objectPath, interface, propertyName,
                 std::move(callback));
 }
 
-inline void getAllProperties(
-    sdbusplus::asio::connection& /*conn*/, const std::string& service,
-    const std::string& objectPath, const std::string& interface,
-    std::function<void(const boost::system::error_code&,
-                       const DBusPropertiesMap&)>&& callback)
-{
-    getAllProperties(service, objectPath, interface, std::move(callback));
-}
+void getAllProperties(sdbusplus::asio::connection& /*conn*/,
+                      const std::string& service, const std::string& objectPath,
+                      const std::string& interface,
+                      std::function<void(const boost::system::error_code&,
+                                         const DBusPropertiesMap&)>&& callback);
 
-inline void checkDbusPathExists(const std::string& path,
-                                std::function<void(bool)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback = std::move(callback)](const boost::system::error_code& ec,
-                                         const MapperGetObject& objectNames) {
-            callback(!ec && !objectNames.empty());
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetObject", path,
-        std::array<std::string, 0>());
-}
+void checkDbusPathExists(const std::string& path,
+                         std::function<void(bool)>&& callback);
 
-inline void getSubTree(
+void getSubTree(
     const std::string& path, int32_t depth,
     std::span<const std::string_view> interfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreeResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
-        interfaces);
-}
+                       const MapperGetSubTreeResponse&)>&& callback);
 
-inline void getSubTreePaths(
+void getSubTreePaths(
     const std::string& path, int32_t depth,
     std::span<const std::string_view> interfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreePathsResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreePathsResponse& subtreePaths) {
-            callback(ec, subtreePaths);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
-        interfaces);
-}
+                       const MapperGetSubTreePathsResponse&)>&& callback);
 
-inline void getAssociatedSubTree(
+void getAssociatedSubTree(
     const sdbusplus::message::object_path& associatedPath,
     const sdbusplus::message::object_path& path, int32_t depth,
     std::span<const std::string_view> interfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreeResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
-        associatedPath, path, depth, interfaces);
-}
+                       const MapperGetSubTreeResponse&)>&& callback);
 
-inline void getAssociatedSubTreePaths(
+void getAssociatedSubTreePaths(
     const sdbusplus::message::object_path& associatedPath,
     const sdbusplus::message::object_path& path, int32_t depth,
     std::span<const std::string_view> interfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreePathsResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreePathsResponse& subtreePaths) {
-            callback(ec, subtreePaths);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
-        associatedPath, path, depth, interfaces);
-}
+                       const MapperGetSubTreePathsResponse&)>&& callback);
 
-inline void getAssociatedSubTreeById(
+void getAssociatedSubTreeById(
     const std::string& id, const std::string& path,
     std::span<const std::string_view> subtreeInterfaces,
     std::string_view association,
     std::span<const std::string_view> endpointInterfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreeResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id,
-        path, subtreeInterfaces, association, endpointInterfaces);
-}
+                       const MapperGetSubTreeResponse&)>&& callback);
 
-inline void getAssociatedSubTreePathsById(
+void getAssociatedSubTreePathsById(
     const std::string& id, const std::string& path,
     std::span<const std::string_view> subtreeInterfaces,
     std::string_view association,
     std::span<const std::string_view> endpointInterfaces,
     std::function<void(const boost::system::error_code&,
-                       const MapperGetSubTreePathsResponse&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code& ec,
-            const MapperGetSubTreePathsResponse& subtreePaths) {
-            callback(ec, subtreePaths);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id,
-        path, subtreeInterfaces, association, endpointInterfaces);
-}
+                       const MapperGetSubTreePathsResponse&)>&& callback);
 
-inline void getDbusObject(
-    const std::string& path, std::span<const std::string_view> interfaces,
-    std::function<void(const boost::system::error_code&,
-                       const MapperGetObject&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](const boost::system::error_code& ec,
-                                        const MapperGetObject& object) {
-            callback(ec, object);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
-}
+void getDbusObject(const std::string& path,
+                   std::span<const std::string_view> interfaces,
+                   std::function<void(const boost::system::error_code&,
+                                      const MapperGetObject&)>&& callback);
 
-inline void getAssociationEndPoints(
+void getAssociationEndPoints(
     const std::string& path,
     std::function<void(const boost::system::error_code&,
-                       const MapperEndPoints&)>&& callback)
-{
-    getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path,
-                                 "xyz.openbmc_project.Association", "endpoints",
-                                 std::move(callback));
-}
+                       const MapperEndPoints&)>&& callback);
 
-inline void getManagedObjects(
+void getManagedObjects(
     const std::string& service, const sdbusplus::message::object_path& path,
     std::function<void(const boost::system::error_code&,
-                       const ManagedObjectType&)>&& callback)
-{
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](const boost::system::error_code& ec,
-                                        const ManagedObjectType& objects) {
-            callback(ec, objects);
-        },
-        service, path, "org.freedesktop.DBus.ObjectManager",
-        "GetManagedObjects");
-}
-
+                       const ManagedObjectType&)>&& callback);
 } // namespace utility
 } // namespace dbus
diff --git a/meson.build b/meson.build
index 440d9ee..5a8e5b6 100644
--- a/meson.build
+++ b/meson.build
@@ -377,6 +377,7 @@
     'src/boost_asio_ssl.cpp',
     'src/boost_beast.cpp',
     'src/dbus_singleton.cpp',
+    'src/dbus_utility.cpp',
     'src/json_html_serializer.cpp',
     'src/ossl_random.cpp',
     'src/ssl_key_handler.cpp',
diff --git a/src/dbus_utility.cpp b/src/dbus_utility.cpp
new file mode 100644
index 0000000..cdfd13c
--- /dev/null
+++ b/src/dbus_utility.cpp
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+
+#include "dbus_utility.hpp"
+
+#include "boost_formatters.hpp"
+#include "dbus_singleton.hpp"
+#include "logging.hpp"
+
+#include <boost/system/error_code.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/property.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <array>
+#include <cstdint>
+#include <filesystem>
+#include <functional>
+#include <regex>
+#include <span>
+#include <string>
+#include <string_view>
+#include <utility>
+
+namespace dbus
+{
+
+namespace utility
+{
+
+void escapePathForDbus(std::string& path)
+{
+    const static std::regex reg("[^A-Za-z0-9_/]");
+    std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
+}
+
+void logError(const boost::system::error_code& ec)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("DBus error: {}, cannot call method", ec);
+    }
+}
+
+// gets the string N strings deep into a path
+// i.e.  /0th/1st/2nd/3rd
+bool getNthStringFromPath(const std::string& path, int index,
+                          std::string& result)
+{
+    if (index < 0)
+    {
+        return false;
+    }
+
+    std::filesystem::path p1(path);
+    int count = -1;
+    for (const auto& element : p1)
+    {
+        if (element.has_filename())
+        {
+            ++count;
+            if (count == index)
+            {
+                result = element.stem().string();
+                break;
+            }
+        }
+    }
+    return count >= index;
+}
+
+void getAllProperties(const std::string& service, const std::string& objectPath,
+                      const std::string& interface,
+                      std::function<void(const boost::system::error_code&,
+                                         const DBusPropertiesMap&)>&& callback)
+{
+    sdbusplus::asio::getAllProperties(*crow::connections::systemBus, service,
+                                      objectPath, interface,
+                                      std::move(callback));
+}
+
+void getAllProperties(sdbusplus::asio::connection& /*conn*/,
+                      const std::string& service, const std::string& objectPath,
+                      const std::string& interface,
+                      std::function<void(const boost::system::error_code&,
+                                         const DBusPropertiesMap&)>&& callback)
+{
+    getAllProperties(service, objectPath, interface, std::move(callback));
+}
+
+void checkDbusPathExists(const std::string& path,
+                         std::function<void(bool)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback = std::move(callback)](const boost::system::error_code& ec,
+                                         const MapperGetObject& objectNames) {
+            callback(!ec && !objectNames.empty());
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetObject", path,
+        std::array<std::string, 0>());
+}
+
+void getSubTree(const std::string& path, int32_t depth,
+                std::span<const std::string_view> interfaces,
+                std::function<void(const boost::system::error_code&,
+                                   const MapperGetSubTreeResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
+        interfaces);
+}
+
+void getSubTreePaths(
+    const std::string& path, int32_t depth,
+    std::span<const std::string_view> interfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreePathsResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreePathsResponse& subtreePaths) {
+            callback(ec, subtreePaths);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
+        interfaces);
+}
+
+void getAssociatedSubTree(
+    const sdbusplus::message::object_path& associatedPath,
+    const sdbusplus::message::object_path& path, int32_t depth,
+    std::span<const std::string_view> interfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreeResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
+        associatedPath, path, depth, interfaces);
+}
+
+void getAssociatedSubTreePaths(
+    const sdbusplus::message::object_path& associatedPath,
+    const sdbusplus::message::object_path& path, int32_t depth,
+    std::span<const std::string_view> interfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreePathsResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreePathsResponse& subtreePaths) {
+            callback(ec, subtreePaths);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
+        associatedPath, path, depth, interfaces);
+}
+
+void getAssociatedSubTreeById(
+    const std::string& id, const std::string& path,
+    std::span<const std::string_view> subtreeInterfaces,
+    std::string_view association,
+    std::span<const std::string_view> endpointInterfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreeResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreeById", id,
+        path, subtreeInterfaces, association, endpointInterfaces);
+}
+
+void getAssociatedSubTreePathsById(
+    const std::string& id, const std::string& path,
+    std::span<const std::string_view> subtreeInterfaces,
+    std::string_view association,
+    std::span<const std::string_view> endpointInterfaces,
+    std::function<void(const boost::system::error_code&,
+                       const MapperGetSubTreePathsResponse&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const MapperGetSubTreePathsResponse& subtreePaths) {
+            callback(ec, subtreePaths);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePathsById", id,
+        path, subtreeInterfaces, association, endpointInterfaces);
+}
+
+void getDbusObject(const std::string& path,
+                   std::span<const std::string_view> interfaces,
+                   std::function<void(const boost::system::error_code&,
+                                      const MapperGetObject&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](const boost::system::error_code& ec,
+                                        const MapperGetObject& object) {
+            callback(ec, object);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
+}
+
+void getAssociationEndPoints(
+    const std::string& path,
+    std::function<void(const boost::system::error_code&,
+                       const MapperEndPoints&)>&& callback)
+{
+    getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", path,
+                                 "xyz.openbmc_project.Association", "endpoints",
+                                 std::move(callback));
+}
+
+void getManagedObjects(const std::string& service,
+                       const sdbusplus::message::object_path& path,
+                       std::function<void(const boost::system::error_code&,
+                                          const ManagedObjectType&)>&& callback)
+{
+    crow::connections::systemBus->async_method_call(
+        [callback{std::move(callback)}](const boost::system::error_code& ec,
+                                        const ManagedObjectType& objects) {
+            callback(ec, objects);
+        },
+        service, path, "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
+}
+
+} // namespace utility
+} // namespace dbus