Create separate file for ConfigMgr class

As the ldap_configuration.cpp was getting long
so it is good to create the seprate file for
ConfigMgr.

TestedBy:
         Ran the unit test.

Signed-off-by: Ratan Gupta <ratagupt@linux.vnet.ibm.com>
Change-Id: I312a9f423d4ab3ca4ebd5f17193f7b02162ded6b
diff --git a/phosphor-ldap-config/Makefile.am b/phosphor-ldap-config/Makefile.am
index 0092ae5..101d8a7 100644
--- a/phosphor-ldap-config/Makefile.am
+++ b/phosphor-ldap-config/Makefile.am
@@ -1,11 +1,12 @@
 bin_PROGRAMS = phosphor-ldap-conf
 
-noinst_HEADERS = ldap_configuration.hpp utils.hpp
+noinst_HEADERS = ldap_configuration.hpp ldap_config_mgr.hpp utils.hpp
 
 phosphor_ldap_conf_SOURCES = \
                 main.cpp \
                 utils.cpp \
                 ldap_configuration.cpp \
+                ldap_config_mgr.cpp \
                 ldap_serialize.cpp
 
 phosphor_ldap_conf_LDFLAGS = $(SDBUSPLUS_LIBS) \
diff --git a/phosphor-ldap-config/ldap_config_mgr.cpp b/phosphor-ldap-config/ldap_config_mgr.cpp
new file mode 100644
index 0000000..35baa9c
--- /dev/null
+++ b/phosphor-ldap-config/ldap_config_mgr.cpp
@@ -0,0 +1,297 @@
+#include "ldap_config_mgr.hpp"
+#include "ldap_configuration.hpp"
+#include "ldap_serialize.hpp"
+
+#include "utils.hpp"
+#include <filesystem>
+#include <fstream>
+#include <sstream>
+
+namespace phosphor
+{
+namespace ldap
+{
+
+constexpr auto nscdService = "nscd.service";
+constexpr auto LDAPscheme = "ldap";
+constexpr auto LDAPSscheme = "ldaps";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+namespace fs = std::filesystem;
+using Argument = xyz::openbmc_project::Common::InvalidArgument;
+
+using Line = std::string;
+using Key = std::string;
+using Val = std::string;
+using ConfigInfo = std::map<Key, Val>;
+
+void ConfigMgr::startOrStopService(const std::string& service, bool start)
+{
+    if (start)
+    {
+        restartService(service);
+    }
+    else
+    {
+        stopService(service);
+    }
+}
+
+void ConfigMgr::restartService(const std::string& service)
+{
+    try
+    {
+        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                          SYSTEMD_INTERFACE, "RestartUnit");
+        method.append(service.c_str(), "replace");
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to restart service",
+                        entry("SERVICE=%s", service.c_str()),
+                        entry("ERR=%s", ex.what()));
+        elog<InternalFailure>();
+    }
+}
+void ConfigMgr::stopService(const std::string& service)
+{
+    try
+    {
+        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                          SYSTEMD_INTERFACE, "StopUnit");
+        method.append(service.c_str(), "replace");
+        bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::SdBusError& ex)
+    {
+        log<level::ERR>("Failed to stop service",
+                        entry("SERVICE=%s", service.c_str()),
+                        entry("ERR=%s", ex.what()));
+        elog<InternalFailure>();
+    }
+}
+
+void ConfigMgr::deleteObject()
+{
+    configPtr.reset(nullptr);
+}
+
+std::string ConfigMgr::createConfig(
+    std::string lDAPServerURI, std::string lDAPBindDN, std::string lDAPBaseDN,
+    std::string lDAPBindDNPassword, CreateIface::SearchScope lDAPSearchScope,
+    CreateIface::Create::Type lDAPType, std::string groupNameAttribute,
+    std::string userNameAttribute)
+{
+    bool secureLDAP = false;
+
+    if (isValidLDAPURI(lDAPServerURI, LDAPSscheme))
+    {
+        secureLDAP = true;
+    }
+    else if (isValidLDAPURI(lDAPServerURI, LDAPscheme))
+    {
+        secureLDAP = false;
+    }
+    else
+    {
+        log<level::ERR>("bad LDAP Server URI",
+                        entry("LDAPSERVERURI=%s", lDAPServerURI.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
+                              Argument::ARGUMENT_VALUE(lDAPServerURI.c_str()));
+    }
+
+    if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
+    {
+        log<level::ERR>("LDAP server's CA certificate not provided",
+                        entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
+        elog<NoCACertificate>();
+    }
+
+    if (lDAPBindDN.empty())
+    {
+        log<level::ERR>("Not a valid LDAP BINDDN",
+                        entry("LDAPBINDDN=%s", lDAPBindDN.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
+                              Argument::ARGUMENT_VALUE(lDAPBindDN.c_str()));
+    }
+
+    if (lDAPBaseDN.empty())
+    {
+        log<level::ERR>("Not a valid LDAP BASEDN",
+                        entry("LDAPBASEDN=%s", lDAPBaseDN.c_str()));
+        elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
+                              Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str()));
+    }
+
+    // With current implementation we support only one LDAP server.
+    deleteObject();
+
+    auto objPath = std::string(LDAP_CONFIG_DBUS_OBJ_PATH);
+    configPtr = std::make_unique<Config>(
+        bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
+        secureLDAP, lDAPServerURI, lDAPBindDN, lDAPBaseDN,
+        std::move(lDAPBindDNPassword),
+        static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
+        static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
+        userNameAttribute, *this);
+
+    restartService(nscdService);
+    return objPath;
+}
+
+void ConfigMgr::restore(const char* filePath)
+{
+    if (!fs::exists(filePath))
+    {
+        log<level::ERR>("Config file doesn't exists",
+                        entry("LDAP_CONFIG_FILE=%s", configFilePath.c_str()));
+        return;
+    }
+
+    ConfigInfo configValues;
+    try
+    {
+        std::fstream stream(filePath, std::fstream::in);
+        Line line;
+        // read characters from stream and places them into line
+        while (std::getline(stream, line))
+        {
+            // remove leading and trailing extra spaces
+            auto firstScan = line.find_first_not_of(' ');
+            auto first =
+                (firstScan == std::string::npos ? line.length() : firstScan);
+            auto last = line.find_last_not_of(' ');
+            line = line.substr(first, last - first + 1);
+            // reduce multiple spaces between two words to a single space
+            auto pred = [](char a, char b) {
+                return (a == b && a == ' ') ? true : false;
+            };
+
+            auto lastPos = std::unique(line.begin(), line.end(), pred);
+
+            line.erase(lastPos, line.end());
+
+            // Ignore if line is empty or starts with '#'
+            if (line.empty() || line.at(0) == '#')
+            {
+                continue;
+            }
+
+            Key key;
+            std::istringstream isLine(line);
+            // extract characters from isLine and stores them into
+            // key until the delimitation character ' ' is found.
+            // If the delimiter is found, it is extracted and discarded
+            // the next input operation will begin after it.
+            if (std::getline(isLine, key, ' '))
+            {
+                Val value;
+                // extract characters after delimitation character ' '
+                if (std::getline(isLine, value, ' '))
+                {
+                    // skip line if it starts with "base shadow" or
+                    // "base passwd" because we would have 3 entries
+                    // ("base lDAPBaseDN" , "base passwd lDAPBaseDN" and
+                    // "base shadow lDAPBaseDN") for the property "lDAPBaseDN",
+                    // one is enough to restore it.
+
+                    if ((key == "base") &&
+                        (value == "passwd" || value == "shadow"))
+                    {
+                        continue;
+                    }
+
+                    // if config type is AD "map group" entry would be add to
+                    // the map configValues. For OpenLdap config file no map
+                    // entry would be there.
+                    if ((key == "map") && (value == "passwd"))
+                    {
+                        key = key + "_" + value;
+                        if (std::getline(isLine, value, ' '))
+                        {
+                            key += "_" + value;
+                        }
+                        std::getline(isLine, value, ' ');
+                    }
+                    configValues[key] = value;
+                }
+            }
+        }
+
+        CreateIface::SearchScope lDAPSearchScope;
+        if (configValues["scope"] == "sub")
+        {
+            lDAPSearchScope = CreateIface::SearchScope::sub;
+        }
+        else if (configValues["scope"] == "one")
+        {
+            lDAPSearchScope = CreateIface::SearchScope::one;
+        }
+        else
+        {
+            lDAPSearchScope = CreateIface::SearchScope::base;
+        }
+
+        CreateIface::Type lDAPType;
+        // If the file is having a line which starts with "map group"
+        if (configValues["map"] == "group")
+        {
+            lDAPType = CreateIface::Type::ActiveDirectory;
+        }
+        else
+        {
+            lDAPType = CreateIface::Type::OpenLdap;
+        }
+
+        // Don't create the config object if either of the field is empty.
+        if (configValues["uri"] == "" || configValues["binddn"] == "" ||
+            configValues["base"] == "")
+        {
+            log<level::INFO>(
+                "LDAP config parameter value missing",
+                entry("URI=%s", configValues["uri"].c_str()),
+                entry("BASEDN=%s", configValues["base"].c_str()),
+                entry("BINDDN=%s", configValues["binddn"].c_str()));
+            return;
+        }
+
+        createConfig(std::move(configValues["uri"]),
+                     std::move(configValues["binddn"]),
+                     std::move(configValues["base"]),
+                     std::move(configValues["bindpw"]), lDAPSearchScope,
+                     lDAPType, std::move(configValues["map_passwd_uid"]),
+                     std::move(configValues["map_passwd_gidNumber"]));
+
+        // Get the enabled property value from the persistent location
+        if (!deserialize(dbusPersistentPath, *configPtr))
+        {
+            log<level::INFO>(
+                "Deserialization Failed, continue with service disable");
+        }
+    }
+    catch (const InvalidArgument& e)
+    {
+        // Don't throw - we don't want to create a D-Bus
+        // object upon finding empty values in config, as
+        // this can be a default config.
+    }
+    catch (const NoCACertificate& e)
+    {
+        // Don't throw - we don't want to create a D-Bus
+        // object upon finding "ssl on" without having tls_cacertFile in place,
+        // as this can be a default config.
+    }
+    catch (const InternalFailure& e)
+    {
+        throw;
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        elog<InternalFailure>();
+    }
+}
+} // namespace ldap
+} // namespace phosphor
diff --git a/phosphor-ldap-config/ldap_config_mgr.hpp b/phosphor-ldap-config/ldap_config_mgr.hpp
new file mode 100644
index 0000000..24c12a9
--- /dev/null
+++ b/phosphor-ldap-config/ldap_config_mgr.hpp
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "ldap_configuration.hpp"
+
+#include "config.h"
+#include <xyz/openbmc_project/User/Ldap/Config/server.hpp>
+#include <xyz/openbmc_project/User/Ldap/Create/server.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <sdbusplus/bus.hpp>
+#include <string>
+namespace phosphor
+{
+namespace ldap
+{
+
+static constexpr auto defaultNslcdFile = "nslcd.conf.default";
+static constexpr auto nsSwitchFile = "nsswitch.conf";
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using CreateIface = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::User::Ldap::server::Create>;
+
+// class Config;
+/** @class ConfigMgr
+ *  @brief Creates LDAP server configuration.
+ *  @details concrete implementation of xyz.openbmc_project.User.Ldap.Create
+ *  APIs, in order to create LDAP configuration.
+ */
+class ConfigMgr : public CreateIface
+{
+  public:
+    ConfigMgr() = delete;
+    ~ConfigMgr() = default;
+    ConfigMgr(const ConfigMgr&) = delete;
+    ConfigMgr& operator=(const ConfigMgr&) = delete;
+    ConfigMgr(ConfigMgr&&) = delete;
+    ConfigMgr& operator=(ConfigMgr&&) = delete;
+
+    /** @brief ConfigMgr to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] filePath - LDAP configuration file.
+     *  @param[in] dbusPersistentPath - Persistent path for LDAP D-Bus property.
+     *  @param[in] caCertFile - LDAP's CA certificate file.
+     */
+    ConfigMgr(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
+              const char* dbusPersistentPath, const char* caCertFile) :
+        CreateIface(bus, path, true),
+        dbusPersistentPath(dbusPersistentPath), configFilePath(filePath),
+        bus(bus)
+    {
+        try
+        {
+            restore(configFilePath.c_str());
+            emit_object_added();
+        }
+        catch (const std::exception& e)
+        {
+            configPtr.reset(nullptr);
+            log<level::ERR>(e.what());
+            elog<InternalFailure>();
+        }
+    }
+
+    /** @brief concrete implementation of the pure virtual funtion
+            xyz.openbmc_project.User.Ldap.Create.createConfig.
+     *  @param[in] lDAPServerURI - LDAP URI of the server.
+     *  @param[in] lDAPBindDN - distinguished name with which bind to bind
+            to the directory server for lookups.
+     *  @param[in] lDAPBaseDN -  distinguished name to use as search base.
+     *  @param[in] lDAPBindDNPassword - credentials with which to bind.
+     *  @param[in] lDAPSearchScope - the search scope.
+     *  @param[in] lDAPType - Specifies the LDAP server type which can be AD
+            or openLDAP.
+     *  @param[in] groupNameAttribute - Specifies attribute name that contains
+     *             the name of the Group in the LDAP server.
+     *  @param[in] usernameAttribute - Specifies attribute name that contains
+     *             the username in the LDAP server.
+     *  @returns the object path of the D-Bus object created.
+     */
+    std::string createConfig(std::string lDAPServerURI, std::string lDAPBindDN,
+                             std::string lDAPBaseDN,
+                             std::string lDAPBindDNPassword,
+                             CreateIface::SearchScope lDAPSearchScope,
+                             CreateIface::Type lDAPType,
+                             std::string groupNameAttribute,
+                             std::string userNameAttribute) override;
+
+    /** @brief restarts given service
+     *  @param[in] service - Service to be restarted.
+     */
+    virtual void restartService(const std::string& service);
+
+    /** @brief stops given service
+     *  @param[in] service - Service to be stopped.
+     */
+    virtual void stopService(const std::string& service);
+
+    /** @brief start or stop the service depending on the given value
+     *  @param[in] service - Service to be start/stop.
+     *  @param[in] value - true to start the service otherwise stop.
+     */
+    virtual void startOrStopService(const std::string& service, bool value);
+
+    /** @brief delete the config D-Bus object.
+     */
+    void deleteObject();
+
+    /* ldap service enabled property would be saved under
+     * this path.
+     */
+    std::string dbusPersistentPath;
+
+  protected:
+    std::string configFilePath{};
+    std::string tlsCacertFile{};
+
+    /** @brief Persistent sdbusplus D-Bus bus connection. */
+    sdbusplus::bus::bus& bus;
+
+    /** @brief Pointer to a Config D-Bus object */
+    std::unique_ptr<Config> configPtr = nullptr;
+
+    /** @brief Populate existing config into D-Bus properties
+     *  @param[in] filePath - LDAP config file path
+     */
+    virtual void restore(const char* filePath);
+};
+} // namespace ldap
+} // namespace phosphor
diff --git a/phosphor-ldap-config/ldap_configuration.cpp b/phosphor-ldap-config/ldap_configuration.cpp
index 77726ee..4edbed7 100644
--- a/phosphor-ldap-config/ldap_configuration.cpp
+++ b/phosphor-ldap-config/ldap_configuration.cpp
@@ -1,3 +1,4 @@
+#include "ldap_config_mgr.hpp"
 #include "ldap_configuration.hpp"
 #include "ldap_serialize.hpp"
 #include "utils.hpp"
@@ -9,6 +10,7 @@
 {
 namespace ldap
 {
+
 constexpr auto nslcdService = "nslcd.service";
 constexpr auto nscdService = "nscd.service";
 constexpr auto LDAPscheme = "ldap";
@@ -480,274 +482,5 @@
     return val;
 }
 
-void ConfigMgr::startOrStopService(const std::string& service, bool start)
-{
-    if (start)
-    {
-        restartService(service);
-    }
-    else
-    {
-        stopService(service);
-    }
-}
-
-void ConfigMgr::restartService(const std::string& service)
-{
-    try
-    {
-        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
-                                          SYSTEMD_INTERFACE, "RestartUnit");
-        method.append(service.c_str(), "replace");
-        bus.call_noreply(method);
-    }
-    catch (const sdbusplus::exception::SdBusError& ex)
-    {
-        log<level::ERR>("Failed to restart service",
-                        entry("SERVICE=%s", service.c_str()),
-                        entry("ERR=%s", ex.what()));
-        elog<InternalFailure>();
-    }
-}
-
-void ConfigMgr::stopService(const std::string& service)
-{
-    try
-    {
-        auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
-                                          SYSTEMD_INTERFACE, "StopUnit");
-        method.append(service.c_str(), "replace");
-        bus.call_noreply(method);
-    }
-    catch (const sdbusplus::exception::SdBusError& ex)
-    {
-        log<level::ERR>("Failed to stop service",
-                        entry("SERVICE=%s", service.c_str()),
-                        entry("ERR=%s", ex.what()));
-        elog<InternalFailure>();
-    }
-}
-
-void ConfigMgr::deleteObject()
-{
-    configPtr.reset(nullptr);
-}
-
-std::string ConfigMgr::createConfig(
-    std::string lDAPServerURI, std::string lDAPBindDN, std::string lDAPBaseDN,
-    std::string lDAPBindDNPassword, CreateIface::SearchScope lDAPSearchScope,
-    CreateIface::Create::Type lDAPType, std::string groupNameAttribute,
-    std::string userNameAttribute)
-{
-    bool secureLDAP = false;
-
-    if (isValidLDAPURI(lDAPServerURI, LDAPSscheme))
-    {
-        secureLDAP = true;
-    }
-    else if (isValidLDAPURI(lDAPServerURI, LDAPscheme))
-    {
-        secureLDAP = false;
-    }
-    else
-    {
-        log<level::ERR>("bad LDAP Server URI",
-                        entry("LDAPSERVERURI=%s", lDAPServerURI.c_str()));
-        elog<InvalidArgument>(Argument::ARGUMENT_NAME("lDAPServerURI"),
-                              Argument::ARGUMENT_VALUE(lDAPServerURI.c_str()));
-    }
-
-    if (secureLDAP && !fs::exists(tlsCacertFile.c_str()))
-    {
-        log<level::ERR>("LDAP server's CA certificate not provided",
-                        entry("TLSCACERTFILE=%s", tlsCacertFile.c_str()));
-        elog<NoCACertificate>();
-    }
-
-    if (lDAPBindDN.empty())
-    {
-        log<level::ERR>("Not a valid LDAP BINDDN",
-                        entry("LDAPBINDDN=%s", lDAPBindDN.c_str()));
-        elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBindDN"),
-                              Argument::ARGUMENT_VALUE(lDAPBindDN.c_str()));
-    }
-
-    if (lDAPBaseDN.empty())
-    {
-        log<level::ERR>("Not a valid LDAP BASEDN",
-                        entry("LDAPBASEDN=%s", lDAPBaseDN.c_str()));
-        elog<InvalidArgument>(Argument::ARGUMENT_NAME("LDAPBaseDN"),
-                              Argument::ARGUMENT_VALUE(lDAPBaseDN.c_str()));
-    }
-
-    // With current implementation we support only one LDAP server.
-    deleteObject();
-
-    auto objPath = std::string(LDAP_CONFIG_DBUS_OBJ_PATH);
-    configPtr = std::make_unique<Config>(
-        bus, objPath.c_str(), configFilePath.c_str(), tlsCacertFile.c_str(),
-        secureLDAP, lDAPServerURI, lDAPBindDN, lDAPBaseDN,
-        std::move(lDAPBindDNPassword),
-        static_cast<ConfigIface::SearchScope>(lDAPSearchScope),
-        static_cast<ConfigIface::Type>(lDAPType), false, groupNameAttribute,
-        userNameAttribute, *this);
-
-    restartService(nscdService);
-    return objPath;
-}
-
-void ConfigMgr::restore(const char* filePath)
-{
-    if (!fs::exists(filePath))
-    {
-        log<level::ERR>("Config file doesn't exists",
-                        entry("LDAP_CONFIG_FILE=%s", configFilePath.c_str()));
-        return;
-    }
-
-    ConfigInfo configValues;
-
-    try
-    {
-        std::fstream stream(filePath, std::fstream::in);
-        Line line;
-        // read characters from stream and places them into line
-        while (std::getline(stream, line))
-        {
-            // remove leading and trailing extra spaces
-            auto firstScan = line.find_first_not_of(' ');
-            auto first =
-                (firstScan == std::string::npos ? line.length() : firstScan);
-            auto last = line.find_last_not_of(' ');
-            line = line.substr(first, last - first + 1);
-            // reduce multiple spaces between two words to a single space
-            auto pred = [](char a, char b) {
-                return (a == b && a == ' ') ? true : false;
-            };
-
-            auto lastPos = std::unique(line.begin(), line.end(), pred);
-
-            line.erase(lastPos, line.end());
-
-            // Ignore if line is empty or starts with '#'
-            if (line.empty() || line.at(0) == '#')
-            {
-                continue;
-            }
-
-            Key key;
-            std::istringstream isLine(line);
-            // extract characters from isLine and stores them into
-            // key until the delimitation character ' ' is found.
-            // If the delimiter is found, it is extracted and discarded
-            // the next input operation will begin after it.
-            if (std::getline(isLine, key, ' '))
-            {
-                Val value;
-                // extract characters after delimitation character ' '
-                if (std::getline(isLine, value, ' '))
-                {
-                    // skip line if it starts with "base shadow" or
-                    // "base passwd" because we would have 3 entries
-                    // ("base lDAPBaseDN" , "base passwd lDAPBaseDN" and
-                    // "base shadow lDAPBaseDN") for the property "lDAPBaseDN",
-                    // one is enough to restore it.
-
-                    if ((key == "base") &&
-                        (value == "passwd" || value == "shadow"))
-                    {
-                        continue;
-                    }
-
-                    // if config type is AD "map group" entry would be add to
-                    // the map configValues. For OpenLdap config file no map
-                    // entry would be there.
-                    if ((key == "map") && (value == "passwd"))
-                    {
-                        key = key + "_" + value;
-                        if (std::getline(isLine, value, ' '))
-                        {
-                            key += "_" + value;
-                        }
-                        std::getline(isLine, value, ' ');
-                    }
-                    configValues[key] = value;
-                }
-            }
-        }
-
-        CreateIface::SearchScope lDAPSearchScope;
-        if (configValues["scope"] == "sub")
-        {
-            lDAPSearchScope = CreateIface::SearchScope::sub;
-        }
-        else if (configValues["scope"] == "one")
-        {
-            lDAPSearchScope = CreateIface::SearchScope::one;
-        }
-        else
-        {
-            lDAPSearchScope = CreateIface::SearchScope::base;
-        }
-
-        CreateIface::Type lDAPType;
-        // If the file is having a line which starts with "map group"
-        if (configValues["map"] == "group")
-        {
-            lDAPType = CreateIface::Type::ActiveDirectory;
-        }
-        else
-        {
-            lDAPType = CreateIface::Type::OpenLdap;
-        }
-
-        // Don't create the config object if either of the field is empty.
-        if (configValues["uri"] == "" || configValues["binddn"] == "" ||
-            configValues["base"] == "")
-        {
-            log<level::INFO>(
-                "LDAP config parameter value missing",
-                entry("URI=%s", configValues["uri"].c_str()),
-                entry("BASEDN=%s", configValues["base"].c_str()),
-                entry("BINDDN=%s", configValues["binddn"].c_str()));
-            return;
-        }
-
-        createConfig(std::move(configValues["uri"]),
-                     std::move(configValues["binddn"]),
-                     std::move(configValues["base"]),
-                     std::move(configValues["bindpw"]), lDAPSearchScope,
-                     lDAPType, std::move(configValues["map_passwd_uid"]),
-                     std::move(configValues["map_passwd_gidNumber"]));
-
-        // Get the enabled property value from the persistent location
-        if (!deserialize(dbusPersistentPath, *configPtr))
-        {
-            log<level::INFO>(
-                "Deserialization Failed, continue with service disable");
-        }
-    }
-    catch (const InvalidArgument& e)
-    {
-        // Don't throw - we don't want to create a D-Bus
-        // object upon finding empty values in config, as
-        // this can be a default config.
-    }
-    catch (const NoCACertificate& e)
-    {
-        // Don't throw - we don't want to create a D-Bus
-        // object upon finding "ssl on" without having tls_cacertFile in place,
-        // as this can be a default config.
-    }
-    catch (const InternalFailure& e)
-    {
-        throw;
-    }
-    catch (const std::exception& e)
-    {
-        log<level::ERR>(e.what());
-        elog<InternalFailure>();
-    }
-}
 } // namespace ldap
 } // namespace phosphor
diff --git a/phosphor-ldap-config/ldap_configuration.hpp b/phosphor-ldap-config/ldap_configuration.hpp
index d4fe5b7..8af4e4d 100644
--- a/phosphor-ldap-config/ldap_configuration.hpp
+++ b/phosphor-ldap-config/ldap_configuration.hpp
@@ -3,8 +3,8 @@
 #include "config.h"
 #include <xyz/openbmc_project/Object/Delete/server.hpp>
 #include <xyz/openbmc_project/Object/Enable/server.hpp>
-#include <xyz/openbmc_project/User/Ldap/Config/server.hpp>
 #include <xyz/openbmc_project/User/Ldap/Create/server.hpp>
+#include <xyz/openbmc_project/User/Ldap/Config/server.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 #include <phosphor-logging/log.hpp>
 #include <phosphor-logging/elog.hpp>
@@ -17,8 +17,6 @@
 {
 namespace ldap
 {
-static constexpr auto defaultNslcdFile = "nslcd.conf.default";
-static constexpr auto nsSwitchFile = "nsswitch.conf";
 
 using namespace phosphor::logging;
 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
@@ -169,110 +167,5 @@
     friend class MockConfigMgr;
 };
 
-/** @class ConfigMgr
- *  @brief Creates LDAP server configuration.
- *  @details concrete implementation of xyz.openbmc_project.User.Ldap.Create
- *  APIs, in order to create LDAP configuration.
- */
-class ConfigMgr : public CreateIface
-{
-  public:
-    ConfigMgr() = delete;
-    ~ConfigMgr() = default;
-    ConfigMgr(const ConfigMgr&) = delete;
-    ConfigMgr& operator=(const ConfigMgr&) = delete;
-    ConfigMgr(ConfigMgr&&) = delete;
-    ConfigMgr& operator=(ConfigMgr&&) = delete;
-
-    /** @brief ConfigMgr to put object onto bus at a dbus path.
-     *  @param[in] bus - Bus to attach to.
-     *  @param[in] path - Path to attach at.
-     *  @param[in] filePath - LDAP configuration file.
-     *  @param[in] dbusPersistentPath - Persistent path for LDAP D-Bus property.
-     *  @param[in] caCertFile - LDAP's CA certificate file.
-     */
-    ConfigMgr(sdbusplus::bus::bus& bus, const char* path, const char* filePath,
-              const char* dbusPersistentPath, const char* caCertFile) :
-        CreateIface(bus, path, true),
-        dbusPersistentPath(dbusPersistentPath), configFilePath(filePath),
-        bus(bus)
-    {
-        try
-        {
-            restore(configFilePath.c_str());
-            emit_object_added();
-        }
-        catch (const std::exception& e)
-        {
-            configPtr.reset(nullptr);
-            log<level::ERR>(e.what());
-            elog<InternalFailure>();
-        }
-    }
-
-    /** @brief concrete implementation of the pure virtual funtion
-            xyz.openbmc_project.User.Ldap.Create.createConfig.
-     *  @param[in] lDAPServerURI - LDAP URI of the server.
-     *  @param[in] lDAPBindDN - distinguished name with which bind to bind
-            to the directory server for lookups.
-     *  @param[in] lDAPBaseDN -  distinguished name to use as search base.
-     *  @param[in] lDAPBindDNPassword - credentials with which to bind.
-     *  @param[in] lDAPSearchScope - the search scope.
-     *  @param[in] lDAPType - Specifies the LDAP server type which can be AD
-            or openLDAP.
-     *  @param[in] groupNameAttribute - Specifies attribute name that contains
-     *             the name of the Group in the LDAP server.
-     *  @param[in] usernameAttribute - Specifies attribute name that contains
-     *             the username in the LDAP server.
-     *  @returns the object path of the D-Bus object created.
-     */
-    std::string createConfig(std::string lDAPServerURI, std::string lDAPBindDN,
-                             std::string lDAPBaseDN,
-                             std::string lDAPBindDNPassword,
-                             CreateIface::SearchScope lDAPSearchScope,
-                             CreateIface::Type lDAPType,
-                             std::string groupNameAttribute,
-                             std::string userNameAttribute) override;
-
-    /** @brief restarts given service
-     *  @param[in] service - Service to be restarted.
-     */
-    virtual void restartService(const std::string& service);
-
-    /** @brief stops given service
-     *  @param[in] service - Service to be stopped.
-     */
-    virtual void stopService(const std::string& service);
-
-    /** @brief start or stop the service depending on the given value
-     *  @param[in] service - Service to be start/stop.
-     *  @param[in] value - true to start the service otherwise stop.
-     */
-    virtual void startOrStopService(const std::string& service, bool value);
-
-    /** @brief delete the config D-Bus object.
-     */
-    void deleteObject();
-
-    /* ldap service enabled property would be saved under
-     * this path.
-     */
-    std::string dbusPersistentPath;
-
-  protected:
-    std::string configFilePath{};
-    std::string tlsCacertFile{};
-
-    /** @brief Persistent sdbusplus D-Bus bus connection. */
-    sdbusplus::bus::bus& bus;
-
-    /** @brief Pointer to a Config D-Bus object */
-    std::unique_ptr<Config> configPtr = nullptr;
-
-    /** @brief Populate existing config into D-Bus properties
-     *  @param[in] filePath - LDAP config file path
-     */
-    virtual void restore(const char* filePath);
-};
 } // namespace ldap
 } // namespace phosphor
diff --git a/phosphor-ldap-config/main.cpp b/phosphor-ldap-config/main.cpp
index 2e3bf66..c6eaa5a 100644
--- a/phosphor-ldap-config/main.cpp
+++ b/phosphor-ldap-config/main.cpp
@@ -1,5 +1,5 @@
 #include "config.h"
-#include "ldap_configuration.hpp"
+#include "ldap_config_mgr.hpp"
 #include <experimental/filesystem>
 #include <phosphor-logging/log.hpp>
 #include <phosphor-logging/elog-errors.hpp>
diff --git a/test/Makefile.am b/test/Makefile.am
index 00f969c..17f5774 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -30,7 +30,8 @@
 ldap_config_test_SOURCES  = ldap_config_test.cpp utils_test.cpp
 ldap_config_test_LDADD  = $(top_builddir)/phosphor-ldap-config/ldap_configuration.o \
                           $(top_builddir)/phosphor-ldap-config/utils.o \
-                          $(top_builddir)/phosphor-ldap-config/ldap_serialize.o
+                          $(top_builddir)/phosphor-ldap-config/ldap_serialize.o \
+                          $(top_builddir)/phosphor-ldap-config/ldap_config_mgr.o
 
 check_PROGRAMS += ldap_mapper_test
 ldap_mapper_test_CPPFLAGS = $(cppflags)
diff --git a/test/ldap_config_test.cpp b/test/ldap_config_test.cpp
index f9cf386..4cbb363 100644
--- a/test/ldap_config_test.cpp
+++ b/test/ldap_config_test.cpp
@@ -1,5 +1,6 @@
 #include "config.h"
 #include "phosphor-ldap-config/ldap_configuration.hpp"
+#include "phosphor-ldap-config/ldap_config_mgr.hpp"
 #include "phosphor-ldap-config/ldap_serialize.hpp"
 
 #include <phosphor-logging/log.hpp>