diff --git a/include/ibm/locks.hpp b/include/ibm/locks.hpp
deleted file mode 100644
index 3bb82b9..0000000
--- a/include/ibm/locks.hpp
+++ /dev/null
@@ -1,610 +0,0 @@
-#pragma once
-
-#include "ibm/utils.hpp"
-#include "logging.hpp"
-
-#include <boost/container/flat_map.hpp>
-#include <boost/endian/conversion.hpp>
-#include <nlohmann/json.hpp>
-
-#include <filesystem>
-#include <fstream>
-#include <variant>
-
-namespace crow
-{
-namespace ibm_mc_lock
-{
-
-using SType = std::string;
-
-/*----------------------------------------
-|Segment flags : LockFlag | SegmentLength|
-------------------------------------------*/
-
-using SegmentFlags = std::vector<std::pair<SType, uint32_t>>;
-
-// Lockrequest = session-id | hmc-id | locktype | resourceid | segmentinfo
-using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
-using LockRequests = std::vector<LockRequest>;
-using Rc =
-    std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
-using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
-using RcGetLockList =
-    std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
-using ListOfTransactionIds = std::vector<uint32_t>;
-using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
-using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
-using SessionFlags = std::pair<SType, SType>;
-using ListOfSessionIds = std::vector<std::string>;
-
-class Lock
-{
-    uint32_t transactionId = 0;
-    boost::container::flat_map<uint32_t, LockRequests> lockTable;
-
-  protected:
-    /*
-     * This function implements the logic for validating an incoming
-     * lock request/requests.
-     *
-     * Returns : True (if Valid)
-     * Returns : False (if not a Valid lock request)
-     */
-
-    virtual bool isValidLockRequest(const LockRequest& refLockRecord);
-
-    /*
-     * This function implements the logic of checking if the incoming
-     * multi-lock request is not having conflicting requirements.
-     *
-     * Returns : True (if conflicting)
-     * Returns : False (if not conflicting)
-     */
-
-    virtual bool isConflictRequest(const LockRequests& refLockRequestStructure);
-    /*
-     * Implements the core algorithm to find the conflicting
-     * lock requests.
-     *
-     * This functions takes two lock requests and check if both
-     * are conflicting to each other.
-     *
-     * Returns : True (if conflicting)
-     * Returns : False (if not conflicting)
-     */
-    virtual bool isConflictRecord(const LockRequest& refLockRecord1,
-                                  const LockRequest& refLockRecord2);
-
-    /*
-     * This function implements the logic of checking the conflicting
-     * locks from a incoming single/multi lock requests with the already
-     * existing lock request in the lock table.
-     *
-     */
-
-    virtual Rc isConflictWithTable(const LockRequests& refLockRequestStructure);
-    /*
-     * This function implements the logic of checking the ownership of the
-     * lock from the releaselock request.
-     *
-     * Returns : True (if the requesting HMC & Session owns the lock(s))
-     * Returns : False (if the request HMC or Session does not own the lock(s))
-     */
-
-    virtual RcRelaseLock isItMyLock(const ListOfTransactionIds& refRids,
-                                    const SessionFlags& ids);
-
-    /*
-     * This function validates the the list of transactionID's and returns false
-     * if the transaction ID is not valid & not present in the lock table
-     */
-
-    virtual bool validateRids(const ListOfTransactionIds& refRids);
-
-    /*
-     * This function releases the locks that are already obtained by the
-     * requesting Management console.
-     */
-
-    void releaseLock(const ListOfTransactionIds& refRids);
-
-    Lock()
-    {
-        transactionId = lockTable.empty() ? 0 : prev(lockTable.end())->first;
-    }
-
-    /*
-     * This function implements the algorithm for checking the respective
-     * bytes of the resource id based on the lock management algorithm.
-     */
-
-    static bool checkByte(uint64_t resourceId1, uint64_t resourceId2,
-                          uint32_t position);
-
-    /*
-     * This functions implements a counter that generates a unique 32 bit
-     * number for every successful transaction. This number will be used by
-     * the Management Console for debug.
-     */
-    virtual uint32_t generateTransactionId();
-
-  public:
-    /*
-     * Explicitly deleted copy and move constructors
-     */
-    Lock(const Lock&) = delete;
-    Lock(Lock&&) = delete;
-    Lock& operator=(const Lock&) = delete;
-    Lock& operator=(Lock&&) = delete;
-
-    /*
-     * This function implements the logic for acquiring a lock on a
-     * resource if the incoming request is legitimate without any
-     * conflicting requirements & without any conflicting requirement
-     * with the existing locks in the lock table.
-     *
-     */
-
-    RcAcquireLock acquireLock(const LockRequests& lockRequestStructure);
-
-    /*
-     * This function implements the logic for releasing the lock that are
-     * owned by a management console session.
-     *
-     * The locks can be released by two ways
-     *  - Using list of transaction ID's
-     *  - Using a Session ID
-     *
-     * Client can choose either of the ways by using `Type` JSON key.
-     *
-     */
-    RcReleaseLockApi releaseLock(const ListOfTransactionIds& p,
-                                 const SessionFlags& ids);
-
-    /*
-     * This function implements the logic for getting the list of locks obtained
-     * by a particular management console.
-     */
-    RcGetLockList getLockList(const ListOfSessionIds& listSessionId);
-
-    /*
-     * This function is releases all the locks obtained by a particular
-     * session.
-     */
-
-    void releaseLock(const std::string& sessionId);
-
-    static Lock& getInstance()
-    {
-        static Lock lockObject;
-        return lockObject;
-    }
-
-    virtual ~Lock() = default;
-};
-
-inline RcGetLockList Lock::getLockList(const ListOfSessionIds& listSessionId)
-{
-    std::vector<std::pair<uint32_t, LockRequests>> lockList{};
-
-    if (!lockTable.empty())
-    {
-        for (const auto& i : listSessionId)
-        {
-            auto it = lockTable.begin();
-            while (it != lockTable.end())
-            {
-                // Check if session id of this entry matches with session id
-                // given
-                if (std::get<0>(it->second[0]) == i)
-                {
-                    BMCWEB_LOG_DEBUG("Session id is found in the locktable");
-
-                    // Push the whole lock record into a vector for returning
-                    // the json
-                    lockList.emplace_back(it->first, it->second);
-                }
-                // Go to next entry in map
-                it++;
-            }
-        }
-    }
-    // we may have found at least one entry with the given session id
-    // return the json list of lock records pertaining to the given
-    // session id, or send an empty list if lock table is empty
-    return {lockList};
-}
-
-inline RcReleaseLockApi Lock::releaseLock(const ListOfTransactionIds& p,
-                                          const SessionFlags& ids)
-{
-    bool status = validateRids(p);
-
-    if (!status)
-    {
-        // Validation of rids failed
-        BMCWEB_LOG_ERROR("releaseLock: Contains invalid request id");
-        return std::make_pair(false, status);
-    }
-    // Validation passed, check if all the locks are owned by the
-    // requesting HMC
-    auto status2 = isItMyLock(p, ids);
-    if (!status2.first)
-    {
-        return std::make_pair(false, status2);
-    }
-    return std::make_pair(true, status2);
-}
-
-inline RcAcquireLock Lock::acquireLock(const LockRequests& lockRequestStructure)
-{
-    // validate the lock request
-
-    for (const auto& lockRecord : lockRequestStructure)
-    {
-        bool status = isValidLockRequest(lockRecord);
-        if (!status)
-        {
-            BMCWEB_LOG_DEBUG("Not a Valid record");
-            BMCWEB_LOG_DEBUG("Bad json in request");
-            return std::make_pair(true, std::make_pair(status, 0));
-        }
-    }
-    // check for conflict record
-
-    const LockRequests& multiRequest = lockRequestStructure;
-    bool status = isConflictRequest(multiRequest);
-
-    if (status)
-    {
-        BMCWEB_LOG_DEBUG("There is a conflict within itself");
-        return std::make_pair(true, std::make_pair(status, 1));
-    }
-    BMCWEB_LOG_DEBUG("The request is not conflicting within itself");
-
-    // Need to check for conflict with the locktable entries.
-
-    auto conflict = isConflictWithTable(multiRequest);
-
-    BMCWEB_LOG_DEBUG("Done with checking conflict with the locktable");
-    return std::make_pair(false, conflict);
-}
-
-inline void Lock::releaseLock(const std::string& sessionId)
-{
-    if (!lockTable.empty())
-    {
-        auto it = lockTable.begin();
-        while (it != lockTable.end())
-        {
-            if (!it->second.empty())
-            {
-                // Check if session id of this entry matches with session id
-                // given
-                if (std::get<0>(it->second[0]) == sessionId)
-                {
-                    BMCWEB_LOG_DEBUG("Remove the lock from the locktable "
-                                     "having sessionID={}",
-                                     sessionId);
-                    BMCWEB_LOG_DEBUG("TransactionID ={}", it->first);
-                    it = lockTable.erase(it);
-                }
-                else
-                {
-                    it++;
-                }
-            }
-        }
-    }
-}
-inline RcRelaseLock Lock::isItMyLock(const ListOfTransactionIds& refRids,
-                                     const SessionFlags& ids)
-{
-    for (const auto& id : refRids)
-    {
-        // Just need to compare the client id of the first lock records in the
-        // complete lock row(in the map), because the rest of the lock records
-        // would have the same client id
-
-        std::string expectedClientId = std::get<1>(lockTable[id][0]);
-        std::string expectedSessionId = std::get<0>(lockTable[id][0]);
-
-        if ((expectedClientId == ids.first) &&
-            (expectedSessionId == ids.second))
-        {
-            // It is owned by the currently request hmc
-            BMCWEB_LOG_DEBUG("Lock is owned  by the current hmc");
-            // remove the lock
-            if (lockTable.erase(id) != 0U)
-            {
-                BMCWEB_LOG_DEBUG("Removing the locks with transaction ID : {}",
-                                 id);
-            }
-            else
-            {
-                BMCWEB_LOG_ERROR("Removing the locks from the lock table "
-                                 "failed, transaction ID: {}",
-                                 id);
-            }
-        }
-        else
-        {
-            BMCWEB_LOG_DEBUG("Lock is not owned by the current hmc");
-            return std::make_pair(false, std::make_pair(id, lockTable[id][0]));
-        }
-    }
-    return std::make_pair(true, std::make_pair(0, LockRequest()));
-}
-
-inline bool Lock::validateRids(const ListOfTransactionIds& refRids)
-{
-    for (const auto& id : refRids)
-    {
-        auto search = lockTable.find(id);
-
-        if (search != lockTable.end())
-        {
-            BMCWEB_LOG_DEBUG("Valid Transaction id");
-            //  continue for the next rid
-        }
-        else
-        {
-            BMCWEB_LOG_ERROR("validateRids: At least 1 inValid Request id: {}",
-                             id);
-            return false;
-        }
-    }
-    return true;
-}
-
-inline bool Lock::isValidLockRequest(const LockRequest& refLockRecord)
-{
-    // validate the locktype
-
-    if (!((std::get<2>(refLockRecord) == "Read" ||
-           (std::get<2>(refLockRecord) == "Write"))))
-    {
-        BMCWEB_LOG_DEBUG("Validation of LockType Failed");
-        BMCWEB_LOG_DEBUG("Locktype : {}", std::get<2>(refLockRecord));
-        return false;
-    }
-
-    BMCWEB_LOG_DEBUG("{}", static_cast<int>(std::get<4>(refLockRecord).size()));
-
-    // validate the number of segments
-    // Allowed No of segments are between 2 and 6
-    if ((static_cast<int>(std::get<4>(refLockRecord).size()) > 6) ||
-        (static_cast<int>(std::get<4>(refLockRecord).size()) < 2))
-    {
-        BMCWEB_LOG_DEBUG("Validation of Number of Segments Failed");
-        BMCWEB_LOG_DEBUG("Number of Segments provided : {}",
-                         std::get<4>(refLockRecord).size());
-        return false;
-    }
-
-    int lockFlag = 0;
-    // validate the lockflags & segment length
-
-    for (const auto& p : std::get<4>(refLockRecord))
-    {
-        // validate the lock flags
-        // Allowed lockflags are locksame,lockall & dontlock
-
-        if (!((p.first == "LockSame" || (p.first == "LockAll") ||
-               (p.first == "DontLock"))))
-        {
-            BMCWEB_LOG_DEBUG("Validation of lock flags failed");
-            BMCWEB_LOG_DEBUG("{}", p.first);
-            return false;
-        }
-
-        // validate the segment length
-        // Allowed values of segment length are between 1 and 4
-
-        if (p.second < 1 || p.second > 4)
-        {
-            BMCWEB_LOG_DEBUG("Validation of Segment Length Failed");
-            BMCWEB_LOG_DEBUG("{}", p.second);
-            return false;
-        }
-
-        if ((p.first == "LockSame" || (p.first == "LockAll")))
-        {
-            ++lockFlag;
-            if (lockFlag >= 2)
-            {
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
-inline Rc Lock::isConflictWithTable(const LockRequests& refLockRequestStructure)
-{
-    if (lockTable.empty())
-    {
-        uint32_t thisTransactionId = generateTransactionId();
-        BMCWEB_LOG_DEBUG("{}", thisTransactionId);
-        // Lock table is empty, so we are safe to add the lockrecords
-        // as there will be no conflict
-        BMCWEB_LOG_DEBUG("Lock table is empty, so adding the lockrecords");
-        lockTable.emplace(thisTransactionId, refLockRequestStructure);
-
-        return std::make_pair(false, thisTransactionId);
-    }
-    BMCWEB_LOG_DEBUG(
-        "Lock table is not empty, check for conflict with lock table");
-    // Lock table is not empty, compare the lockrequest entries with
-    // the entries in the lock table
-
-    for (const auto& lockRecord1 : refLockRequestStructure)
-    {
-        for (const auto& map : lockTable)
-        {
-            for (const auto& lockRecord2 : map.second)
-            {
-                bool status = isConflictRecord(lockRecord1, lockRecord2);
-                if (status)
-                {
-                    return std::make_pair(
-                        true, std::make_pair(map.first, lockRecord2));
-                }
-            }
-        }
-    }
-
-    // Reached here, so no conflict with the locktable, so we are safe to
-    // add the request records into the lock table
-
-    // Lock table is empty, so we are safe to add the lockrecords
-    // as there will be no conflict
-    BMCWEB_LOG_DEBUG(" Adding elements into lock table");
-    transactionId = generateTransactionId();
-    lockTable.emplace(std::make_pair(transactionId, refLockRequestStructure));
-
-    return std::make_pair(false, transactionId);
-}
-
-inline bool Lock::isConflictRequest(const LockRequests& refLockRequestStructure)
-{
-    // check for all the locks coming in as a part of single request
-    // return conflict if any two lock requests are conflicting
-
-    if (refLockRequestStructure.size() == 1)
-    {
-        BMCWEB_LOG_DEBUG("Only single lock request, so there is no conflict");
-        // This means , we have only one lock request in the current
-        // request , so no conflict within the request
-        return false;
-    }
-
-    BMCWEB_LOG_DEBUG(
-        "There are multiple lock requests coming in a single request");
-
-    // There are multiple requests a part of one request
-
-    for (uint32_t i = 0; i < refLockRequestStructure.size(); i++)
-    {
-        for (uint32_t j = i + 1; j < refLockRequestStructure.size(); j++)
-        {
-            const LockRequest& p = refLockRequestStructure[i];
-            const LockRequest& q = refLockRequestStructure[j];
-            bool status = isConflictRecord(p, q);
-
-            if (status)
-            {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-// This function converts the provided uint64_t resource id's from the two
-// lock requests subjected for comparison, and this function also compares
-// the content by bytes mentioned by a uint32_t number.
-
-// If all the elements in the lock requests which are subjected for comparison
-// are same, then the last comparison would be to check for the respective
-// bytes in the resourceid based on the segment length.
-inline bool Lock::checkByte(uint64_t resourceId1, uint64_t resourceId2,
-                            uint32_t position)
-{
-    if (position >= sizeof(resourceId1))
-    {
-        return false;
-    }
-
-    uint8_t pPosition = 0;
-    uint8_t qPosition = 0;
-    pPosition = 0xFF & (resourceId1 >> (8 * position));
-    qPosition = 0xFF & (resourceId2 >> (8 * position));
-
-    return pPosition == qPosition;
-}
-
-inline bool Lock::isConflictRecord(const LockRequest& refLockRecord1,
-                                   const LockRequest& refLockRecord2)
-{
-    // No conflict if both are read locks
-
-    if (std::get<2>(refLockRecord1) == "Read" &&
-        std::get<2>(refLockRecord2) == "Read")
-    {
-        BMCWEB_LOG_DEBUG("Both are read locks, no conflict");
-        return false;
-    }
-
-    uint32_t i = 0;
-    for (const auto& p : std::get<4>(refLockRecord1))
-    {
-        // return conflict when any of them is try to lock all resources
-        // under the current resource level.
-        if (p.first == "LockAll" ||
-            std::get<4>(refLockRecord2)[i].first == "LockAll")
-        {
-            BMCWEB_LOG_DEBUG(
-                "Either of the Comparing locks are trying to lock all "
-                "resources under the current resource level");
-            return true;
-        }
-
-        // determine if there is a lock-all-with-same-segment-size.
-        // If the current segment sizes are the same,then we should fail.
-
-        if ((p.first == "LockSame" ||
-             std::get<4>(refLockRecord2)[i].first == "LockSame") &&
-            (p.second == std::get<4>(refLockRecord2)[i].second))
-        {
-            return true;
-        }
-
-        // if segment lengths are not the same, it means two different locks
-        // So no conflict
-        if (p.second != std::get<4>(refLockRecord2)[i].second)
-        {
-            BMCWEB_LOG_DEBUG("Segment lengths are not same");
-            BMCWEB_LOG_DEBUG("Segment 1 length : {}", p.second);
-            BMCWEB_LOG_DEBUG("Segment 2 length : {}",
-                             std::get<4>(refLockRecord2)[i].second);
-            return false;
-        }
-
-        // compare segment data
-
-        for (uint32_t j = 0; j < p.second; j++)
-        {
-            // if the segment data is different, then the locks is on a
-            // different resource so no conflict between the lock
-            // records.
-            // BMC is little endian, but the resourceID is formed by
-            // the Management Console in such a way that, the first byte
-            // from the MSB Position corresponds to the First Segment
-            // data. Therefore we need to convert the incoming
-            // resourceID into Big Endian before processing further.
-            if (!(checkByte(
-                    boost::endian::endian_reverse(std::get<3>(refLockRecord1)),
-                    boost::endian::endian_reverse(std::get<3>(refLockRecord2)),
-                    j)))
-            {
-                return false;
-            }
-        }
-
-        ++i;
-    }
-
-    return true;
-}
-
-inline uint32_t Lock::generateTransactionId()
-{
-    ++transactionId;
-    return transactionId;
-}
-
-} // namespace ibm_mc_lock
-} // namespace crow
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index ec8d4d6..51437c9 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -4,7 +4,7 @@
 #include "async_resp.hpp"
 #include "error_messages.hpp"
 #include "event_service_manager.hpp"
-#include "ibm/locks.hpp"
+#include "ibm/utils.hpp"
 #include "resource_messages.hpp"
 #include "str_utility.hpp"
 #include "utils/json_utils.hpp"
@@ -16,14 +16,6 @@
 #include <filesystem>
 #include <fstream>
 
-using SType = std::string;
-using SegmentFlags = std::vector<std::pair<std::string, uint32_t>>;
-using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
-using LockRequests = std::vector<LockRequest>;
-using Rc = std::pair<bool, std::variant<uint32_t, LockRequest>>;
-using RcGetLockList =
-    std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
-using ListOfSessionIds = std::vector<std::string>;
 namespace crow
 {
 namespace ibm_mc
@@ -277,22 +269,6 @@
     }
 }
 
-inline void
-    getLockServiceData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-{
-    asyncResp->res.jsonValue["@odata.type"] = "#LockService.v1_0_0.LockService";
-    asyncResp->res.jsonValue["@odata.id"] = "/ibm/v1/HMC/LockService/";
-    asyncResp->res.jsonValue["Id"] = "LockService";
-    asyncResp->res.jsonValue["Name"] = "LockService";
-
-    asyncResp->res.jsonValue["Actions"]["#LockService.AcquireLock"] = {
-        {"target", "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock"}};
-    asyncResp->res.jsonValue["Actions"]["#LockService.ReleaseLock"] = {
-        {"target", "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock"}};
-    asyncResp->res.jsonValue["Actions"]["#LockService.GetLockList"] = {
-        {"target", "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList"}};
-}
-
 inline void handleFileGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const std::string& fileID)
 {
@@ -399,248 +375,6 @@
     }
 }
 
-inline void
-    handleAcquireLockAPI(const crow::Request& req,
-                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                         std::vector<nlohmann::json::object_t> body)
-{
-    LockRequests lockRequestStructure;
-    for (auto& element : body)
-    {
-        std::string lockType;
-        uint64_t resourceId = 0;
-
-        SegmentFlags segInfo;
-        std::vector<nlohmann::json::object_t> segmentFlags;
-
-        if (!redfish::json_util::readJsonObject(
-                element, asyncResp->res, "LockType", lockType, "ResourceID",
-                resourceId, "SegmentFlags", segmentFlags))
-        {
-            BMCWEB_LOG_DEBUG("Not a Valid JSON");
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
-        BMCWEB_LOG_DEBUG("{}", lockType);
-        BMCWEB_LOG_DEBUG("{}", resourceId);
-
-        BMCWEB_LOG_DEBUG("Segment Flags are present");
-
-        for (auto& e : segmentFlags)
-        {
-            std::string lockFlags;
-            uint32_t segmentLength = 0;
-
-            if (!redfish::json_util::readJsonObject(
-                    e, asyncResp->res, "LockFlag", lockFlags, "SegmentLength",
-                    segmentLength))
-            {
-                asyncResp->res.result(boost::beast::http::status::bad_request);
-                return;
-            }
-
-            BMCWEB_LOG_DEBUG("Lockflag : {}", lockFlags);
-            BMCWEB_LOG_DEBUG("SegmentLength : {}", segmentLength);
-
-            segInfo.emplace_back(std::make_pair(lockFlags, segmentLength));
-        }
-
-        lockRequestStructure.emplace_back(make_tuple(
-            req.session->uniqueId, req.session->clientId.value_or(""), lockType,
-            resourceId, segInfo));
-    }
-
-    // print lock request into journal
-
-    for (auto& i : lockRequestStructure)
-    {
-        BMCWEB_LOG_DEBUG("{}", std::get<0>(i));
-        BMCWEB_LOG_DEBUG("{}", std::get<1>(i));
-        BMCWEB_LOG_DEBUG("{}", std::get<2>(i));
-        BMCWEB_LOG_DEBUG("{}", std::get<3>(i));
-
-        for (const auto& p : std::get<4>(i))
-        {
-            BMCWEB_LOG_DEBUG("{}, {}", p.first, p.second);
-        }
-    }
-
-    const LockRequests& t = lockRequestStructure;
-
-    auto varAcquireLock = crow::ibm_mc_lock::Lock::getInstance().acquireLock(t);
-
-    if (varAcquireLock.first)
-    {
-        // Either validity failure of there is a conflict with itself
-
-        auto validityStatus =
-            std::get<std::pair<bool, int>>(varAcquireLock.second);
-
-        if ((!validityStatus.first) && (validityStatus.second == 0))
-        {
-            BMCWEB_LOG_DEBUG("Not a Valid record");
-            BMCWEB_LOG_DEBUG("Bad json in request");
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
-        if (validityStatus.first && (validityStatus.second == 1))
-        {
-            BMCWEB_LOG_ERROR("There is a conflict within itself");
-            asyncResp->res.result(boost::beast::http::status::conflict);
-            return;
-        }
-    }
-    else
-    {
-        auto conflictStatus =
-            std::get<crow::ibm_mc_lock::Rc>(varAcquireLock.second);
-        if (!conflictStatus.first)
-        {
-            BMCWEB_LOG_DEBUG("There is no conflict with the locktable");
-            asyncResp->res.result(boost::beast::http::status::ok);
-
-            auto var = std::get<uint32_t>(conflictStatus.second);
-            nlohmann::json returnJson;
-            returnJson["id"] = var;
-            asyncResp->res.jsonValue["TransactionID"] = var;
-            return;
-        }
-        BMCWEB_LOG_DEBUG("There is a conflict with the lock table");
-        asyncResp->res.result(boost::beast::http::status::conflict);
-        auto var =
-            std::get<std::pair<uint32_t, LockRequest>>(conflictStatus.second);
-        nlohmann::json returnJson;
-        nlohmann::json segments;
-        nlohmann::json myarray = nlohmann::json::array();
-        returnJson["TransactionID"] = var.first;
-        returnJson["SessionID"] = std::get<0>(var.second);
-        returnJson["HMCID"] = std::get<1>(var.second);
-        returnJson["LockType"] = std::get<2>(var.second);
-        returnJson["ResourceID"] = std::get<3>(var.second);
-
-        for (const auto& i : std::get<4>(var.second))
-        {
-            segments["LockFlag"] = i.first;
-            segments["SegmentLength"] = i.second;
-            myarray.push_back(segments);
-        }
-
-        returnJson["SegmentFlags"] = myarray;
-        BMCWEB_LOG_ERROR("Conflicting lock record: {}", returnJson);
-        asyncResp->res.jsonValue["Record"] = returnJson;
-        return;
-    }
-}
-inline void
-    handleRelaseAllAPI(const crow::Request& req,
-                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-{
-    crow::ibm_mc_lock::Lock::getInstance().releaseLock(req.session->uniqueId);
-    asyncResp->res.result(boost::beast::http::status::ok);
-}
-
-inline void
-    handleReleaseLockAPI(const crow::Request& req,
-                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                         const std::vector<uint32_t>& listTransactionIds)
-{
-    BMCWEB_LOG_DEBUG("{}", listTransactionIds.size());
-    BMCWEB_LOG_DEBUG("Data is present");
-    for (unsigned int listTransactionId : listTransactionIds)
-    {
-        BMCWEB_LOG_DEBUG("{}", listTransactionId);
-    }
-
-    // validate the request ids
-
-    auto varReleaselock = crow::ibm_mc_lock::Lock::getInstance().releaseLock(
-        listTransactionIds, std::make_pair(req.session->clientId.value_or(""),
-                                           req.session->uniqueId));
-
-    if (!varReleaselock.first)
-    {
-        // validation Failed
-        BMCWEB_LOG_ERROR("handleReleaseLockAPI: validation failed");
-        asyncResp->res.result(boost::beast::http::status::bad_request);
-        return;
-    }
-    auto statusRelease =
-        std::get<crow::ibm_mc_lock::RcRelaseLock>(varReleaselock.second);
-    if (statusRelease.first)
-    {
-        // The current hmc owns all the locks, so we already released
-        // them
-        return;
-    }
-
-    // valid rid, but the current hmc does not own all the locks
-    BMCWEB_LOG_DEBUG("Current HMC does not own all the locks");
-    asyncResp->res.result(boost::beast::http::status::unauthorized);
-
-    auto var = statusRelease.second;
-    nlohmann::json returnJson;
-    nlohmann::json segments;
-    nlohmann::json myArray = nlohmann::json::array();
-    returnJson["TransactionID"] = var.first;
-    returnJson["SessionID"] = std::get<0>(var.second);
-    returnJson["HMCID"] = std::get<1>(var.second);
-    returnJson["LockType"] = std::get<2>(var.second);
-    returnJson["ResourceID"] = std::get<3>(var.second);
-
-    for (const auto& i : std::get<4>(var.second))
-    {
-        segments["LockFlag"] = i.first;
-        segments["SegmentLength"] = i.second;
-        myArray.push_back(segments);
-    }
-
-    returnJson["SegmentFlags"] = myArray;
-    BMCWEB_LOG_DEBUG("handleReleaseLockAPI: lockrecord: {}", returnJson);
-    asyncResp->res.jsonValue["Record"] = returnJson;
-}
-
-inline void
-    handleGetLockListAPI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                         const ListOfSessionIds& listSessionIds)
-{
-    BMCWEB_LOG_DEBUG("{}", listSessionIds.size());
-
-    auto status =
-        crow::ibm_mc_lock::Lock::getInstance().getLockList(listSessionIds);
-    auto var = std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
-
-    nlohmann::json lockRecords = nlohmann::json::array();
-
-    for (const auto& transactionId : var)
-    {
-        for (const auto& lockRecord : transactionId.second)
-        {
-            nlohmann::json returnJson;
-
-            returnJson["TransactionID"] = transactionId.first;
-            returnJson["SessionID"] = std::get<0>(lockRecord);
-            returnJson["HMCID"] = std::get<1>(lockRecord);
-            returnJson["LockType"] = std::get<2>(lockRecord);
-            returnJson["ResourceID"] = std::get<3>(lockRecord);
-
-            nlohmann::json segments;
-            nlohmann::json segmentInfoArray = nlohmann::json::array();
-
-            for (const auto& segment : std::get<4>(lockRecord))
-            {
-                segments["LockFlag"] = segment.first;
-                segments["SegmentLength"] = segment.second;
-                segmentInfoArray.push_back(segments);
-            }
-
-            returnJson["SegmentFlags"] = segmentInfoArray;
-            lockRecords.push_back(returnJson);
-        }
-    }
-    asyncResp->res.result(boost::beast::http::status::ok);
-    asyncResp->res.jsonValue["Records"] = lockRecords;
-}
-
 inline bool isValidConfigFileName(const std::string& fileName,
                                   crow::Response& res)
 {
@@ -690,8 +424,6 @@
         asyncResp->res.jsonValue["Name"] = "IBM Service Root";
         asyncResp->res.jsonValue["ConfigFiles"]["@odata.id"] =
             "/ibm/v1/Host/ConfigFiles";
-        asyncResp->res.jsonValue["LockService"]["@odata.id"] =
-            "/ibm/v1/HMC/LockService";
         asyncResp->res.jsonValue["BroadcastService"]["@odata.id"] =
             "/ibm/v1/HMC/BroadcastService";
     });
@@ -730,75 +462,6 @@
         handleFileUrl(req, asyncResp, fileName);
     });
 
-    BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService")
-        .privileges({{"ConfigureComponents", "ConfigureManager"}})
-        .methods(boost::beast::http::verb::get)(
-            [](const crow::Request&,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        getLockServiceData(asyncResp);
-    });
-
-    BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock")
-        .privileges({{"ConfigureComponents", "ConfigureManager"}})
-        .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        std::vector<nlohmann::json::object_t> body;
-        if (!redfish::json_util::readJsonAction(req, asyncResp->res, "Request",
-                                                body))
-        {
-            BMCWEB_LOG_DEBUG("Not a Valid JSON");
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
-        handleAcquireLockAPI(req, asyncResp, body);
-    });
-    BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
-        .privileges({{"ConfigureComponents", "ConfigureManager"}})
-        .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        std::string type;
-        std::vector<uint32_t> listTransactionIds;
-
-        if (!redfish::json_util::readJsonPatch(req, asyncResp->res, "Type",
-                                               type, "TransactionIDs",
-                                               listTransactionIds))
-        {
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
-        if (type == "Transaction")
-        {
-            handleReleaseLockAPI(req, asyncResp, listTransactionIds);
-        }
-        else if (type == "Session")
-        {
-            handleRelaseAllAPI(req, asyncResp);
-        }
-        else
-        {
-            BMCWEB_LOG_DEBUG(" Value of Type : {}is Not a Valid key", type);
-            redfish::messages::propertyValueNotInList(asyncResp->res, type,
-                                                      "Type");
-        }
-    });
-    BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList")
-        .privileges({{"ConfigureComponents", "ConfigureManager"}})
-        .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        ListOfSessionIds listSessionIds;
-
-        if (!redfish::json_util::readJsonPatch(req, asyncResp->res,
-                                               "SessionIDs", listSessionIds))
-        {
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
-        handleGetLockListAPI(asyncResp, listSessionIds);
-    });
-
     BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
         .privileges({{"ConfigureComponents", "ConfigureManager"}})
         .methods(boost::beast::http::verb::post)(
diff --git a/include/sessions.hpp b/include/sessions.hpp
index fb72762..1d0b620 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -11,9 +11,6 @@
 #include <csignal>
 #include <optional>
 #include <random>
-#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
-#include "ibm/locks.hpp"
-#endif
 
 namespace persistent_data
 {
@@ -310,9 +307,6 @@
 
     void removeSession(const std::shared_ptr<UserSession>& session)
     {
-#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
-        crow::ibm_mc_lock::Lock::getInstance().releaseLock(session->uniqueId);
-#endif
         authTokens.erase(session->sessionToken);
         needWrite = true;
     }
@@ -396,10 +390,6 @@
                 if (timeNow - authTokensIt->second->lastUpdated >=
                     timeoutInSeconds)
                 {
-#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
-                    crow::ibm_mc_lock::Lock::getInstance().releaseLock(
-                        authTokensIt->second->uniqueId);
-#endif
                     authTokensIt = authTokens.erase(authTokensIt);
 
                     needWrite = true;
diff --git a/meson.build b/meson.build
index a965b7f..ee8a91f 100644
--- a/meson.build
+++ b/meson.build
@@ -464,7 +464,6 @@
     'test/include/http_utility_test.cpp',
     'test/include/human_sort_test.cpp',
     'test/include/ibm/configfile_test.cpp',
-    'test/include/ibm/lock_test.cpp',
     'test/include/json_html_serializer.cpp',
     'test/include/multipart_test.cpp',
     'test/include/openbmc_dbus_rest_test.cpp',
diff --git a/src/webserver_run.cpp b/src/webserver_run.cpp
index 2f28e16..3c1c615 100644
--- a/src/webserver_run.cpp
+++ b/src/webserver_run.cpp
@@ -76,7 +76,6 @@
 
 #ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
     crow::ibm_mc::requestRoutes(app);
-    crow::ibm_mc_lock::Lock::getInstance();
 #endif
 
 #ifdef BMCWEB_ENABLE_GOOGLE_API
diff --git a/test/include/ibm/lock_test.cpp b/test/include/ibm/lock_test.cpp
deleted file mode 100644
index 9570ec6..0000000
--- a/test/include/ibm/lock_test.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-#include "ibm/locks.hpp"
-
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <variant>
-#include <vector>
-
-#include <gmock/gmock.h> // IWYU pragma: keep
-#include <gtest/gtest.h> // IWYU pragma: keep
-
-// IWYU pragma: no_include <gtest/gtest-message.h>
-// IWYU pragma: no_include <gtest/gtest-test-part.h>
-// IWYU pragma: no_include "gtest/gtest_pred_impl.h"
-
-namespace crow::ibm_mc_lock
-{
-namespace
-{
-
-using SType = std::string;
-using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
-using LockRequests = std::vector<LockRequest>;
-using Rc =
-    std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
-using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
-using RcGetLockList =
-    std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
-using ListOfTransactionIds = std::vector<uint32_t>;
-using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
-using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
-using SessionFlags = std::pair<SType, SType>;
-using ListOfSessionIds = std::vector<std::string>;
-using ::testing::IsEmpty;
-
-class LockTest : public ::testing::Test
-{
-  protected:
-    LockRequests request;
-    LockRequests request1, request2;
-    LockRequest record;
-
-  public:
-    LockTest() :
-        // lockrequest with multiple lockrequests
-        request{{"xxxxx",
-                 "hmc-id",
-                 "Read",
-                 234,
-                 {{"DontLock", 2}, {"DontLock", 4}}},
-                {"xxxxx",
-                 "hmc-id",
-                 "Read",
-                 234,
-                 {{"DontLock", 2}, {"DontLock", 4}}}},
-        request1{{"xxxxx",
-                  "hmc-id",
-                  "Read",
-                  234,
-                  {{"DontLock", 2}, {"DontLock", 4}}}},
-        request2{{"xxxxx",
-                  "hmc-id",
-                  "Write",
-                  234,
-                  {{"LockAll", 2}, {"DontLock", 4}}}},
-        record{
-            "xxxxx", "hmc-id", "Read", 234, {{"DontLock", 2}, {"DontLock", 4}}}
-    {}
-
-    ~LockTest() override = default;
-
-    LockTest(const LockTest&) = delete;
-    LockTest(LockTest&&) = delete;
-    LockTest& operator=(const LockTest&) = delete;
-    LockTest& operator=(const LockTest&&) = delete;
-};
-
-class MockLock : public crow::ibm_mc_lock::Lock
-{
-  public:
-    bool isValidLockRequest(const LockRequest& record1) override
-    {
-        bool status = Lock::isValidLockRequest(record1);
-        return status;
-    }
-    bool isConflictRequest(const LockRequests& request) override
-    {
-        bool status = Lock::isConflictRequest(request);
-        return status;
-    }
-    Rc isConflictWithTable(const LockRequests& request) override
-    {
-        auto conflict = Lock::isConflictWithTable(request);
-        return conflict;
-    }
-    uint32_t generateTransactionId() override
-    {
-        uint32_t tid = Lock::generateTransactionId();
-        return tid;
-    }
-
-    bool validateRids(const ListOfTransactionIds& tids) override
-    {
-        bool status = Lock::validateRids(tids);
-        return status;
-    }
-    RcRelaseLock isItMyLock(const ListOfTransactionIds& tids,
-                            const SessionFlags& ids) override
-    {
-        auto status = Lock::isItMyLock(tids, ids);
-        return status;
-    }
-    friend class LockTest;
-};
-
-TEST_F(LockTest, ValidationGoodTestCase)
-{
-    MockLock lockManager;
-    const LockRequest& t = record;
-    EXPECT_TRUE(lockManager.isValidLockRequest(t));
-}
-
-TEST_F(LockTest, ValidationBadTestWithLocktype)
-{
-    MockLock lockManager;
-    // Corrupt the lock type
-    std::get<2>(record) = "rwrite";
-    const LockRequest& t = record;
-    EXPECT_FALSE(lockManager.isValidLockRequest(t));
-}
-
-TEST_F(LockTest, ValidationBadTestWithlockFlags)
-{
-    MockLock lockManager;
-    // Corrupt the lockflag
-    std::get<4>(record)[0].first = "lock";
-    const LockRequest& t = record;
-    EXPECT_FALSE(lockManager.isValidLockRequest(t));
-}
-
-TEST_F(LockTest, ValidationBadTestWithSegmentlength)
-{
-    MockLock lockManager;
-    // Corrupt the Segment length
-    std::get<4>(record)[0].second = 7;
-    const LockRequest& t = record;
-    EXPECT_FALSE(lockManager.isValidLockRequest(t));
-}
-
-TEST_F(LockTest, MultiRequestWithoutConflict)
-{
-    MockLock lockManager;
-    const LockRequests& t = request;
-    EXPECT_FALSE(lockManager.isConflictRequest(t));
-}
-
-TEST_F(LockTest, MultiRequestWithConflictduetoSameSegmentLength)
-{
-    MockLock lockManager;
-    // Corrupt the locktype
-    std::get<2>(request[0]) = "Write";
-    // Match the segment lengths to points them to lock similar kind of
-    // resource
-    std::get<4>(request[0])[0].first = "LockAll";
-    const LockRequests& t = request;
-    EXPECT_TRUE(lockManager.isConflictRequest(t));
-}
-
-TEST_F(LockTest, MultiRequestWithoutConflictduetoDifferentSegmentLength)
-{
-    MockLock lockManager;
-    // Corrupt the locktype
-    std::get<2>(request[0]) = "Write";
-    // Match the segment lengths to points them to lock similar kind of
-    // resource
-    std::get<4>(request[0])[0].first = "LockSame";
-    // Change the segment length , so that the requests are trying to lock
-    // two different kind of resources
-    std::get<4>(request[0])[0].second = 3;
-    const LockRequests& t = request;
-    // Return No Conflict
-    EXPECT_FALSE(lockManager.isConflictRequest(t));
-}
-
-TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktype)
-{
-    MockLock lockManager;
-    // Match the segment lengths to points them to lock similar kind of
-    // resource
-    std::get<4>(request[0])[0].first = "LockAll";
-    const LockRequests& t = request;
-    // Return No Conflict
-    EXPECT_FALSE(lockManager.isConflictRequest(t));
-}
-
-TEST_F(LockTest, MultiRequestWithoutConflictduetoReadLocktypeAndLockall)
-{
-    MockLock lockManager;
-    // Match the segment lengths to points them to lock similar kind of
-    // resource
-    std::get<4>(request[0])[0].first = "LockAll";
-    std::get<4>(request[0])[1].first = "LockAll";
-    const LockRequests& t = request;
-    // Return No Conflict
-    EXPECT_FALSE(lockManager.isConflictRequest(t));
-}
-
-TEST_F(LockTest, RequestNotConflictedWithLockTableEntries)
-{
-    MockLock lockManager;
-    const LockRequests& t = request1;
-    // Insert the request1 into the lock table
-    auto rc1 = lockManager.isConflictWithTable(t);
-    // Corrupt the lock type
-    std::get<2>(request[0]) = "Read";
-    // Corrupt the lockflag
-    std::get<4>(request[0])[1].first = "LockAll";
-    const LockRequests& p = request;
-    auto rc2 = lockManager.isConflictWithTable(p);
-    // Return No Conflict
-    EXPECT_FALSE(rc2.first);
-}
-
-TEST_F(LockTest, TestGenerateTransactionIDFunction)
-{
-    MockLock lockManager;
-    uint32_t transactionId1 = lockManager.generateTransactionId();
-    uint32_t transactionId2 = lockManager.generateTransactionId();
-    EXPECT_EQ(transactionId2, ++transactionId1);
-}
-
-TEST_F(LockTest, ValidateTransactionIDsGoodTestCase)
-{
-    MockLock lockManager;
-    const LockRequests& t = request1;
-    // Insert the request1 into the lock table
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<uint32_t> tids = {1};
-    const std::vector<uint32_t>& p = tids;
-    EXPECT_TRUE(lockManager.validateRids(p));
-}
-
-TEST_F(LockTest, ValidateTransactionIDsBadTestCase)
-{
-    MockLock lockManager;
-    // Insert the request1 into the lock table
-    const LockRequests& t = request1;
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<uint32_t> tids = {10};
-    const std::vector<uint32_t>& p = tids;
-    EXPECT_FALSE(lockManager.validateRids(p));
-}
-
-TEST_F(LockTest, ValidateisItMyLockGoodTestCase)
-{
-    MockLock lockManager;
-    // Insert the request1 into the lock table
-    const LockRequests& t = request1;
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<uint32_t> tids = {1};
-    const std::vector<uint32_t>& p = tids;
-    std::string hmcid = "hmc-id";
-    std::string sessionid = "xxxxx";
-    std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
-    auto rc = lockManager.isItMyLock(p, ids);
-    EXPECT_TRUE(rc.first);
-}
-
-TEST_F(LockTest, ValidateisItMyLockBadTestCase)
-{
-    MockLock lockManager;
-    // Corrupt the client identifier
-    std::get<1>(request1[0]) = "randomid";
-    // Insert the request1 into the lock table
-    const LockRequests& t = request1;
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<uint32_t> tids = {1};
-    const std::vector<uint32_t>& p = tids;
-    std::string hmcid = "hmc-id";
-    std::string sessionid = "random";
-    std::pair<SType, SType> ids = std::make_pair(hmcid, sessionid);
-    auto rc = lockManager.isItMyLock(p, ids);
-    EXPECT_FALSE(rc.first);
-}
-
-TEST_F(LockTest, ValidateSessionIDForGetlocklistBadTestCase)
-{
-    MockLock lockManager;
-    // Insert the request1 into the lock table
-    const LockRequests& t = request1;
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<std::string> sessionid = {"random"};
-    auto status = lockManager.getLockList(sessionid);
-    auto result =
-        std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
-    EXPECT_THAT(result, IsEmpty());
-}
-
-TEST_F(LockTest, ValidateSessionIDForGetlocklistGoodTestCase)
-{
-    MockLock lockManager;
-    // Insert the request1 into the lock table
-    const LockRequests& t = request1;
-    auto rc1 = lockManager.isConflictWithTable(t);
-    std::vector<std::string> sessionid = {"xxxxx"};
-    auto status = lockManager.getLockList(sessionid);
-    auto result =
-        std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
-    EXPECT_EQ(result.size(), 1);
-}
-
-} // namespace
-} // namespace crow::ibm_mc_lock
