blob: d273aea3b89c776cdcd6c4e721e4b946a7b21847 [file] [log] [blame]
AppaRao Pulie5aaf042020-03-20 01:05:52 +05301/*
2// Copyright (c) 2020 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
AppaRao Pulib52664e2020-04-09 21:36:51 +053017#include "event_service_manager.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053018
John Edward Broadbent7e860f12021-04-08 15:57:16 -070019#include <app.hpp>
Ed Tanous601c71a2021-09-08 16:40:12 -070020#include <boost/beast/http/fields.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070021#include <registries/privilege_registry.hpp>
22
AppaRao Pulie5aaf042020-03-20 01:05:52 +053023namespace redfish
24{
25
AppaRao Puli156d6b02020-04-25 06:04:05 +053026static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
27 eventFormatType, metricReportFormatType};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053028static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +053029 "Base", "OpenBMC", "TaskEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053030static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
31 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
32
Sunitha Harishe56f2542020-07-22 02:38:59 -050033#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
34static constexpr const std::array<const char*, 2> supportedResourceTypes = {
35 "IBMConfigFile", "Task"};
36#else
37static constexpr const std::array<const char*, 1> supportedResourceTypes = {
38 "Task"};
39#endif
40
AppaRao Pulie5aaf042020-03-20 01:05:52 +053041static constexpr const uint8_t maxNoOfSubscriptions = 20;
42
John Edward Broadbent7e860f12021-04-08 15:57:16 -070043inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053044{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070045 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070046 .privileges(redfish::privileges::getEventService)
George Liu0fda0f12021-11-16 10:06:17 +080047 .methods(
48 boost::beast::http::verb::
49 get)([](const crow::Request&,
50 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
51 asyncResp->res.jsonValue = {
52 {"@odata.type", "#EventService.v1_5_0.EventService"},
53 {"Id", "EventService"},
54 {"Name", "Event Service"},
55 {"Subscriptions",
56 {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
57 {"Actions",
58 {{"#EventService.SubmitTestEvent",
59 {{"target",
60 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"}}}}},
61 {"@odata.id", "/redfish/v1/EventService"}};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053062
George Liu0fda0f12021-11-16 10:06:17 +080063 const persistent_data::EventServiceConfig eventServiceConfig =
64 persistent_data::EventServiceStore::getInstance()
65 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080066
George Liu0fda0f12021-11-16 10:06:17 +080067 asyncResp->res.jsonValue["Status"]["State"] =
68 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
69 asyncResp->res.jsonValue["ServiceEnabled"] =
70 eventServiceConfig.enabled;
71 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
72 eventServiceConfig.retryAttempts;
73 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
74 eventServiceConfig.retryTimeoutInterval;
75 asyncResp->res.jsonValue["EventFormatTypes"] =
76 supportedEvtFormatTypes;
77 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
78 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053079
George Liu0fda0f12021-11-16 10:06:17 +080080 nlohmann::json supportedSSEFilters = {
81 {"EventFormatType", true}, {"MessageId", true},
82 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
83 {"OriginResource", false}, {"ResourceType", false}};
AppaRao Puli7d1cc382020-05-16 02:42:22 +053084
George Liu0fda0f12021-11-16 10:06:17 +080085 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
86 supportedSSEFilters;
87 });
Ayushi Smriti07941a82020-05-21 15:55:34 +053088
John Edward Broadbent7e860f12021-04-08 15:57:16 -070089 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070090 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -070091 .methods(boost::beast::http::verb::patch)(
92 [](const crow::Request& req,
93 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ayushi Smriti07941a82020-05-21 15:55:34 +053094
AppaRao Pulie5aaf042020-03-20 01:05:52 +053095 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -070096 std::optional<bool> serviceEnabled;
97 std::optional<uint32_t> retryAttemps;
98 std::optional<uint32_t> retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053099
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700100 if (!json_util::readJson(
101 req, asyncResp->res, "ServiceEnabled", serviceEnabled,
102 "DeliveryRetryAttempts", retryAttemps,
103 "DeliveryRetryIntervalSeconds", retryInterval))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530104 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530105 return;
106 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530107
JunLin Chen28afb492021-02-24 17:13:29 +0800108 persistent_data::EventServiceConfig eventServiceConfig =
109 persistent_data::EventServiceStore::getInstance()
110 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700111
112 if (serviceEnabled)
Sunitha Harishe56f2542020-07-22 02:38:59 -0500113 {
JunLin Chen28afb492021-02-24 17:13:29 +0800114 eventServiceConfig.enabled = *serviceEnabled;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500115 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500116
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700117 if (retryAttemps)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530118 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700119 // Supported range [1-3]
120 if ((*retryAttemps < 1) || (*retryAttemps > 3))
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530121 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700122 messages::queryParameterOutOfRange(
123 asyncResp->res, std::to_string(*retryAttemps),
124 "DeliveryRetryAttempts", "[1-3]");
125 }
126 else
127 {
JunLin Chen28afb492021-02-24 17:13:29 +0800128 eventServiceConfig.retryAttempts = *retryAttemps;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530129 }
130 }
131
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700132 if (retryInterval)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530133 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700134 // Supported range [30 - 180]
135 if ((*retryInterval < 30) || (*retryInterval > 180))
136 {
137 messages::queryParameterOutOfRange(
138 asyncResp->res, std::to_string(*retryInterval),
139 "DeliveryRetryIntervalSeconds", "[30-180]");
140 }
141 else
142 {
JunLin Chen28afb492021-02-24 17:13:29 +0800143 eventServiceConfig.retryTimeoutInterval =
144 *retryInterval;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700145 }
146 }
147
148 EventServiceManager::getInstance().setEventServiceConfig(
JunLin Chen28afb492021-02-24 17:13:29 +0800149 eventServiceConfig);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700150 });
151}
152
153inline void requestRoutesSubmitTestEvent(App& app)
154{
155
156 BMCWEB_ROUTE(
157 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700158 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700159 .methods(boost::beast::http::verb::post)(
160 [](const crow::Request&,
161 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
162 EventServiceManager::getInstance().sendTestEventLog();
163 asyncResp->res.result(boost::beast::http::status::no_content);
164 });
165}
166
167inline void requestRoutesEventDestinationCollection(App& app)
168{
169 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions")
Ed Tanoused398212021-06-09 17:05:54 -0700170 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700171 .methods(boost::beast::http::verb::get)(
172 [](const crow::Request&,
173 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
174 asyncResp->res.jsonValue = {
175 {"@odata.type",
176 "#EventDestinationCollection.EventDestinationCollection"},
177 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
178 {"Name", "Event Destination Collections"}};
179
180 nlohmann::json& memberArray =
181 asyncResp->res.jsonValue["Members"];
182
183 std::vector<std::string> subscripIds =
184 EventServiceManager::getInstance().getAllIDs();
185 memberArray = nlohmann::json::array();
186 asyncResp->res.jsonValue["Members@odata.count"] =
187 subscripIds.size();
188
189 for (const std::string& id : subscripIds)
190 {
191 memberArray.push_back(
192 {{"@odata.id",
193 "/redfish/v1/EventService/Subscriptions/" + id}});
194 }
195 });
196 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500197 .privileges(redfish::privileges::postEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700198 .methods(boost::beast::http::verb::post)(
199 [](const crow::Request& req,
200 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
201 if (EventServiceManager::getInstance()
202 .getNumberOfSubscriptions() >= maxNoOfSubscriptions)
203 {
204 messages::eventSubscriptionLimitExceeded(asyncResp->res);
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530205 return;
206 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700207 std::string destUrl;
208 std::string protocol;
209 std::optional<std::string> context;
210 std::optional<std::string> subscriptionType;
211 std::optional<std::string> eventFormatType2;
212 std::optional<std::string> retryPolicy;
213 std::optional<std::vector<std::string>> msgIds;
214 std::optional<std::vector<std::string>> regPrefixes;
215 std::optional<std::vector<std::string>> resTypes;
216 std::optional<std::vector<nlohmann::json>> headers;
217 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530218
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700219 if (!json_util::readJson(
220 req, asyncResp->res, "Destination", destUrl, "Context",
221 context, "Protocol", protocol, "SubscriptionType",
222 subscriptionType, "EventFormatType", eventFormatType2,
223 "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
224 "MessageIds", msgIds, "DeliveryRetryPolicy",
225 retryPolicy, "MetricReportDefinitions", mrdJsonArray,
226 "ResourceTypes", resTypes))
AppaRao Puli144b6312020-08-03 22:23:12 +0530227 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700228 return;
229 }
230
231 if (regPrefixes && msgIds)
232 {
233 if (regPrefixes->size() && msgIds->size())
234 {
235 messages::mutualExclusiveProperties(
236 asyncResp->res, "RegistryPrefixes", "MessageIds");
237 return;
238 }
239 }
240
241 // Validate the URL using regex expression
242 // Format: <protocol>://<host>:<port>/<uri>
243 // protocol: http/https
244 // host: Exclude ' ', ':', '#', '?'
245 // port: Empty or numeric value with ':' separator.
246 // uri: Start with '/' and Exclude '#', ' '
247 // Can include query params(ex: '/event?test=1')
248 // TODO: Need to validate hostname extensively(as per rfc)
249 const std::regex urlRegex(
250 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
251 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
252 std::cmatch match;
253 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
254 {
255 messages::propertyValueFormatError(asyncResp->res, destUrl,
256 "Destination");
257 return;
258 }
259
260 std::string uriProto =
261 std::string(match[1].first, match[1].second);
262 if (uriProto == "http")
263 {
264#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
265 messages::propertyValueFormatError(asyncResp->res, destUrl,
266 "Destination");
267 return;
268#endif
269 }
270
271 std::string host = std::string(match[2].first, match[2].second);
272 std::string port = std::string(match[3].first, match[3].second);
273 std::string path = std::string(match[4].first, match[4].second);
274 if (port.empty())
275 {
276 if (uriProto == "http")
277 {
278 port = "80";
279 }
280 else
281 {
282 port = "443";
283 }
284 }
285 if (path.empty())
286 {
287 path = "/";
288 }
289
290 std::shared_ptr<Subscription> subValue =
291 std::make_shared<Subscription>(host, port, path, uriProto);
292
293 subValue->destinationUrl = destUrl;
294
295 if (subscriptionType)
296 {
297 if (*subscriptionType != "RedfishEvent")
298 {
299 messages::propertyValueNotInList(asyncResp->res,
300 *subscriptionType,
301 "SubscriptionType");
302 return;
303 }
304 subValue->subscriptionType = *subscriptionType;
AppaRao Puli144b6312020-08-03 22:23:12 +0530305 }
306 else
307 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700308 subValue->subscriptionType = "RedfishEvent"; // Default
309 }
310
311 if (protocol != "Redfish")
312 {
313 messages::propertyValueNotInList(asyncResp->res, protocol,
314 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530315 return;
316 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700317 subValue->protocol = protocol;
AppaRao Puli156d6b02020-04-25 06:04:05 +0530318
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700319 if (eventFormatType2)
320 {
321 if (std::find(supportedEvtFormatTypes.begin(),
322 supportedEvtFormatTypes.end(),
323 *eventFormatType2) ==
324 supportedEvtFormatTypes.end())
325 {
326 messages::propertyValueNotInList(asyncResp->res,
327 *eventFormatType2,
328 "EventFormatType");
329 return;
330 }
331 subValue->eventFormatType = *eventFormatType2;
332 }
333 else
334 {
335 // If not specified, use default "Event"
336 subValue->eventFormatType = "Event";
337 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530338
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700339 if (context)
340 {
341 subValue->customText = *context;
342 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530343
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700344 if (headers)
345 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700346 for (const nlohmann::json& headerChunk : *headers)
347 {
348 for (const auto& item : headerChunk.items())
349 {
350 const std::string* value =
351 item.value().get_ptr<const std::string*>();
352 if (value == nullptr)
353 {
354 messages::propertyValueFormatError(
355 asyncResp->res, item.value().dump(2, true),
356 "HttpHeaders/" + item.key());
357 return;
358 }
359 subValue->httpHeaders.set(item.key(), *value);
360 }
361 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700362 }
363
364 if (regPrefixes)
365 {
366 for (const std::string& it : *regPrefixes)
367 {
368 if (std::find(supportedRegPrefixes.begin(),
369 supportedRegPrefixes.end(),
370 it) == supportedRegPrefixes.end())
371 {
372 messages::propertyValueNotInList(
373 asyncResp->res, it, "RegistryPrefixes");
374 return;
375 }
376 }
377 subValue->registryPrefixes = *regPrefixes;
378 }
379
380 if (resTypes)
381 {
382 for (const std::string& it : *resTypes)
383 {
384 if (std::find(supportedResourceTypes.begin(),
385 supportedResourceTypes.end(),
386 it) == supportedResourceTypes.end())
387 {
388 messages::propertyValueNotInList(asyncResp->res, it,
389 "ResourceTypes");
390 return;
391 }
392 }
393 subValue->resourceTypes = *resTypes;
394 }
395
396 if (msgIds)
397 {
398 std::vector<std::string> registryPrefix;
399
400 // If no registry prefixes are mentioned, consider all
401 // supported prefixes
402 if (subValue->registryPrefixes.empty())
403 {
404 registryPrefix.assign(supportedRegPrefixes.begin(),
405 supportedRegPrefixes.end());
406 }
407 else
408 {
409 registryPrefix = subValue->registryPrefixes;
410 }
411
412 for (const std::string& id : *msgIds)
413 {
414 bool validId = false;
415
416 // Check for Message ID in each of the selected Registry
417 for (const std::string& it : registryPrefix)
418 {
419 const boost::beast::span<
420 const redfish::message_registries::MessageEntry>
421 registry = redfish::message_registries::
422 getRegistryFromPrefix(it);
423
424 if (std::any_of(
425 registry.cbegin(), registry.cend(),
426 [&id](const redfish::message_registries::
427 MessageEntry& messageEntry) {
428 return !id.compare(messageEntry.first);
429 }))
430 {
431 validId = true;
432 break;
433 }
434 }
435
436 if (!validId)
437 {
438 messages::propertyValueNotInList(asyncResp->res, id,
439 "MessageIds");
440 return;
441 }
442 }
443
444 subValue->registryMsgIds = *msgIds;
445 }
446
447 if (retryPolicy)
448 {
449 if (std::find(supportedRetryPolicies.begin(),
450 supportedRetryPolicies.end(),
451 *retryPolicy) == supportedRetryPolicies.end())
452 {
453 messages::propertyValueNotInList(asyncResp->res,
454 *retryPolicy,
455 "DeliveryRetryPolicy");
456 return;
457 }
458 subValue->retryPolicy = *retryPolicy;
459 }
460 else
461 {
462 // Default "TerminateAfterRetries"
463 subValue->retryPolicy = "TerminateAfterRetries";
464 }
465
466 if (mrdJsonArray)
467 {
468 for (nlohmann::json& mrdObj : *mrdJsonArray)
469 {
470 std::string mrdUri;
471 if (json_util::getValueFromJsonObject(
472 mrdObj, "@odata.id", mrdUri))
473 {
474 subValue->metricReportDefinitions.emplace_back(
475 mrdUri);
476 }
477 else
478 {
479 messages::propertyValueFormatError(
480 asyncResp->res,
481 mrdObj.dump(
482 2, ' ', true,
483 nlohmann::json::error_handler_t::replace),
484 "MetricReportDefinitions");
485 return;
486 }
487 }
488 }
489
490 std::string id =
491 EventServiceManager::getInstance().addSubscription(
492 subValue);
493 if (id.empty())
494 {
495 messages::internalError(asyncResp->res);
496 return;
497 }
498
499 messages::created(asyncResp->res);
500 asyncResp->res.addHeader(
501 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
502 });
503}
504
505inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530506{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500507 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700508 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700509 .methods(boost::beast::http::verb::get)(
510 [](const crow::Request&,
511 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
512 const std::string& param) {
513 std::shared_ptr<Subscription> subValue =
514 EventServiceManager::getInstance().getSubscription(param);
515 if (subValue == nullptr)
516 {
517 asyncResp->res.result(
518 boost::beast::http::status::not_found);
519 return;
520 }
521 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530522
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700523 asyncResp->res.jsonValue = {
524 {"@odata.type",
525 "#EventDestination.v1_7_0.EventDestination"},
526 {"Protocol", "Redfish"}};
527 asyncResp->res.jsonValue["@odata.id"] =
528 "/redfish/v1/EventService/Subscriptions/" + id;
529 asyncResp->res.jsonValue["Id"] = id;
530 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
531 asyncResp->res.jsonValue["Destination"] =
532 subValue->destinationUrl;
533 asyncResp->res.jsonValue["Context"] = subValue->customText;
534 asyncResp->res.jsonValue["SubscriptionType"] =
535 subValue->subscriptionType;
Ed Tanousad22fef2021-09-13 13:07:32 -0700536 asyncResp->res.jsonValue["HttpHeaders"] =
537 nlohmann::json::array();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700538 asyncResp->res.jsonValue["EventFormatType"] =
539 subValue->eventFormatType;
540 asyncResp->res.jsonValue["RegistryPrefixes"] =
541 subValue->registryPrefixes;
542 asyncResp->res.jsonValue["ResourceTypes"] =
543 subValue->resourceTypes;
zhanghch058d1b46d2021-04-01 11:18:24 +0800544
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700545 asyncResp->res.jsonValue["MessageIds"] =
546 subValue->registryMsgIds;
547 asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
548 subValue->retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530549
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700550 std::vector<nlohmann::json> mrdJsonArray;
551 for (const auto& mdrUri : subValue->metricReportDefinitions)
552 {
553 mrdJsonArray.push_back({{"@odata.id", mdrUri}});
554 }
555 asyncResp->res.jsonValue["MetricReportDefinitions"] =
556 mrdJsonArray;
557 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500558 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700559 // The below privilege is wrong, it should be ConfigureManager OR
560 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500561 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700562 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700563 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700564 .methods(boost::beast::http::verb::patch)(
565 [](const crow::Request& req,
566 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
567 const std::string& param) {
568 std::shared_ptr<Subscription> subValue =
569 EventServiceManager::getInstance().getSubscription(param);
570 if (subValue == nullptr)
571 {
572 asyncResp->res.result(
573 boost::beast::http::status::not_found);
574 return;
575 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530576
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700577 std::optional<std::string> context;
578 std::optional<std::string> retryPolicy;
579 std::optional<std::vector<nlohmann::json>> headers;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500580
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700581 if (!json_util::readJson(req, asyncResp->res, "Context",
582 context, "DeliveryRetryPolicy",
583 retryPolicy, "HttpHeaders", headers))
584 {
585 return;
586 }
AppaRao Puli144b6312020-08-03 22:23:12 +0530587
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700588 if (context)
589 {
590 subValue->customText = *context;
591 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530592
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700593 if (headers)
594 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700595 boost::beast::http::fields fields;
596 for (const nlohmann::json& headerChunk : *headers)
597 {
598 for (auto& it : headerChunk.items())
599 {
600 const std::string* value =
601 it.value().get_ptr<const std::string*>();
602 if (value == nullptr)
603 {
604 messages::propertyValueFormatError(
605 asyncResp->res,
606 it.value().dump(2, ' ', true),
607 "HttpHeaders/" + it.key());
608 return;
609 }
610 fields.set(it.key(), *value);
611 }
612 }
613 subValue->httpHeaders = fields;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700614 }
zhanghch058d1b46d2021-04-01 11:18:24 +0800615
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700616 if (retryPolicy)
617 {
618 if (std::find(supportedRetryPolicies.begin(),
619 supportedRetryPolicies.end(),
620 *retryPolicy) == supportedRetryPolicies.end())
621 {
622 messages::propertyValueNotInList(asyncResp->res,
623 *retryPolicy,
624 "DeliveryRetryPolicy");
625 return;
626 }
627 subValue->retryPolicy = *retryPolicy;
628 subValue->updateRetryPolicy();
629 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530630
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700631 EventServiceManager::getInstance().updateSubscriptionData();
632 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500633 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700634 // The below privilege is wrong, it should be ConfigureManager OR
635 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500636 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700637 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700638 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700639 .methods(boost::beast::http::verb::delete_)(
640 [](const crow::Request&,
641 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
642 const std::string& param) {
643 if (!EventServiceManager::getInstance().isSubscriptionExist(
644 param))
645 {
646 asyncResp->res.result(
647 boost::beast::http::status::not_found);
648 return;
649 }
650 EventServiceManager::getInstance().deleteSubscription(param);
651 });
652}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530653
654} // namespace redfish