blob: b0e57eddb791cf6f3ea3a5dd91395c4d409d1484 [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 }
Ed Tanous3174e4d2020-10-07 11:41:22 -070094 BMCWEB_LOG_DEBUG << "Not a multipart/form-data. Continue..";
asmithakarun1c7b07c2019-09-09 03:42:59 -050095
96 BMCWEB_LOG_DEBUG
97 << "handleIbmPut: Request to create/update the save-area file";
98 if (!createSaveAreaPath(res))
Sunitha Harish97b0e432019-11-21 04:59:29 -060099 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500100 res.result(boost::beast::http::status::not_found);
101 res.jsonValue["Description"] = resourceNotFoundMsg;
102 return;
103 }
104 // Create the file
105 std::ofstream file;
106 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
107 loc /= fileID;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600108
Ed Tanous3174e4d2020-10-07 11:41:22 -0700109 const std::string& data = req.body;
asmithakarun1c7b07c2019-09-09 03:42:59 -0500110 BMCWEB_LOG_DEBUG << "data capaticty : " << data.capacity();
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500111 if (data.capacity() > maxSaveareaFileSize)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500112 {
113 res.result(boost::beast::http::status::bad_request);
114 res.jsonValue["Description"] =
Ratan Guptae46946a2020-05-11 13:22:59 +0530115 "File size exceeds maximum allowed size[500KB]";
asmithakarun1c7b07c2019-09-09 03:42:59 -0500116 return;
117 }
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500118 BMCWEB_LOG_DEBUG << "Writing to the file: " << loc;
119
120 bool fileExists = false;
121 if (std::filesystem::exists(loc))
122 {
123 fileExists = true;
124 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500125 file.open(loc, std::ofstream::out);
126 if (file.fail())
127 {
128 BMCWEB_LOG_DEBUG << "Error while opening the file for writing";
129 res.result(boost::beast::http::status::internal_server_error);
130 res.jsonValue["Description"] = "Error while creating the file";
131 return;
Sunitha Harish97b0e432019-11-21 04:59:29 -0600132 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700133 file << data;
134 std::string origin = "/ibm/v1/Host/ConfigFiles/" + fileID;
135 // Push an event
136 if (fileExists)
137 {
138 BMCWEB_LOG_DEBUG << "config file is updated";
139 res.jsonValue["Description"] = "File Updated";
140
141 redfish::EventServiceManager::getInstance().sendEvent(
142 redfish::messages::resourceChanged(), origin, "IBMConfigFile");
143 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600144 else
145 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700146 BMCWEB_LOG_DEBUG << "config file is created";
147 res.jsonValue["Description"] = "File Created";
Asmitha Karunanithi10693fa2020-07-27 02:27:49 -0500148
Ed Tanous3174e4d2020-10-07 11:41:22 -0700149 redfish::EventServiceManager::getInstance().sendEvent(
150 redfish::messages::resourceCreated(), origin, "IBMConfigFile");
asmithakarun1c7b07c2019-09-09 03:42:59 -0500151 }
Ratan Guptad3630cb2019-12-14 11:21:35 +0530152}
asmithakarun1c7b07c2019-09-09 03:42:59 -0500153
Ed Tanous02379d32020-09-15 21:15:44 -0700154inline void handleConfigFileList(crow::Response& res)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530155{
156 std::vector<std::string> pathObjList;
157 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
158 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
159 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500160 for (const auto& file : std::filesystem::directory_iterator(loc))
Ratan Guptad3630cb2019-12-14 11:21:35 +0530161 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700162 const std::filesystem::path& pathObj = file.path();
Ratan Guptad3630cb2019-12-14 11:21:35 +0530163 pathObjList.push_back("/ibm/v1/Host/ConfigFiles/" +
164 pathObj.filename().string());
165 }
166 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500167 res.jsonValue["@odata.type"] = "#IBMConfigFile.v1_0_0.IBMConfigFile";
Ratan Guptad3630cb2019-12-14 11:21:35 +0530168 res.jsonValue["@odata.id"] = "/ibm/v1/Host/ConfigFiles/";
169 res.jsonValue["Id"] = "ConfigFiles";
170 res.jsonValue["Name"] = "ConfigFiles";
171
172 res.jsonValue["Members"] = std::move(pathObjList);
Sunitha Harishe56f2542020-07-22 02:38:59 -0500173 res.jsonValue["Actions"]["#IBMConfigFiles.DeleteAll"] = {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530174 {"target",
Sunitha Harishe56f2542020-07-22 02:38:59 -0500175 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll"}};
Ratan Guptad3630cb2019-12-14 11:21:35 +0530176 res.end();
177}
178
Ed Tanous02379d32020-09-15 21:15:44 -0700179inline void deleteConfigFiles(crow::Response& res)
Ratan Guptad3630cb2019-12-14 11:21:35 +0530180{
181 std::vector<std::string> pathObjList;
182 std::error_code ec;
183 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area");
184 if (std::filesystem::exists(loc) && std::filesystem::is_directory(loc))
185 {
186 std::filesystem::remove_all(loc, ec);
187 if (ec)
188 {
189 res.result(boost::beast::http::status::internal_server_error);
190 res.jsonValue["Description"] = internalServerError;
191 BMCWEB_LOG_DEBUG << "deleteConfigFiles: Failed to delete the "
192 "config files directory. ec : "
193 << ec;
194 }
195 }
196 res.end();
asmithakarun1c7b07c2019-09-09 03:42:59 -0500197}
198
Ed Tanous02379d32020-09-15 21:15:44 -0700199inline void getLockServiceData(crow::Response& res)
Ratan Gupta734a1c32019-12-14 11:53:48 +0530200{
201 res.jsonValue["@odata.type"] = "#LockService.v1_0_0.LockService";
202 res.jsonValue["@odata.id"] = "/ibm/v1/HMC/LockService/";
203 res.jsonValue["Id"] = "LockService";
204 res.jsonValue["Name"] = "LockService";
205
206 res.jsonValue["Actions"]["#LockService.AcquireLock"] = {
207 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock"}};
208 res.jsonValue["Actions"]["#LockService.ReleaseLock"] = {
209 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock"}};
210 res.jsonValue["Actions"]["#LockService.GetLockList"] = {
211 {"target", "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList"}};
212 res.end();
213}
214
Ed Tanous02379d32020-09-15 21:15:44 -0700215inline void handleFileGet(crow::Response& res, const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500216{
217 BMCWEB_LOG_DEBUG << "HandleGet on SaveArea files on path: " << fileID;
218 std::filesystem::path loc("/var/lib/obmc/bmc-console-mgmt/save-area/" +
219 fileID);
220 if (!std::filesystem::exists(loc))
221 {
222 BMCWEB_LOG_ERROR << loc << "Not found";
223 res.result(boost::beast::http::status::not_found);
224 res.jsonValue["Description"] = resourceNotFoundMsg;
225 return;
226 }
227
228 std::ifstream readfile(loc.string());
229 if (!readfile)
230 {
231 BMCWEB_LOG_ERROR << loc.string() << "Not found";
232 res.result(boost::beast::http::status::not_found);
233 res.jsonValue["Description"] = resourceNotFoundMsg;
234 return;
235 }
236
237 std::string contentDispositionParam =
238 "attachment; filename=\"" + fileID + "\"";
239 res.addHeader("Content-Disposition", contentDispositionParam);
240 std::string fileData;
241 fileData = {std::istreambuf_iterator<char>(readfile),
242 std::istreambuf_iterator<char>()};
243 res.jsonValue["Data"] = fileData;
244 return;
245}
246
Ed Tanous02379d32020-09-15 21:15:44 -0700247inline void handleFileDelete(crow::Response& res, const std::string& fileID)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500248{
249 std::string filePath("/var/lib/obmc/bmc-console-mgmt/save-area/" + fileID);
250 BMCWEB_LOG_DEBUG << "Removing the file : " << filePath << "\n";
251
Ed Tanous2c70f802020-09-28 14:29:23 -0700252 std::ifstream fileOpen(filePath.c_str());
253 if (static_cast<bool>(fileOpen))
Ed Tanous3174e4d2020-10-07 11:41:22 -0700254 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500255 if (remove(filePath.c_str()) == 0)
256 {
257 BMCWEB_LOG_DEBUG << "File removed!\n";
258 res.jsonValue["Description"] = "File Deleted";
259 }
260 else
261 {
262 BMCWEB_LOG_ERROR << "File not removed!\n";
263 res.result(boost::beast::http::status::internal_server_error);
264 res.jsonValue["Description"] = internalServerError;
265 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700266 }
asmithakarun1c7b07c2019-09-09 03:42:59 -0500267 else
268 {
269 BMCWEB_LOG_ERROR << "File not found!\n";
Sunitha Harish97b0e432019-11-21 04:59:29 -0600270 res.result(boost::beast::http::status::not_found);
271 res.jsonValue["Description"] = resourceNotFoundMsg;
272 }
273 return;
274}
275
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500276inline void handleBroadcastService(const crow::Request& req,
277 crow::Response& res)
278{
279 std::string broadcastMsg;
280
281 if (!redfish::json_util::readJson(req, res, "Message", broadcastMsg))
282 {
283 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
284 res.result(boost::beast::http::status::bad_request);
285 return;
286 }
287 if (broadcastMsg.size() > maxBroadcastMsgSize)
288 {
289 BMCWEB_LOG_ERROR << "Message size exceeds maximum allowed size[1KB]";
290 res.result(boost::beast::http::status::bad_request);
291 return;
292 }
293 redfish::EventServiceManager::getInstance().sendBroadcastMsg(broadcastMsg);
294 res.end();
295 return;
296}
297
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500298inline void handleFileUrl(const crow::Request& req, crow::Response& res,
299 const std::string& fileID)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600300{
Ed Tanousb41187f2019-10-24 16:30:02 -0700301 if (req.method() == boost::beast::http::verb::put)
Sunitha Harish97b0e432019-11-21 04:59:29 -0600302 {
asmithakarun1c7b07c2019-09-09 03:42:59 -0500303 handleFilePut(req, res, fileID);
Sunitha Harish97b0e432019-11-21 04:59:29 -0600304 res.end();
305 return;
306 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700307 if (req.method() == boost::beast::http::verb::get)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500308 {
309 handleFileGet(res, fileID);
310 res.end();
311 return;
312 }
Ed Tanousb41187f2019-10-24 16:30:02 -0700313 if (req.method() == boost::beast::http::verb::delete_)
asmithakarun1c7b07c2019-09-09 03:42:59 -0500314 {
315 handleFileDelete(res, fileID);
316 res.end();
317 return;
318 }
Sunitha Harish97b0e432019-11-21 04:59:29 -0600319}
Ratan Gupta453fed02019-12-14 09:39:47 +0530320
Ed Tanous02379d32020-09-15 21:15:44 -0700321inline void handleAcquireLockAPI(const crow::Request& req, crow::Response& res,
322 std::vector<nlohmann::json> body)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530323{
324 LockRequests lockRequestStructure;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500325 for (auto& element : body)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530326 {
327 std::string lockType;
328 uint64_t resourceId;
329
330 SegmentFlags segInfo;
331 std::vector<nlohmann::json> segmentFlags;
332
333 if (!redfish::json_util::readJson(element, res, "LockType", lockType,
334 "ResourceID", resourceId,
335 "SegmentFlags", segmentFlags))
336 {
337 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
338 res.result(boost::beast::http::status::bad_request);
339 res.end();
340 return;
341 }
342 BMCWEB_LOG_DEBUG << lockType;
343 BMCWEB_LOG_DEBUG << resourceId;
344
345 BMCWEB_LOG_DEBUG << "Segment Flags are present";
346
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500347 for (auto& e : segmentFlags)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530348 {
349 std::string lockFlags;
350 uint32_t segmentLength;
351
352 if (!redfish::json_util::readJson(e, res, "LockFlag", lockFlags,
353 "SegmentLength", segmentLength))
354 {
355 res.result(boost::beast::http::status::bad_request);
356 res.end();
357 return;
358 }
359
360 BMCWEB_LOG_DEBUG << "Lockflag : " << lockFlags;
361 BMCWEB_LOG_DEBUG << "SegmentLength : " << segmentLength;
362
363 segInfo.push_back(std::make_pair(lockFlags, segmentLength));
364 }
Manojkiran Eda566329e2020-05-22 12:36:17 +0530365 lockRequestStructure.push_back(
366 make_tuple(req.session->uniqueId, req.session->clientId, lockType,
367 resourceId, segInfo));
manojkiraneda0b631ae2019-12-03 17:54:28 +0530368 }
369
370 // print lock request into journal
371
Ed Tanous4e087512020-09-28 18:41:25 -0700372 for (auto& i : lockRequestStructure)
manojkiraneda0b631ae2019-12-03 17:54:28 +0530373 {
Ed Tanous4e087512020-09-28 18:41:25 -0700374 BMCWEB_LOG_DEBUG << std::get<0>(i);
375 BMCWEB_LOG_DEBUG << std::get<1>(i);
376 BMCWEB_LOG_DEBUG << std::get<2>(i);
377 BMCWEB_LOG_DEBUG << std::get<3>(i);
manojkiraneda0b631ae2019-12-03 17:54:28 +0530378
Ed Tanous4e087512020-09-28 18:41:25 -0700379 for (const auto& p : std::get<4>(i))
manojkiraneda0b631ae2019-12-03 17:54:28 +0530380 {
381 BMCWEB_LOG_DEBUG << p.first << ", " << p.second;
382 }
383 }
384
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500385 const LockRequests& t = lockRequestStructure;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530386
Ratan Gupta07386c62019-12-14 14:06:09 +0530387 auto varAcquireLock = crow::ibm_mc_lock::Lock::getInstance().acquireLock(t);
manojkiraneda0b631ae2019-12-03 17:54:28 +0530388
389 if (varAcquireLock.first)
390 {
391 // Either validity failure of there is a conflict with itself
392
393 auto validityStatus =
394 std::get<std::pair<bool, int>>(varAcquireLock.second);
395
396 if ((!validityStatus.first) && (validityStatus.second == 0))
397 {
398 BMCWEB_LOG_DEBUG << "Not a Valid record";
399 BMCWEB_LOG_DEBUG << "Bad json in request";
400 res.result(boost::beast::http::status::bad_request);
401 res.end();
402 return;
403 }
404 if (validityStatus.first && (validityStatus.second == 1))
405 {
406 BMCWEB_LOG_DEBUG << "There is a conflict within itself";
407 res.result(boost::beast::http::status::bad_request);
408 res.end();
409 return;
410 }
411 }
412 else
413 {
414 auto conflictStatus =
415 std::get<crow::ibm_mc_lock::Rc>(varAcquireLock.second);
416 if (!conflictStatus.first)
417 {
418 BMCWEB_LOG_DEBUG << "There is no conflict with the locktable";
419 res.result(boost::beast::http::status::ok);
420
421 auto var = std::get<uint32_t>(conflictStatus.second);
422 nlohmann::json returnJson;
423 returnJson["id"] = var;
424 res.jsonValue["TransactionID"] = var;
425 res.end();
426 return;
427 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700428 BMCWEB_LOG_DEBUG << "There is a conflict with the lock table";
429 res.result(boost::beast::http::status::conflict);
430 auto var =
431 std::get<std::pair<uint32_t, LockRequest>>(conflictStatus.second);
432 nlohmann::json returnJson, segments;
433 nlohmann::json myarray = nlohmann::json::array();
434 returnJson["TransactionID"] = var.first;
435 returnJson["SessionID"] = std::get<0>(var.second);
436 returnJson["HMCID"] = std::get<1>(var.second);
437 returnJson["LockType"] = std::get<2>(var.second);
438 returnJson["ResourceID"] = std::get<3>(var.second);
439
440 for (auto& i : std::get<4>(var.second))
manojkiraneda0b631ae2019-12-03 17:54:28 +0530441 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700442 segments["LockFlag"] = i.first;
443 segments["SegmentLength"] = i.second;
444 myarray.push_back(segments);
manojkiraneda0b631ae2019-12-03 17:54:28 +0530445 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700446
447 returnJson["SegmentFlags"] = myarray;
448
449 res.jsonValue["Record"] = returnJson;
450 res.end();
451 return;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530452 }
453}
Ed Tanous02379d32020-09-15 21:15:44 -0700454inline void handleRelaseAllAPI(const crow::Request& req, crow::Response& res)
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530455{
456 crow::ibm_mc_lock::Lock::getInstance().releaseLock(req.session->uniqueId);
457 res.result(boost::beast::http::status::ok);
458 res.end();
459 return;
460}
manojkiraneda0b631ae2019-12-03 17:54:28 +0530461
Ed Tanous02379d32020-09-15 21:15:44 -0700462inline void
463 handleReleaseLockAPI(const crow::Request& req, crow::Response& res,
464 const std::vector<uint32_t>& listTransactionIds)
manojkiraneda3b6dea62019-12-13 17:05:36 +0530465{
466 BMCWEB_LOG_DEBUG << listTransactionIds.size();
467 BMCWEB_LOG_DEBUG << "Data is present";
Ed Tanous4e087512020-09-28 18:41:25 -0700468 for (unsigned int listTransactionId : listTransactionIds)
manojkiraneda3b6dea62019-12-13 17:05:36 +0530469 {
Ed Tanous4e087512020-09-28 18:41:25 -0700470 BMCWEB_LOG_DEBUG << listTransactionId;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530471 }
472
manojkiraneda3b6dea62019-12-13 17:05:36 +0530473 // validate the request ids
474
Ratan Gupta07386c62019-12-14 14:06:09 +0530475 auto varReleaselock = crow::ibm_mc_lock::Lock::getInstance().releaseLock(
Manojkiran Eda566329e2020-05-22 12:36:17 +0530476 listTransactionIds,
477 std::make_pair(req.session->clientId, req.session->uniqueId));
manojkiraneda3b6dea62019-12-13 17:05:36 +0530478
479 if (!varReleaselock.first)
480 {
481 // validation Failed
482 res.result(boost::beast::http::status::bad_request);
483 res.end();
484 return;
485 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700486 auto statusRelease =
487 std::get<crow::ibm_mc_lock::RcRelaseLock>(varReleaselock.second);
488 if (statusRelease.first)
manojkiraneda3b6dea62019-12-13 17:05:36 +0530489 {
Ed Tanous3174e4d2020-10-07 11:41:22 -0700490 // The current hmc owns all the locks, so we already released
491 // them
492 res.result(boost::beast::http::status::ok);
493 res.end();
494 return;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530495 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700496
497 // valid rid, but the current hmc does not own all the locks
498 BMCWEB_LOG_DEBUG << "Current HMC does not own all the locks";
499 res.result(boost::beast::http::status::unauthorized);
500
501 auto var = statusRelease.second;
502 nlohmann::json returnJson, segments;
503 nlohmann::json myArray = nlohmann::json::array();
504 returnJson["TransactionID"] = var.first;
505 returnJson["SessionID"] = std::get<0>(var.second);
506 returnJson["HMCID"] = std::get<1>(var.second);
507 returnJson["LockType"] = std::get<2>(var.second);
508 returnJson["ResourceID"] = std::get<3>(var.second);
509
510 for (auto& i : std::get<4>(var.second))
511 {
512 segments["LockFlag"] = i.first;
513 segments["SegmentLength"] = i.second;
514 myArray.push_back(segments);
515 }
516
517 returnJson["SegmentFlags"] = myArray;
518 res.jsonValue["Record"] = returnJson;
519 res.end();
520 return;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530521}
522
Ed Tanous02379d32020-09-15 21:15:44 -0700523inline void handleGetLockListAPI(crow::Response& res,
524 const ListOfSessionIds& listSessionIds)
manojkiraneda402b5712019-12-13 17:07:09 +0530525{
526 BMCWEB_LOG_DEBUG << listSessionIds.size();
527
Ratan Gupta07386c62019-12-14 14:06:09 +0530528 auto status =
529 crow::ibm_mc_lock::Lock::getInstance().getLockList(listSessionIds);
manojkiraneda402b5712019-12-13 17:07:09 +0530530 auto var = std::get<std::vector<std::pair<uint32_t, LockRequests>>>(status);
531
532 nlohmann::json lockRecords = nlohmann::json::array();
533
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500534 for (const auto& transactionId : var)
manojkiraneda402b5712019-12-13 17:07:09 +0530535 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500536 for (const auto& lockRecord : transactionId.second)
manojkiraneda402b5712019-12-13 17:07:09 +0530537 {
538 nlohmann::json returnJson;
539
540 returnJson["TransactionID"] = transactionId.first;
541 returnJson["SessionID"] = std::get<0>(lockRecord);
542 returnJson["HMCID"] = std::get<1>(lockRecord);
543 returnJson["LockType"] = std::get<2>(lockRecord);
544 returnJson["ResourceID"] = std::get<3>(lockRecord);
545
546 nlohmann::json segments;
547 nlohmann::json segmentInfoArray = nlohmann::json::array();
548
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500549 for (const auto& segment : std::get<4>(lockRecord))
manojkiraneda402b5712019-12-13 17:07:09 +0530550 {
551 segments["LockFlag"] = segment.first;
552 segments["SegmentLength"] = segment.second;
553 segmentInfoArray.push_back(segments);
554 }
555
556 returnJson["SegmentFlags"] = segmentInfoArray;
557 lockRecords.push_back(returnJson);
558 }
559 }
560 res.result(boost::beast::http::status::ok);
561 res.jsonValue["Records"] = lockRecords;
562 res.end();
563}
564
Ed Tanous02379d32020-09-15 21:15:44 -0700565inline void requestRoutes(App& app)
Ratan Gupta453fed02019-12-14 09:39:47 +0530566{
567
568 // allowed only for admin
569 BMCWEB_ROUTE(app, "/ibm/v1/")
Ed Tanous23a21a12020-07-25 04:45:05 +0000570 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700571 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000572 [](const crow::Request&, crow::Response& res) {
Ratan Gupta453fed02019-12-14 09:39:47 +0530573 res.jsonValue["@odata.type"] =
574 "#ibmServiceRoot.v1_0_0.ibmServiceRoot";
575 res.jsonValue["@odata.id"] = "/ibm/v1/";
576 res.jsonValue["Id"] = "IBM Rest RootService";
577 res.jsonValue["Name"] = "IBM Service Root";
578 res.jsonValue["ConfigFiles"] = {
579 {"@odata.id", "/ibm/v1/Host/ConfigFiles"}};
580 res.jsonValue["LockService"] = {
581 {"@odata.id", "/ibm/v1/HMC/LockService"}};
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500582 res.jsonValue["BroadcastService"] = {
583 {"@odata.id", "/ibm/v1/HMC/BroadcastService"}};
Ratan Gupta453fed02019-12-14 09:39:47 +0530584 res.end();
585 });
Sunitha Harish97b0e432019-11-21 04:59:29 -0600586
Ratan Guptad3630cb2019-12-14 11:21:35 +0530587 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles")
Ed Tanous23a21a12020-07-25 04:45:05 +0000588 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700589 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000590 [](const crow::Request&, crow::Response& res) {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530591 handleConfigFileList(res);
592 });
593
594 BMCWEB_ROUTE(app,
Sunitha Harishe56f2542020-07-22 02:38:59 -0500595 "/ibm/v1/Host/ConfigFiles/Actions/IBMConfigFiles.DeleteAll")
Ed Tanous23a21a12020-07-25 04:45:05 +0000596 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700597 .methods(boost::beast::http::verb::post)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000598 [](const crow::Request&, crow::Response& res) {
Ratan Guptad3630cb2019-12-14 11:21:35 +0530599 deleteConfigFiles(res);
600 });
601
asmithakarun1c7b07c2019-09-09 03:42:59 -0500602 BMCWEB_ROUTE(app, "/ibm/v1/Host/ConfigFiles/<path>")
Ed Tanous23a21a12020-07-25 04:45:05 +0000603 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700604 .methods(boost::beast::http::verb::put, boost::beast::http::verb::get,
605 boost::beast::http::verb::delete_)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500606 [](const crow::Request& req, crow::Response& res,
607 const std::string& path) { handleFileUrl(req, res, path); });
Ratan Gupta734a1c32019-12-14 11:53:48 +0530608
609 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService")
Ed Tanous23a21a12020-07-25 04:45:05 +0000610 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700611 .methods(boost::beast::http::verb::get)(
Ed Tanouscb13a392020-07-25 19:02:03 +0000612 [](const crow::Request&, crow::Response& res) {
Ratan Gupta734a1c32019-12-14 11:53:48 +0530613 getLockServiceData(res);
614 });
manojkiraneda0b631ae2019-12-03 17:54:28 +0530615
616 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock")
Ed Tanous23a21a12020-07-25 04:45:05 +0000617 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700618 .methods(boost::beast::http::verb::post)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500619 [](const crow::Request& req, crow::Response& res) {
manojkiraneda0b631ae2019-12-03 17:54:28 +0530620 std::vector<nlohmann::json> body;
manojkiraneda0b631ae2019-12-03 17:54:28 +0530621 if (!redfish::json_util::readJson(req, res, "Request", body))
622 {
623 BMCWEB_LOG_DEBUG << "Not a Valid JSON";
624 res.result(boost::beast::http::status::bad_request);
625 res.end();
626 return;
627 }
628 handleAcquireLockAPI(req, res, body);
629 });
manojkiraneda3b6dea62019-12-13 17:05:36 +0530630 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
Ed Tanous23a21a12020-07-25 04:45:05 +0000631 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700632 .methods(boost::beast::http::verb::post)([](const crow::Request& req,
633 crow::Response& res) {
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530634 std::string type;
635 std::vector<uint32_t> listTransactionIds;
manojkiraneda3b6dea62019-12-13 17:05:36 +0530636
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530637 if (!redfish::json_util::readJson(req, res, "Type", type,
638 "TransactionIDs",
639 listTransactionIds))
640 {
641 res.result(boost::beast::http::status::bad_request);
642 res.end();
643 return;
644 }
645 if (type == "Transaction")
646 {
manojkiraneda3b6dea62019-12-13 17:05:36 +0530647 handleReleaseLockAPI(req, res, listTransactionIds);
Manojkiran Eda5bb0ece2020-01-20 20:22:36 +0530648 }
649 else if (type == "Session")
650 {
651 handleRelaseAllAPI(req, res);
652 }
653 else
654 {
655 BMCWEB_LOG_DEBUG << " Value of Type : " << type
656 << "is Not a Valid key";
657 redfish::messages::propertyValueNotInList(res, type, "Type");
658 }
659 });
manojkiraneda402b5712019-12-13 17:07:09 +0530660 BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.GetLockList")
Ed Tanous23a21a12020-07-25 04:45:05 +0000661 .privileges({"ConfigureComponents", "ConfigureManager"})
Ed Tanousb41187f2019-10-24 16:30:02 -0700662 .methods(boost::beast::http::verb::post)(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500663 [](const crow::Request& req, crow::Response& res) {
manojkiraneda402b5712019-12-13 17:07:09 +0530664 ListOfSessionIds listSessionIds;
665
666 if (!redfish::json_util::readJson(req, res, "SessionIDs",
667 listSessionIds))
668 {
669 res.result(boost::beast::http::status::bad_request);
670 res.end();
671 return;
672 }
Ed Tanouscb13a392020-07-25 19:02:03 +0000673 handleGetLockListAPI(res, listSessionIds);
manojkiraneda402b5712019-12-13 17:07:09 +0530674 });
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500675
676 BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
Ed Tanous23a21a12020-07-25 04:45:05 +0000677 .privileges({"ConfigureComponents", "ConfigureManager"})
Asmitha Karunanithi5738de52020-07-17 02:03:31 -0500678 .methods(boost::beast::http::verb::post)(
679 [](const crow::Request& req, crow::Response& res) {
680 handleBroadcastService(req, res);
681 });
Ratan Gupta453fed02019-12-14 09:39:47 +0530682}
683
684} // namespace ibm_mc
685} // namespace crow