Changes to fix async POST/PATCH infra

'''
NSMD created async object in round robin manner on POST/PATCH request. There was no handshake between bmcweb and nsmd for these objectPaths getting reused. Sometime it was causing overriding of value while creating RF response.

This change will enable nsmd to create unique object path for each post/patch request and delete these object paths after 2 mins.
'''

Fixes nvbug https://nvbugspro.nvidia.com/bug/5266003
signed-off-by: <ayushkumart@nvidia.com>
diff --git a/nsmd/nsmRawCommand/test/nsmRawCommandHandler_test.cpp b/nsmd/nsmRawCommand/test/nsmRawCommandHandler_test.cpp
index 43cbaa5..d80b3fa 100644
--- a/nsmd/nsmRawCommand/test/nsmRawCommandHandler_test.cpp
+++ b/nsmd/nsmRawCommand/test/nsmRawCommandHandler_test.cpp
@@ -77,6 +77,7 @@
         0, 0, 0, false, 0, 0, unix_fd(fd));
     EXPECT_NE(path, sdbusplus::message::object_path{});
 }
+
 TEST_F(NsmRawCommandHandlerTest, BadTestSendRequest)
 {
     EXPECT_THROW(
@@ -87,27 +88,6 @@
         NsmRawCommandHandler::getInstance().sendRequest(
             0, 0, 0, false, NSM_TYPE_FIRMWARE + 1, 0, unix_fd(fd)),
         sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
-    for (size_t i = 0; i < AsyncOperationManager::getInstance()->maxObjectCount;
-         i++)
-    {
-        AsyncOperationManager::getInstance()->getNewStatusInterface();
-    }
-    EXPECT_THROW(NsmRawCommandHandler::getInstance().sendRequest(
-                     0, 0, 0, false, 0, 0, unix_fd(fd)),
-                 sdbusplus::error::xyz::openbmc_project::common::Unavailable);
-    for (auto& interface :
-         AsyncOperationManager::getInstance()->statusInterfaces)
-    {
-        interface.reset();
-    }
-    for (auto& interface :
-         AsyncOperationManager::getInstance()->valueInterfaces)
-    {
-        interface.reset();
-    }
-    AsyncOperationManager::getInstance()->statusInterfaces.clear();
-    AsyncOperationManager::getInstance()->valueInterfaces.clear();
-    AsyncOperationManager::getInstance()->currentObjectCount = 0;
 }
 
 TEST_F(NsmRawCommandHandlerTest, BadTestNoDevice)
diff --git a/nsmd/nsmSetAsync/asyncOperationManager.cpp b/nsmd/nsmSetAsync/asyncOperationManager.cpp
index 43306ea..be5991e 100644
--- a/nsmd/nsmSetAsync/asyncOperationManager.cpp
+++ b/nsmd/nsmSetAsync/asyncOperationManager.cpp
@@ -25,15 +25,12 @@
 AsyncOperationManager* AsyncOperationManager::getInstance()
 {
     static const std::unique_ptr<AsyncOperationManager> instance{
-        new AsyncOperationManager{MaxAsyncOperationResultObjectCount,
-                                  AsyncOperationResultObjPath}};
+        new AsyncOperationManager{AsyncOperationResultObjPath}};
     return instance.get();
 }
 
 AsyncOperationManager::AsyncOperationManager(
-    const size_t maxResultObjectCount,
     const std::string& asyncOperationResultObjPath) :
-    maxObjectCount(maxResultObjectCount),
     asyncOperationResultObjPath(asyncOperationResultObjPath)
 {}
 
@@ -48,59 +45,31 @@
 
 std::pair<bool, size_t> AsyncOperationManager::getCurrentObjectCount()
 {
-    const size_t numResultObjects = statusInterfaces.size();
+    const std::string objPath = asyncOperationResultObjPath + "/" +
+                                std::to_string(currentObjectCount);
 
-    // check if maximum result object count is reached
-    if (numResultObjects >= maxObjectCount)
-    {
-        size_t count{currentObjectCount};
+    auto statusInterface = std::make_shared<AsyncStatusIntf>(
+        utils::DBusHandler::getBus(), objPath.c_str());
 
-        // check for the next available not in progress result object
-        while (statusInterfaces[count]->status() ==
-               AsyncOperationStatusType::InProgress)
-        {
-            ++count;
+    auto valueInterface = std::make_shared<AsyncValueIntf>(
+        utils::DBusHandler::getBus(), objPath.c_str());
 
-            if (count >= maxObjectCount)
-            {
-                count = 0;
-            }
+    statusInterfaces[currentObjectCount] = statusInterface;
+    valueInterfaces[currentObjectCount] = valueInterface;
+    const size_t returnValue = currentObjectCount;
 
-            // all the result Objects are checked and no Object is found with
-            // status not in progress
-            if (count == currentObjectCount)
-            {
-                lg2::error(
-                    "AsyncOperationManager : no available result Object to allocate for the request.");
+    auto timer =
+        std::make_shared<sdbusplus::Timer>([this, index = returnValue]() {
+        statusInterfaces.erase(index);
+        valueInterfaces.erase(index);
+        objectPathTimers.erase(index);
+        return false; // Don't restart timer
+    });
+    timer->start(std::chrono::minutes(2));
 
-                return {false, {}};
-            }
-        }
-
-        currentObjectCount = count;
-    }
-    else
-    {
-        const std::string objPath = asyncOperationResultObjPath + "/" +
-                                    std::to_string(currentObjectCount);
-
-        auto statusInterface = std::make_shared<AsyncStatusIntf>(
-            utils::DBusHandler::getBus(), objPath.c_str());
-
-        auto valueInterface = std::make_shared<AsyncValueIntf>(
-            utils::DBusHandler::getBus(), objPath.c_str());
-
-        statusInterfaces.push_back(statusInterface);
-        valueInterfaces.push_back(valueInterface);
-    }
-
-    const size_t returnValue{currentObjectCount};
+    objectPathTimers[returnValue] = std::move(timer);
 
     ++currentObjectCount;
-    if (currentObjectCount >= maxObjectCount)
-    {
-        currentObjectCount = 0;
-    }
 
     return {true, returnValue};
 }
diff --git a/nsmd/nsmSetAsync/asyncOperationManager.hpp b/nsmd/nsmSetAsync/asyncOperationManager.hpp
index af62d71..425c632 100644
--- a/nsmd/nsmSetAsync/asyncOperationManager.hpp
+++ b/nsmd/nsmSetAsync/asyncOperationManager.hpp
@@ -80,10 +80,10 @@
         getNewStatusValueInterface();
 
   private:
-    AsyncOperationManager(const size_t maxResultObjectCount,
-                          const std::string& asyncOperationResultObjPath);
+    AsyncOperationManager(const std::string& asyncOperationResultObjPath);
 
     std::pair<bool, size_t> getCurrentObjectCount();
+    size_t currentObjectCount{0};
 
     /**
      * @brief Clear the value stored in the value interface, special attention
@@ -93,12 +93,14 @@
      */
     void clearValueInterface(std::shared_ptr<AsyncValueIntf> valueIntf);
 
-    size_t currentObjectCount{};
-    const size_t maxObjectCount;
     const std::string asyncOperationResultObjPath;
 
-    std::vector<std::shared_ptr<AsyncStatusIntf>> statusInterfaces;
-    std::vector<std::shared_ptr<AsyncValueIntf>> valueInterfaces;
+    std::unordered_map<uint64_t, std::shared_ptr<AsyncStatusIntf>>
+        statusInterfaces;
+    std::unordered_map<uint64_t, std::shared_ptr<AsyncValueIntf>>
+        valueInterfaces;
+    std::unordered_map<uint64_t, std::shared_ptr<sdbusplus::Timer>>
+        objectPathTimers;
 
     std::unordered_map<std::string, AsyncSetOperationDispatcher> dispatchers;
 };
diff --git a/nsmd/nsmSetAsync/test/asyncOperationManager_test.cpp b/nsmd/nsmSetAsync/test/asyncOperationManager_test.cpp
index 8d9c327..c2c10e9 100644
--- a/nsmd/nsmSetAsync/test/asyncOperationManager_test.cpp
+++ b/nsmd/nsmSetAsync/test/asyncOperationManager_test.cpp
@@ -26,7 +26,7 @@
 
 TEST(asyncOperationManager, GoodTest)
 {
-    AsyncOperationManager manager{8, AsyncOperationResultObjPath};
+    AsyncOperationManager manager{AsyncOperationResultObjPath};
 
     for (size_t i{0}; i < 4; ++i)
     {
@@ -55,8 +55,8 @@
     for (size_t i{0}; i < 32; ++i)
     {
         const auto [path, statusInterface] = manager.getNewStatusInterface();
-        EXPECT_EQ(path, "");
-        EXPECT_EQ(statusInterface.get(), nullptr);
+        EXPECT_NE(path, "");
+        EXPECT_NE(statusInterface.get(), nullptr);
     }
 
     for (size_t i{0}; i < 32; ++i)
@@ -64,48 +64,8 @@
         const auto [path, statusInterface,
                     valueInterface] = manager.getNewStatusValueInterface();
 
-        EXPECT_EQ(path, "");
-        EXPECT_EQ(statusInterface.get(), nullptr);
-        EXPECT_EQ(valueInterface.get(), nullptr);
-    }
-
-    manager.statusInterfaces[2]->status(AsyncOperationStatusType::Success);
-    manager.statusInterfaces[7]->status(AsyncOperationStatusType::WriteFailure);
-
-    {
-        const auto [path, statusInterface,
-                    valueInterface] = manager.getNewStatusValueInterface();
-
-        const std::string objPath = std::string{AsyncOperationResultObjPath} +
-                                    "/" + std::to_string(2);
-
-        EXPECT_EQ(path, objPath);
+        EXPECT_NE(path, "");
         EXPECT_NE(statusInterface.get(), nullptr);
         EXPECT_NE(valueInterface.get(), nullptr);
     }
-
-    {
-        const auto [path, statusInterface,
-                    valueInterface] = manager.getNewStatusValueInterface();
-
-        const std::string objPath = std::string{AsyncOperationResultObjPath} +
-                                    "/" + std::to_string(7);
-
-        EXPECT_EQ(path, objPath);
-        EXPECT_NE(statusInterface.get(), nullptr);
-        EXPECT_NE(valueInterface.get(), nullptr);
-    }
-
-    manager.statusInterfaces[5]->status(
-        AsyncOperationStatusType::UnsupportedRequest);
-
-    {
-        const auto [path, statusInterface] = manager.getNewStatusInterface();
-
-        const std::string objPath = std::string{AsyncOperationResultObjPath} +
-                                    "/" + std::to_string(5);
-
-        EXPECT_EQ(path, objPath);
-        EXPECT_NE(statusInterface.get(), nullptr);
-    }
 }