blob: 2c45693957c2bf255c36be9bda5b21dce410e933 [file] [log] [blame]
Ratan Gupta453fed02019-12-14 09:39:47 +05301#pragma once
2#include <app.h>
3#include <tinyxml2.h>
4
5#include <async_resp.hpp>
Sunitha Harish97b0e432019-11-21 04:59:29 -06006#include <boost/algorithm/string.hpp>
7#include <boost/container/flat_set.hpp>
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +05308#include <error_messages.hpp>
Sunitha Harish96330b92020-06-26 05:42:14 -05009#include <event_service_manager.hpp>
manojkiraneda0b631ae2019-12-03 17:54:28 +053010#include <ibm/locks.hpp>
11#include <nlohmann/json.hpp>
Sunitha Harish96330b92020-06-26 05:42:14 -050012#include <resource_messages.hpp>
Sunitha Harish97b0e432019-11-21 04:59:29 -060013#include <sdbusplus/message/types.hpp>
manojkiraneda0b631ae2019-12-03 17:54:28 +053014#include <utils/json_utils.hpp>
Sunitha Harish97b0e432019-11-21 04:59:29 -060015
Gunnar Mills1214b7e2020-06-04 10:11:30 -050016#include <filesystem>
17#include <fstream>
18#include <regex>
19
manojkiraneda0b631ae2019-12-03 17:54:28 +053020using SType = std::string;
21using SegmentFlags = std::vector<std::pair<std::string, uint32_t>>;
22using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
23using LockRequests = std::vector<LockRequest>;
24using Rc = std::pair<bool, std::variant<uint32_t, LockRequest>>;
manojkiraneda402b5712019-12-13 17:07:09 +053025using RcGetLockList =
26 std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>;
27using ListOfSessionIds = std::vector<std::string>;
Ratan Gupta453fed02019-12-14 09:39:47 +053028namespace crow
29{
30namespace ibm_mc
31{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050032constexpr const char* methodNotAllowedMsg = "Method Not Allowed";
33constexpr const char* resourceNotFoundMsg = "Resource Not Found";
34constexpr const char* contentNotAcceptableMsg = "Content Not Acceptable";
35constexpr const char* internalServerError = "Internal Server Error";
Sunitha Harish97b0e432019-11-21 04:59:29 -060036
Asmitha Karunanithi5738de52020-07-17 02:03:31 -050037constexpr size_t maxSaveareaFileSize =
38 500000; // Allow save area file size upto 500KB
39constexpr size_t maxBroadcastMsgSize =
40 1000; // Allow Broadcast message size upto 1KB
41
Ed Tanous02379d32020-09-15 21:15:44 -070042inline bool createSaveAreaPath(crow::Response& res)
Sunitha Harish97b0e432019-11-21 04:59:29 -060043{
44 // The path /var/lib/obmc will be created by initrdscripts
45 // Create the directories for the save-area files, when we get
46 // first file upload request
47 std::error_code ec;
48 if (!std::filesystem::is_directory("/var/lib/obmc/bmc-console-mgmt", ec))
49 {
50 std::filesystem::create_directory("/var/lib/obmc/bmc-console-mgmt", ec);
51 }
52 if (ec)
53 {
54 res.result(boost::beast::http::status::internal_server_error);
55 res.jsonValue["Description"] = internalServerError;
56 BMCWEB_LOG_DEBUG
57 << "handleIbmPost: Failed to prepare save-area directory. ec : "
58 << ec;
59 return false;
60 }
61
62 if (!std::filesystem::is_directory(
63 "/var/lib/obmc/bmc-console-mgmt/save-area", ec))
64 {
65 std::filesystem::create_directory(
66 "/var/lib/obmc/bmc-console-mgmt/save-area", ec);
67 }
68 if (ec)
69 {
70 res.result(boost::beast::http::status::internal_server_error);
71 res.jsonValue["Description"] = internalServerError;
72 BMCWEB_LOG_DEBUG
73 << "handleIbmPost: Failed to prepare save-area directory. ec : "
74 << ec;
75 return false;
76 }
77 return true;
78}
Ed Tanous02379d32020-09-15 21:15:44 -070079
80inline void handleFilePut(const crow::Request& req, crow::Response& res,
81 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -060082{
83 // Check the content-type of the request
84 std::string_view contentType = req.getHeaderValue("content-type");
85 if (boost::starts_with(contentType, "multipart/form-data"))
86 {
87 BMCWEB_LOG_DEBUG
88 << "This is multipart/form-data. Invalid content for PUT";
89
90 res.result(boost::beast::http::status::not_acceptable);
91 res.jsonValue["Description"] = contentNotAcceptableMsg;
92 return;
93 }
94 else
95 {
96 BMCWEB_LOG_DEBUG << "Not a multipart/form-data. Continue..";
97 }
asmithakarun1c7b07c2019-09-09 03:42:59 -050098
99 BMCWEB_LOG_DEBUG
100 << "handleIbmPut: Request to create/update the save-area file";
101 if (!createSaveAreaPath(res))
Sunitha Harish97b0e432019-11-21 04:59:29 -0600102 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500103 res.result(boost::beast::http::status::not_found);
104 res.jsonValue["Description"] = resourceNotFoundMsg;
105 return;
106 }
107 // Create the file
108 std::ofstream file;
109 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
110 loc /= fileID;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600111
asmithakarun1c7b07c2019-09-09 03:42:59 -0500112 std::string data = std::move(req.body);
113 BMCWEB_LOG_DEBUG << "data capaticty : " << data.capacity();
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500114 if (data.capacity() > maxSaveareaFileSize)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500115 {
116 res.result(boost::beast::http::status::bad_request);
117 res.jsonValue["Description"] =
Ratan Guptae46946a2020-05-11 13:22:59 +0530118 "File size exceeds maximum allowed size[500KB]";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500119 return;
120 }
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500121 BMCWEB_LOG_DEBUG << "Writing to the file: " << loc;
122
123 bool fileExists = false;
124 if (std::filesystem::exists(loc))
125 {
126 fileExists = true;
127 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500128 file.open(loc, std::ofstream::out);
129 if (file.fail())
130 {
131 BMCWEB_LOG_DEBUG << "Error while opening the file for writing";
132 res.result(boost::beast::http::status::internal_server_error);
133 res.jsonValue["Description"] = "Error while creating the file";
134 return;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600135 }
136 else
137 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500138 file << data;
Sunitha Harish96330b92020-06-26 05:42:14 -0500139 std::string origin = "/ibm/v1/Host/ConfigFiles/" + fileID;
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500140 // Push an event
141 if (fileExists)
142 {
143 BMCWEB_LOG_DEBUG << "config file is updated";
144 res.jsonValue["Description"] = "File Updated";
145
146 redfish::EventServiceManager::getInstance().sendEvent(
Ed Tanous2c70f802020-09-28 14:29:23 -0700147 redfish::messages::resourceChanged(), origin, "IBMConfigFile");
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500148 }
149 else
150 {
151 BMCWEB_LOG_DEBUG << "config file is created";
152 res.jsonValue["Description"] = "File Created";
153
154 redfish::EventServiceManager::getInstance().sendEvent(
Ed Tanous2c70f802020-09-28 14:29:23 -0700155 redfish::messages::resourceCreated(), origin, "IBMConfigFile");
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500156 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500157 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530158}
asmithakarun1c7b07c2019-09-09 03:42:59 -0500159
Ed Tanous02379d32020-09-15 21:15:44 -0700160inline void handleConfigFileList(crow::Response& res)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530161{
162 std::vector<std::string> pathObjList;
163 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
164 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
165 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500166 for (const auto& file : std::filesystem::directory_iterator(loc))
Ratan Guptad3630cb2019-12-14 11:21:35 +0530167 {
168 std::filesystem::path pathObj(file.path());
169 pathObjList.push_back("/ibm/v1/Host/ConfigFiles/" +
170 pathObj.filename().string());
171 }
172 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500173 res.jsonValue["@odata.type"] = "#IBMConfigFile.v1_0_0.IBMConfigFile";
Ratan Guptad3630cb2019-12-14 11:21:35 +0530174 res.jsonValue["@odata.id"] = "/ibm/v1/Host/ConfigFiles/";
175 res.jsonValue["Id"] = "ConfigFiles";
176 res.jsonValue["Name"] = "ConfigFiles";
177
178 res.jsonValue["Members"] = std::move(pathObjList);
Sunitha Harishe56f2542020-07-22 02:38:59 -0500179 res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"] = {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530180 {"target",
Sunitha Harishe56f2542020-07-22 02:38:59 -0500181 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll"}};
Ratan Guptad3630cb2019-12-14 11:21:35 +0530182 res.end();
183}
184
Ed Tanous02379d32020-09-15 21:15:44 -0700185inline void deleteConfigFiles(crow::Response& res)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530186{
187 std::vector<std::string> pathObjList;
188 std::error_code ec;
189 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
190 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
191 {
192 std::filesystem::remove_all(loc, ec);
193 if (ec)
194 {
195 res.result(boost::beast::http::status::internal_server_error);
196 res.jsonValue["Description"] = internalServerError;
197 BMCWEB_LOG_DEBUG << "deleteConfigFiles: Failed to delete the "
198 "config files directory. ec : "
199 << ec;
200 }
201 }
202 res.end();
asmithakarun1c7b07c2019-09-09 03:42:59 -0500203}
204
Ed Tanous02379d32020-09-15 21:15:44 -0700205inline void getLockServiceData(crow::Response& res)
Ratan Gupta734a1c32019-12-14 11:53:48 +0530206{
207 res.jsonValue["@odata.type"] = "#LockService.v1_0_0.LockService";
208 res.jsonValue["@odata.id"] = "/ibm/v1/HMC/LockService/";
209 res.jsonValue["Id"] = "LockService";
210 res.jsonValue["Name"] = "LockService";
211
212 res.jsonValue["Actions"]["#LockService.AcquireLock"] = {
213 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock"}};
214 res.jsonValue["Actions"]["#LockService.ReleaseLock"] = {
215 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock"}};
216 res.jsonValue["Actions"]["#LockService.GetLockList"] = {
217 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList"}};
218 res.end();
219}
220
Ed Tanous02379d32020-09-15 21:15:44 -0700221inline void handleFileGet(crow::Response& res, const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500222{
223 BMCWEB_LOG_DEBUG << "HandleGet on SaveArea files on path: " << fileID;
224 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area/" +
225 fileID);
226 if (!std::filesystem::exists(loc))
227 {
228 BMCWEB_LOG_ERROR << loc << "Not found";
229 res.result(boost::beast::http::status::not_found);
230 res.jsonValue["Description"] = resourceNotFoundMsg;
231 return;
232 }
233
234 std::ifstream readfile(loc.string());
235 if (!readfile)
236 {
237 BMCWEB_LOG_ERROR << loc.string() << "Not found";
238 res.result(boost::beast::http::status::not_found);
239 res.jsonValue["Description"] = resourceNotFoundMsg;
240 return;
241 }
242
243 std::string contentDispositionParam =
244 "attachment; filename=\"" + fileID + "\"";
245 res.addHeader("Content-Disposition", contentDispositionParam);
246 std::string fileData;
247 fileData = {std::istreambuf_iterator<char>(readfile),
248 std::istreambuf_iterator<char>()};
249 res.jsonValue["Data"] = fileData;
250 return;
251}
252
Ed Tanous02379d32020-09-15 21:15:44 -0700253inline void handleFileDelete(crow::Response& res, const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500254{
255 std::string filePath("/var/lib/obmc/bmc-console-mgmt/save-area/" + fileID);
256 BMCWEB_LOG_DEBUG << "Removing the file : " << filePath << "\n";
257
Ed Tanous2c70f802020-09-28 14:29:23 -0700258 std::ifstream fileOpen(filePath.c_str());
259 if (static_cast<bool>(fileOpen))
asmithakarun1c7b07c2019-09-09 03:42:59 -0500260 if (remove(filePath.c_str()) == 0)
261 {
262 BMCWEB_LOG_DEBUG << "File removed!\n";
263 res.jsonValue["Description"] = "File Deleted";
264 }
265 else
266 {
267 BMCWEB_LOG_ERROR << "File not removed!\n";
268 res.result(boost::beast::http::status::internal_server_error);
269 res.jsonValue["Description"] = internalServerError;
270 }
271 else
272 {
273 BMCWEB_LOG_ERROR << "File not found!\n";
Sunitha Harish97b0e432019-11-21 04:59:29 -0600274 res.result(boost::beast::http::status::not_found);
275 res.jsonValue["Description"] = resourceNotFoundMsg;
276 }
277 return;
278}
279
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500280inline void handleBroadcastService(const crow::Request& req,
281 crow::Response& res)
282{
283 std::string broadcastMsg;
284
285 if (!redfish::json_util::readJson(req, res, "Message", broadcastMsg))
286 {
287 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
288 res.result(boost::beast::http::status::bad_request);
289 return;
290 }
291 if (broadcastMsg.size() > maxBroadcastMsgSize)
292 {
293 BMCWEB_LOG_ERROR << "Message size exceeds maximum allowed size[1KB]";
294 res.result(boost::beast::http::status::bad_request);
295 return;
296 }
297 redfish::EventServiceManager::getInstance().sendBroadcastMsg(broadcastMsg);
298 res.end();
299 return;
300}
301
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500302inline void handleFileUrl(const crow::Request& req, crow::Response& res,
303 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600304{
Ed Tanousb41187f2019-10-24 16:30:02 -0700305 if (req.method() == boost::beast::http::verb::put)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600306 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500307 handleFilePut(req, res, fileID);
Sunitha Harish97b0e432019-11-21 04:59:29 -0600308 res.end();
309 return;
310 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700311 if (req.method() == boost::beast::http::verb::get)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500312 {
313 handleFileGet(res, fileID);
314 res.end();
315 return;
316 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700317 if (req.method() == boost::beast::http::verb::delete_)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500318 {
319 handleFileDelete(res, fileID);
320 res.end();
321 return;
322 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600323}
Ratan Gupta453fed02019-12-14 09:39:47 +0530324
Ed Tanous02379d32020-09-15 21:15:44 -0700325inline void handleAcquireLockAPI(const crow::Request& req, crow::Response& res,
326 std::vector<nlohmann::json> body)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530327{
328 LockRequests lockRequestStructure;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500329 for (auto& element : body)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530330 {
331 std::string lockType;
332 uint64_t resourceId;
333
334 SegmentFlags segInfo;
335 std::vector<nlohmann::json> segmentFlags;
336
337 if (!redfish::json_util::readJson(element, res, "LockType", lockType,
338 "ResourceID", resourceId,
339 "SegmentFlags", segmentFlags))
340 {
341 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
342 res.result(boost::beast::http::status::bad_request);
343 res.end();
344 return;
345 }
346 BMCWEB_LOG_DEBUG << lockType;
347 BMCWEB_LOG_DEBUG << resourceId;
348
349 BMCWEB_LOG_DEBUG << "Segment Flags are present";
350
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500351 for (auto& e : segmentFlags)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530352 {
353 std::string lockFlags;
354 uint32_t segmentLength;
355
356 if (!redfish::json_util::readJson(e, res, "LockFlag", lockFlags,
357 "SegmentLength", segmentLength))
358 {
359 res.result(boost::beast::http::status::bad_request);
360 res.end();
361 return;
362 }
363
364 BMCWEB_LOG_DEBUG << "Lockflag : " << lockFlags;
365 BMCWEB_LOG_DEBUG << "SegmentLength : " << segmentLength;
366
367 segInfo.push_back(std::make_pair(lockFlags, segmentLength));
368 }
Manojkiran Eda566329e2020-05-22 12:36:17 +0530369 lockRequestStructure.push_back(
370 make_tuple(req.session->uniqueId, req.session->clientId, lockType,
371 resourceId, segInfo));
manojkiraneda0b631ae2019-12-03 17:54:28 +0530372 }
373
374 // print lock request into journal
375
Ed Tanous4e087512020-09-28 18:41:25 -0700376 for (auto& i : lockRequestStructure)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530377 {
Ed Tanous4e087512020-09-28 18:41:25 -0700378 BMCWEB_LOG_DEBUG << std::get<0>(i);
379 BMCWEB_LOG_DEBUG << std::get<1>(i);
380 BMCWEB_LOG_DEBUG << std::get<2>(i);
381 BMCWEB_LOG_DEBUG << std::get<3>(i);
manojkiraneda0b631ae2019-12-03 17:54:28 +0530382
Ed Tanous4e087512020-09-28 18:41:25 -0700383 for (const auto& p : std::get<4>(i))
manojkiraneda0b631ae2019-12-03 17:54:28 +0530384 {
385 BMCWEB_LOG_DEBUG << p.first << ", " << p.second;
386 }
387 }
388
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500389 const LockRequests& t = lockRequestStructure;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530390
Ratan Gupta07386c62019-12-14 14:06:09 +0530391 auto varAcquireLock = crow::ibm_mc_lock::Lock::getInstance().acquireLock(t);
manojkiraneda0b631ae2019-12-03 17:54:28 +0530392
393 if (varAcquireLock.first)
394 {
395 // Either validity failure of there is a conflict with itself
396
397 auto validityStatus =
398 std::get<std::pair<bool, int>>(varAcquireLock.second);
399
400 if ((!validityStatus.first) && (validityStatus.second == 0))
401 {
402 BMCWEB_LOG_DEBUG << "Not a Valid record";
403 BMCWEB_LOG_DEBUG << "Bad json in request";
404 res.result(boost::beast::http::status::bad_request);
405 res.end();
406 return;
407 }
408 if (validityStatus.first && (validityStatus.second == 1))
409 {
410 BMCWEB_LOG_DEBUG << "There is a conflict within itself";
411 res.result(boost::beast::http::status::bad_request);
412 res.end();
413 return;
414 }
415 }
416 else
417 {
418 auto conflictStatus =
419 std::get<crow::ibm_mc_lock::Rc>(varAcquireLock.second);
420 if (!conflictStatus.first)
421 {
422 BMCWEB_LOG_DEBUG << "There is no conflict with the locktable";
423 res.result(boost::beast::http::status::ok);
424
425 auto var = std::get<uint32_t>(conflictStatus.second);
426 nlohmann::json returnJson;
427 returnJson["id"] = var;
428 res.jsonValue["TransactionID"] = var;
429 res.end();
430 return;
431 }
432 else
433 {
434 BMCWEB_LOG_DEBUG << "There is a conflict with the lock table";
435 res.result(boost::beast::http::status::conflict);
436 auto var = std::get<std::pair<uint32_t, LockRequest>>(
437 conflictStatus.second);
438 nlohmann::json returnJson, segments;
439 nlohmann::json myarray = nlohmann::json::array();
440 returnJson["TransactionID"] = var.first;
441 returnJson["SessionID"] = std::get<0>(var.second);
442 returnJson["HMCID"] = std::get<1>(var.second);
443 returnJson["LockType"] = std::get<2>(var.second);
444 returnJson["ResourceID"] = std::get<3>(var.second);
445
Ed Tanous4e087512020-09-28 18:41:25 -0700446 for (auto& i : std::get<4>(var.second))
manojkiraneda0b631ae2019-12-03 17:54:28 +0530447 {
Ed Tanous4e087512020-09-28 18:41:25 -0700448 segments["LockFlag"] = i.first;
449 segments["SegmentLength"] = i.second;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530450 myarray.push_back(segments);
451 }
452
453 returnJson["SegmentFlags"] = myarray;
454
455 res.jsonValue["Record"] = returnJson;
456 res.end();
457 return;
458 }
459 }
460}
Ed Tanous02379d32020-09-15 21:15:44 -0700461inline void handleRelaseAllAPI(const crow::Request& req, crow::Response& res)
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530462{
463 crow::ibm_mc_lock::Lock::getInstance().releaseLock(req.session->uniqueId);
464 res.result(boost::beast::http::status::ok);
465 res.end();
466 return;
467}
manojkiraneda0b631ae2019-12-03 17:54:28 +0530468
Ed Tanous02379d32020-09-15 21:15:44 -0700469inline void
470 handleReleaseLockAPI(const crow::Request& req, crow::Response& res,
471 const std::vector<uint32_t>& listTransactionIds)
manojkiraneda3b6dea62019-12-13 17:05:36 +0530472{
473 BMCWEB_LOG_DEBUG << listTransactionIds.size();
474 BMCWEB_LOG_DEBUG << "Data is present";
Ed Tanous4e087512020-09-28 18:41:25 -0700475 for (unsigned int listTransactionId : listTransactionIds)
manojkiraneda3b6dea62019-12-13 17:05:36 +0530476 {
Ed Tanous4e087512020-09-28 18:41:25 -0700477 BMCWEB_LOG_DEBUG << listTransactionId;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530478 }
479
manojkiraneda3b6dea62019-12-13 17:05:36 +0530480 // validate the request ids
481
Ratan Gupta07386c62019-12-14 14:06:09 +0530482 auto varReleaselock = crow::ibm_mc_lock::Lock::getInstance().releaseLock(
Manojkiran Eda566329e2020-05-22 12:36:17 +0530483 listTransactionIds,
484 std::make_pair(req.session->clientId, req.session->uniqueId));
manojkiraneda3b6dea62019-12-13 17:05:36 +0530485
486 if (!varReleaselock.first)
487 {
488 // validation Failed
489 res.result(boost::beast::http::status::bad_request);
490 res.end();
491 return;
492 }
493 else
494 {
495 auto statusRelease =
496 std::get<crow::ibm_mc_lock::RcRelaseLock>(varReleaselock.second);
497 if (statusRelease.first)
498 {
499 // The current hmc owns all the locks, so we already released
500 // them
501 res.result(boost::beast::http::status::ok);
502 res.end();
503 return;
504 }
505
506 else
507 {
508 // valid rid, but the current hmc does not own all the locks
509 BMCWEB_LOG_DEBUG << "Current HMC does not own all the locks";
510 res.result(boost::beast::http::status::unauthorized);
511
512 auto var = statusRelease.second;
513 nlohmann::json returnJson, segments;
514 nlohmann::json myArray = nlohmann::json::array();
515 returnJson["TransactionID"] = var.first;
516 returnJson["SessionID"] = std::get<0>(var.second);
517 returnJson["HMCID"] = std::get<1>(var.second);
518 returnJson["LockType"] = std::get<2>(var.second);
519 returnJson["ResourceID"] = std::get<3>(var.second);
520
Ed Tanous4e087512020-09-28 18:41:25 -0700521 for (auto& i : std::get<4>(var.second))
manojkiraneda3b6dea62019-12-13 17:05:36 +0530522 {
Ed Tanous4e087512020-09-28 18:41:25 -0700523 segments["LockFlag"] = i.first;
524 segments["SegmentLength"] = i.second;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530525 myArray.push_back(segments);
526 }
527
528 returnJson["SegmentFlags"] = myArray;
529 res.jsonValue["Record"] = returnJson;
530 res.end();
531 return;
532 }
533 }
534}
535
Ed Tanous02379d32020-09-15 21:15:44 -0700536inline void handleGetLockListAPI(crow::Response& res,
537 const ListOfSessionIds& listSessionIds)
manojkiraneda402b5712019-12-13 17:07:09 +0530538{
539 BMCWEB_LOG_DEBUG << listSessionIds.size();
540
Ratan Gupta07386c62019-12-14 14:06:09 +0530541 auto status =
542 crow::ibm_mc_lock::Lock::getInstance().getLockList(listSessionIds);
manojkiraneda402b5712019-12-13 17:07:09 +0530543 auto var = std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
544
545 nlohmann::json lockRecords = nlohmann::json::array();
546
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500547 for (const auto& transactionId : var)
manojkiraneda402b5712019-12-13 17:07:09 +0530548 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500549 for (const auto& lockRecord : transactionId.second)
manojkiraneda402b5712019-12-13 17:07:09 +0530550 {
551 nlohmann::json returnJson;
552
553 returnJson["TransactionID"] = transactionId.first;
554 returnJson["SessionID"] = std::get<0>(lockRecord);
555 returnJson["HMCID"] = std::get<1>(lockRecord);
556 returnJson["LockType"] = std::get<2>(lockRecord);
557 returnJson["ResourceID"] = std::get<3>(lockRecord);
558
559 nlohmann::json segments;
560 nlohmann::json segmentInfoArray = nlohmann::json::array();
561
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500562 for (const auto& segment : std::get<4>(lockRecord))
manojkiraneda402b5712019-12-13 17:07:09 +0530563 {
564 segments["LockFlag"] = segment.first;
565 segments["SegmentLength"] = segment.second;
566 segmentInfoArray.push_back(segments);
567 }
568
569 returnJson["SegmentFlags"] = segmentInfoArray;
570 lockRecords.push_back(returnJson);
571 }
572 }
573 res.result(boost::beast::http::status::ok);
574 res.jsonValue["Records"] = lockRecords;
575 res.end();
576}
577
Ed Tanous02379d32020-09-15 21:15:44 -0700578inline void requestRoutes(App& app)
Ratan Gupta453fed02019-12-14 09:39:47 +0530579{
580
581 // allowed only for admin
582 BMCWEB_ROUTE(app, "/ibm/v1/")
Ed Tanous23a21a12020-07-25 04:45:05 +0000583 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700584 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000585 [](const crow::Request&, crow::Response& res) {
Ratan Gupta453fed02019-12-14 09:39:47 +0530586 res.jsonValue["@odata.type"] =
587 "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
588 res.jsonValue["@odata.id"] = "/ibm/v1/";
589 res.jsonValue["Id"] = "IBM Rest RootService";
590 res.jsonValue["Name"] = "IBM Service Root";
591 res.jsonValue["ConfigFiles"] = {
592 {"@odata.id", "/ibm/v1/Host/ConfigFiles"}};
593 res.jsonValue["LockService"] = {
594 {"@odata.id", "/ibm/v1/HMC/LockService"}};
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500595 res.jsonValue["BroadcastService"] = {
596 {"@odata.id", "/ibm/v1/HMC/BroadcastService"}};
Ratan Gupta453fed02019-12-14 09:39:47 +0530597 res.end();
598 });
Sunitha Harish97b0e432019-11-21 04:59:29 -0600599
Ratan Guptad3630cb2019-12-14 11:21:35 +0530600 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
Ed Tanous23a21a12020-07-25 04:45:05 +0000601 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700602 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000603 [](const crow::Request&, crow::Response& res) {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530604 handleConfigFileList(res);
605 });
606
607 BMCWEB_ROUTE(app,
Sunitha Harishe56f2542020-07-22 02:38:59 -0500608 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
Ed Tanous23a21a12020-07-25 04:45:05 +0000609 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700610 .methods(boost::beast::http::verb::post)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000611 [](const crow::Request&, crow::Response& res) {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530612 deleteConfigFiles(res);
613 });
614
asmithakarun1c7b07c2019-09-09 03:42:59 -0500615 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<path>")
Ed Tanous23a21a12020-07-25 04:45:05 +0000616 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700617 .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
618 boost::beast::http::verb::delete_)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500619 [](const crow::Request& req, crow::Response& res,
620 const std::string& path) { handleFileUrl(req, res, path); });
Ratan Gupta734a1c32019-12-14 11:53:48 +0530621
622 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService")
Ed Tanous23a21a12020-07-25 04:45:05 +0000623 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700624 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000625 [](const crow::Request&, crow::Response& res) {
Ratan Gupta734a1c32019-12-14 11:53:48 +0530626 getLockServiceData(res);
627 });
manojkiraneda0b631ae2019-12-03 17:54:28 +0530628
629 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock")
Ed Tanous23a21a12020-07-25 04:45:05 +0000630 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700631 .methods(boost::beast::http::verb::post)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500632 [](const crow::Request& req, crow::Response& res) {
manojkiraneda0b631ae2019-12-03 17:54:28 +0530633 std::vector<nlohmann::json> body;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530634 if (!redfish::json_util::readJson(req, res, "Request", body))
635 {
636 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
637 res.result(boost::beast::http::status::bad_request);
638 res.end();
639 return;
640 }
641 handleAcquireLockAPI(req, res, body);
642 });
manojkiraneda3b6dea62019-12-13 17:05:36 +0530643 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
Ed Tanous23a21a12020-07-25 04:45:05 +0000644 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700645 .methods(boost::beast::http::verb::post)([](const crow::Request& req,
646 crow::Response& res) {
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530647 std::string type;
648 std::vector<uint32_t> listTransactionIds;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530649
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530650 if (!redfish::json_util::readJson(req, res, "Type", type,
651 "TransactionIDs",
652 listTransactionIds))
653 {
654 res.result(boost::beast::http::status::bad_request);
655 res.end();
656 return;
657 }
658 if (type == "Transaction")
659 {
manojkiraneda3b6dea62019-12-13 17:05:36 +0530660 handleReleaseLockAPI(req, res, listTransactionIds);
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530661 }
662 else if (type == "Session")
663 {
664 handleRelaseAllAPI(req, res);
665 }
666 else
667 {
668 BMCWEB_LOG_DEBUG << " Value of Type : " << type
669 << "is Not a Valid key";
670 redfish::messages::propertyValueNotInList(res, type, "Type");
671 }
672 });
manojkiraneda402b5712019-12-13 17:07:09 +0530673 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList")
Ed Tanous23a21a12020-07-25 04:45:05 +0000674 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700675 .methods(boost::beast::http::verb::post)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500676 [](const crow::Request& req, crow::Response& res) {
manojkiraneda402b5712019-12-13 17:07:09 +0530677 ListOfSessionIds listSessionIds;
678
679 if (!redfish::json_util::readJson(req, res, "SessionIDs",
680 listSessionIds))
681 {
682 res.result(boost::beast::http::status::bad_request);
683 res.end();
684 return;
685 }
Ed Tanouscb13a392020-07-25 19:02:03 +0000686 handleGetLockListAPI(res, listSessionIds);
manojkiraneda402b5712019-12-13 17:07:09 +0530687 });
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500688
689 BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
Ed Tanous23a21a12020-07-25 04:45:05 +0000690 .privileges({"ConfigureComponents", "ConfigureManager"})
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500691 .methods(boost::beast::http::verb::post)(
692 [](const crow::Request& req, crow::Response& res) {
693 handleBroadcastService(req, res);
694 });
Ratan Gupta453fed02019-12-14 09:39:47 +0530695}
696
697} // namespace ibm_mc
698} // namespace crow