Implement Release Lock in Lock Service

- This commit implements the Release Lock rest API, so that
  any external client(having admin-privelege) can release the
  locks owned by it.

Tested By:

1.curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{
 "Request" :[
             {
                 "LockType":"Read",
                 "SegmentFlags":
                                 [
                                   {"LockFlag":"LockSame","SegmentLength":3},
                                   {"LockFlag":"DontLock","SegmentLength":4}
                                 ],
                 "ResourceID": 256
              }
         ]
 }' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock
{
  "TransactionID": 1
}

2.curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{
  "Request" :[
             {
                 "LockType":"Read",
                 "SegmentFlags":
                                 [
                                   {"LockFlag":"LockSame","SegmentLength":3},
                                   {"LockFlag":"DontLock","SegmentLength":4}
                                 ],
                 "ResourceID": 256
              }
         ]
 }' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock
{
  "TransactionID": 2
}

3. Try releasing the lock owned by it

curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d
'{"TransactionIDs": [1]}' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock

4. Try releasing the lock, which is not owned by the same session

curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d
'{"TransactionIDs": [2]}' https://127.0.0.1:2443/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock

{
  "Record": {
    "HMCID": "hmc-id",
    "LockType": "Read",
    "ResourceID": 256,
    "SegmentFlags": [
      {
        "LockFlag": "LockSame",
        "SegmentLength": 3
      },
      {
        "LockFlag": "DontLock",
        "SegmentLength": 4
      }
    ],
    "SessionID": "qM4D0VfZt3",
    "TransactionID": 2
  }
}

Signed-off-by: manojkiraneda <manojkiran.eda@gmail.com>
Change-Id: I5d75d44ce805358b25dc293db4dc0f44f4317c06
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index a4dcf4a..a4bf31e 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -406,6 +406,74 @@
     }
 }
 
+void handleReleaseLockAPI(const crow::Request &req, crow::Response &res,
+                          const std::vector<uint32_t> &listTransactionIds)
+{
+    BMCWEB_LOG_DEBUG << listTransactionIds.size();
+    BMCWEB_LOG_DEBUG << "Data is present";
+    for (uint32_t i = 0; i < listTransactionIds.size(); i++)
+    {
+        BMCWEB_LOG_DEBUG << listTransactionIds[i];
+    }
+
+    std::string clientId = "hmc-id";
+    std::string sessionId = req.session->uniqueId;
+
+    // validate the request ids
+
+    auto varReleaselock = crow::ibm_mc_lock::lockObject.releaseLock(
+        listTransactionIds, std::make_pair(clientId, sessionId));
+
+    if (!varReleaselock.first)
+    {
+        // validation Failed
+        res.result(boost::beast::http::status::bad_request);
+        res.end();
+        return;
+    }
+    else
+    {
+        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
+            res.result(boost::beast::http::status::ok);
+            res.end();
+            return;
+        }
+
+        else
+        {
+            // valid rid, but the current hmc does not own all the locks
+            BMCWEB_LOG_DEBUG << "Current HMC does not own all the locks";
+            res.result(boost::beast::http::status::unauthorized);
+
+            auto var = statusRelease.second;
+            nlohmann::json returnJson, 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 (uint32_t i = 0; i < std::get<4>(var.second).size(); i++)
+            {
+                segments["LockFlag"] = std::get<4>(var.second)[i].first;
+                segments["SegmentLength"] = std::get<4>(var.second)[i].second;
+                myArray.push_back(segments);
+            }
+
+            returnJson["SegmentFlags"] = myArray;
+            res.jsonValue["Record"] = returnJson;
+            res.end();
+            return;
+        }
+    }
+}
+
 template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
 {
 
@@ -469,6 +537,23 @@
                 }
                 handleAcquireLockAPI(req, res, body);
             });
+
+    BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
+        .requires({"ConfigureComponents", "ConfigureManager"})
+        .methods("POST"_method)(
+            [](const crow::Request &req, crow::Response &res) {
+                std::vector<uint32_t> listTransactionIds;
+
+                if (!redfish::json_util::readJson(req, res, "TransactionIDs",
+                                                  listTransactionIds))
+                {
+                    res.result(boost::beast::http::status::bad_request);
+                    res.end();
+                    return;
+                }
+
+                handleReleaseLockAPI(req, res, listTransactionIds);
+            });
 }
 
 } // namespace ibm_mc