blob: b802280b91fa10029b8d97c3353d79f3b31901f5 [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)
John Edward Broadbent7e860f12021-04-08 15:57:16 -070047 .methods(boost::beast::http::verb::get)(
48 [](const crow::Request&,
49 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
50 asyncResp->res.jsonValue = {
51 {"@odata.type", "#EventService.v1_5_0.EventService"},
52 {"Id", "EventService"},
53 {"Name", "Event Service"},
54 {"Subscriptions",
55 {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
56 {"Actions",
57 {{"#EventService.SubmitTestEvent",
58 {{"target", "/redfish/v1/EventService/Actions/"
59 "EventService.SubmitTestEvent"}}}}},
60 {"@odata.id", "/redfish/v1/EventService"}};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053061
JunLin Chen28afb492021-02-24 17:13:29 +080062 const persistent_data::EventServiceConfig eventServiceConfig =
63 persistent_data::EventServiceStore::getInstance()
64 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080065
John Edward Broadbent7e860f12021-04-08 15:57:16 -070066 asyncResp->res.jsonValue["Status"]["State"] =
JunLin Chen28afb492021-02-24 17:13:29 +080067 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
68 asyncResp->res.jsonValue["ServiceEnabled"] =
69 eventServiceConfig.enabled;
John Edward Broadbent7e860f12021-04-08 15:57:16 -070070 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
JunLin Chen28afb492021-02-24 17:13:29 +080071 eventServiceConfig.retryAttempts;
John Edward Broadbent7e860f12021-04-08 15:57:16 -070072 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
JunLin Chen28afb492021-02-24 17:13:29 +080073 eventServiceConfig.retryTimeoutInterval;
John Edward Broadbent7e860f12021-04-08 15:57:16 -070074 asyncResp->res.jsonValue["EventFormatTypes"] =
75 supportedEvtFormatTypes;
76 asyncResp->res.jsonValue["RegistryPrefixes"] =
77 supportedRegPrefixes;
78 asyncResp->res.jsonValue["ResourceTypes"] =
79 supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053080
John Edward Broadbent7e860f12021-04-08 15:57:16 -070081 nlohmann::json supportedSSEFilters = {
82 {"EventFormatType", true}, {"MessageId", true},
83 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
84 {"OriginResource", false}, {"ResourceType", false}};
AppaRao Puli7d1cc382020-05-16 02:42:22 +053085
John Edward Broadbent7e860f12021-04-08 15:57:16 -070086 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
87 supportedSSEFilters;
88 });
Ayushi Smriti07941a82020-05-21 15:55:34 +053089
John Edward Broadbent7e860f12021-04-08 15:57:16 -070090 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070091 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -070092 .methods(boost::beast::http::verb::patch)(
93 [](const crow::Request& req,
94 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ayushi Smriti07941a82020-05-21 15:55:34 +053095
AppaRao Pulie5aaf042020-03-20 01:05:52 +053096 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -070097 std::optional<bool> serviceEnabled;
98 std::optional<uint32_t> retryAttemps;
99 std::optional<uint32_t> retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530100
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700101 if (!json_util::readJson(
102 req, asyncResp->res, "ServiceEnabled", serviceEnabled,
103 "DeliveryRetryAttempts", retryAttemps,
104 "DeliveryRetryIntervalSeconds", retryInterval))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530105 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530106 return;
107 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530108
JunLin Chen28afb492021-02-24 17:13:29 +0800109 persistent_data::EventServiceConfig eventServiceConfig =
110 persistent_data::EventServiceStore::getInstance()
111 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700112
113 if (serviceEnabled)
Sunitha Harishe56f2542020-07-22 02:38:59 -0500114 {
JunLin Chen28afb492021-02-24 17:13:29 +0800115 eventServiceConfig.enabled = *serviceEnabled;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500116 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500117
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700118 if (retryAttemps)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530119 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700120 // Supported range [1-3]
121 if ((*retryAttemps < 1) || (*retryAttemps > 3))
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530122 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700123 messages::queryParameterOutOfRange(
124 asyncResp->res, std::to_string(*retryAttemps),
125 "DeliveryRetryAttempts", "[1-3]");
126 }
127 else
128 {
JunLin Chen28afb492021-02-24 17:13:29 +0800129 eventServiceConfig.retryAttempts = *retryAttemps;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530130 }
131 }
132
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700133 if (retryInterval)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530134 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700135 // Supported range [30 - 180]
136 if ((*retryInterval < 30) || (*retryInterval > 180))
137 {
138 messages::queryParameterOutOfRange(
139 asyncResp->res, std::to_string(*retryInterval),
140 "DeliveryRetryIntervalSeconds", "[30-180]");
141 }
142 else
143 {
JunLin Chen28afb492021-02-24 17:13:29 +0800144 eventServiceConfig.retryTimeoutInterval =
145 *retryInterval;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700146 }
147 }
148
149 EventServiceManager::getInstance().setEventServiceConfig(
JunLin Chen28afb492021-02-24 17:13:29 +0800150 eventServiceConfig);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700151 });
152}
153
154inline void requestRoutesSubmitTestEvent(App& app)
155{
156
157 BMCWEB_ROUTE(
158 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700159 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700160 .methods(boost::beast::http::verb::post)(
161 [](const crow::Request&,
162 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
163 EventServiceManager::getInstance().sendTestEventLog();
164 asyncResp->res.result(boost::beast::http::status::no_content);
165 });
166}
167
168inline void requestRoutesEventDestinationCollection(App& app)
169{
170 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions")
Ed Tanoused398212021-06-09 17:05:54 -0700171 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700172 .methods(boost::beast::http::verb::get)(
173 [](const crow::Request&,
174 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
175 asyncResp->res.jsonValue = {
176 {"@odata.type",
177 "#EventDestinationCollection.EventDestinationCollection"},
178 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
179 {"Name", "Event Destination Collections"}};
180
181 nlohmann::json& memberArray =
182 asyncResp->res.jsonValue["Members"];
183
184 std::vector<std::string> subscripIds =
185 EventServiceManager::getInstance().getAllIDs();
186 memberArray = nlohmann::json::array();
187 asyncResp->res.jsonValue["Members@odata.count"] =
188 subscripIds.size();
189
190 for (const std::string& id : subscripIds)
191 {
192 memberArray.push_back(
193 {{"@odata.id",
194 "/redfish/v1/EventService/Subscriptions/" + id}});
195 }
196 });
197 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500198 .privileges(redfish::privileges::postEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700199 .methods(boost::beast::http::verb::post)(
200 [](const crow::Request& req,
201 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
202 if (EventServiceManager::getInstance()
203 .getNumberOfSubscriptions() >= maxNoOfSubscriptions)
204 {
205 messages::eventSubscriptionLimitExceeded(asyncResp->res);
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530206 return;
207 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700208 std::string destUrl;
209 std::string protocol;
210 std::optional<std::string> context;
211 std::optional<std::string> subscriptionType;
212 std::optional<std::string> eventFormatType2;
213 std::optional<std::string> retryPolicy;
214 std::optional<std::vector<std::string>> msgIds;
215 std::optional<std::vector<std::string>> regPrefixes;
216 std::optional<std::vector<std::string>> resTypes;
217 std::optional<std::vector<nlohmann::json>> headers;
218 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530219
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700220 if (!json_util::readJson(
221 req, asyncResp->res, "Destination", destUrl, "Context",
222 context, "Protocol", protocol, "SubscriptionType",
223 subscriptionType, "EventFormatType", eventFormatType2,
224 "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
225 "MessageIds", msgIds, "DeliveryRetryPolicy",
226 retryPolicy, "MetricReportDefinitions", mrdJsonArray,
227 "ResourceTypes", resTypes))
AppaRao Puli144b6312020-08-03 22:23:12 +0530228 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700229 return;
230 }
231
232 if (regPrefixes && msgIds)
233 {
234 if (regPrefixes->size() && msgIds->size())
235 {
236 messages::mutualExclusiveProperties(
237 asyncResp->res, "RegistryPrefixes", "MessageIds");
238 return;
239 }
240 }
241
242 // Validate the URL using regex expression
243 // Format: <protocol>://<host>:<port>/<uri>
244 // protocol: http/https
245 // host: Exclude ' ', ':', '#', '?'
246 // port: Empty or numeric value with ':' separator.
247 // uri: Start with '/' and Exclude '#', ' '
248 // Can include query params(ex: '/event?test=1')
249 // TODO: Need to validate hostname extensively(as per rfc)
250 const std::regex urlRegex(
251 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
252 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
253 std::cmatch match;
254 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
255 {
256 messages::propertyValueFormatError(asyncResp->res, destUrl,
257 "Destination");
258 return;
259 }
260
261 std::string uriProto =
262 std::string(match[1].first, match[1].second);
263 if (uriProto == "http")
264 {
265#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
266 messages::propertyValueFormatError(asyncResp->res, destUrl,
267 "Destination");
268 return;
269#endif
270 }
271
272 std::string host = std::string(match[2].first, match[2].second);
273 std::string port = std::string(match[3].first, match[3].second);
274 std::string path = std::string(match[4].first, match[4].second);
275 if (port.empty())
276 {
277 if (uriProto == "http")
278 {
279 port = "80";
280 }
281 else
282 {
283 port = "443";
284 }
285 }
286 if (path.empty())
287 {
288 path = "/";
289 }
290
291 std::shared_ptr<Subscription> subValue =
292 std::make_shared<Subscription>(host, port, path, uriProto);
293
294 subValue->destinationUrl = destUrl;
295
296 if (subscriptionType)
297 {
298 if (*subscriptionType != "RedfishEvent")
299 {
300 messages::propertyValueNotInList(asyncResp->res,
301 *subscriptionType,
302 "SubscriptionType");
303 return;
304 }
305 subValue->subscriptionType = *subscriptionType;
AppaRao Puli144b6312020-08-03 22:23:12 +0530306 }
307 else
308 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700309 subValue->subscriptionType = "RedfishEvent"; // Default
310 }
311
312 if (protocol != "Redfish")
313 {
314 messages::propertyValueNotInList(asyncResp->res, protocol,
315 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530316 return;
317 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700318 subValue->protocol = protocol;
AppaRao Puli156d6b02020-04-25 06:04:05 +0530319
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700320 if (eventFormatType2)
321 {
322 if (std::find(supportedEvtFormatTypes.begin(),
323 supportedEvtFormatTypes.end(),
324 *eventFormatType2) ==
325 supportedEvtFormatTypes.end())
326 {
327 messages::propertyValueNotInList(asyncResp->res,
328 *eventFormatType2,
329 "EventFormatType");
330 return;
331 }
332 subValue->eventFormatType = *eventFormatType2;
333 }
334 else
335 {
336 // If not specified, use default "Event"
337 subValue->eventFormatType = "Event";
338 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530339
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700340 if (context)
341 {
342 subValue->customText = *context;
343 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530344
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700345 if (headers)
346 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700347 for (const nlohmann::json& headerChunk : *headers)
348 {
349 for (const auto& item : headerChunk.items())
350 {
351 const std::string* value =
352 item.value().get_ptr<const std::string*>();
353 if (value == nullptr)
354 {
355 messages::propertyValueFormatError(
356 asyncResp->res, item.value().dump(2, true),
357 "HttpHeaders/" + item.key());
358 return;
359 }
360 subValue->httpHeaders.set(item.key(), *value);
361 }
362 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700363 }
364
365 if (regPrefixes)
366 {
367 for (const std::string& it : *regPrefixes)
368 {
369 if (std::find(supportedRegPrefixes.begin(),
370 supportedRegPrefixes.end(),
371 it) == supportedRegPrefixes.end())
372 {
373 messages::propertyValueNotInList(
374 asyncResp->res, it, "RegistryPrefixes");
375 return;
376 }
377 }
378 subValue->registryPrefixes = *regPrefixes;
379 }
380
381 if (resTypes)
382 {
383 for (const std::string& it : *resTypes)
384 {
385 if (std::find(supportedResourceTypes.begin(),
386 supportedResourceTypes.end(),
387 it) == supportedResourceTypes.end())
388 {
389 messages::propertyValueNotInList(asyncResp->res, it,
390 "ResourceTypes");
391 return;
392 }
393 }
394 subValue->resourceTypes = *resTypes;
395 }
396
397 if (msgIds)
398 {
399 std::vector<std::string> registryPrefix;
400
401 // If no registry prefixes are mentioned, consider all
402 // supported prefixes
403 if (subValue->registryPrefixes.empty())
404 {
405 registryPrefix.assign(supportedRegPrefixes.begin(),
406 supportedRegPrefixes.end());
407 }
408 else
409 {
410 registryPrefix = subValue->registryPrefixes;
411 }
412
413 for (const std::string& id : *msgIds)
414 {
415 bool validId = false;
416
417 // Check for Message ID in each of the selected Registry
418 for (const std::string& it : registryPrefix)
419 {
420 const boost::beast::span<
421 const redfish::message_registries::MessageEntry>
422 registry = redfish::message_registries::
423 getRegistryFromPrefix(it);
424
425 if (std::any_of(
426 registry.cbegin(), registry.cend(),
427 [&id](const redfish::message_registries::
428 MessageEntry& messageEntry) {
429 return !id.compare(messageEntry.first);
430 }))
431 {
432 validId = true;
433 break;
434 }
435 }
436
437 if (!validId)
438 {
439 messages::propertyValueNotInList(asyncResp->res, id,
440 "MessageIds");
441 return;
442 }
443 }
444
445 subValue->registryMsgIds = *msgIds;
446 }
447
448 if (retryPolicy)
449 {
450 if (std::find(supportedRetryPolicies.begin(),
451 supportedRetryPolicies.end(),
452 *retryPolicy) == supportedRetryPolicies.end())
453 {
454 messages::propertyValueNotInList(asyncResp->res,
455 *retryPolicy,
456 "DeliveryRetryPolicy");
457 return;
458 }
459 subValue->retryPolicy = *retryPolicy;
460 }
461 else
462 {
463 // Default "TerminateAfterRetries"
464 subValue->retryPolicy = "TerminateAfterRetries";
465 }
466
467 if (mrdJsonArray)
468 {
469 for (nlohmann::json& mrdObj : *mrdJsonArray)
470 {
471 std::string mrdUri;
472 if (json_util::getValueFromJsonObject(
473 mrdObj, "@odata.id", mrdUri))
474 {
475 subValue->metricReportDefinitions.emplace_back(
476 mrdUri);
477 }
478 else
479 {
480 messages::propertyValueFormatError(
481 asyncResp->res,
482 mrdObj.dump(
483 2, ' ', true,
484 nlohmann::json::error_handler_t::replace),
485 "MetricReportDefinitions");
486 return;
487 }
488 }
489 }
490
491 std::string id =
492 EventServiceManager::getInstance().addSubscription(
493 subValue);
494 if (id.empty())
495 {
496 messages::internalError(asyncResp->res);
497 return;
498 }
499
500 messages::created(asyncResp->res);
501 asyncResp->res.addHeader(
502 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
503 });
504}
505
506inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530507{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500508 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700509 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700510 .methods(boost::beast::http::verb::get)(
511 [](const crow::Request&,
512 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
513 const std::string& param) {
514 std::shared_ptr<Subscription> subValue =
515 EventServiceManager::getInstance().getSubscription(param);
516 if (subValue == nullptr)
517 {
518 asyncResp->res.result(
519 boost::beast::http::status::not_found);
520 return;
521 }
522 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530523
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700524 asyncResp->res.jsonValue = {
525 {"@odata.type",
526 "#EventDestination.v1_7_0.EventDestination"},
527 {"Protocol", "Redfish"}};
528 asyncResp->res.jsonValue["@odata.id"] =
529 "/redfish/v1/EventService/Subscriptions/" + id;
530 asyncResp->res.jsonValue["Id"] = id;
531 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
532 asyncResp->res.jsonValue["Destination"] =
533 subValue->destinationUrl;
534 asyncResp->res.jsonValue["Context"] = subValue->customText;
535 asyncResp->res.jsonValue["SubscriptionType"] =
536 subValue->subscriptionType;
Ed Tanousad22fef2021-09-13 13:07:32 -0700537 asyncResp->res.jsonValue["HttpHeaders"] =
538 nlohmann::json::array();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700539 asyncResp->res.jsonValue["EventFormatType"] =
540 subValue->eventFormatType;
541 asyncResp->res.jsonValue["RegistryPrefixes"] =
542 subValue->registryPrefixes;
543 asyncResp->res.jsonValue["ResourceTypes"] =
544 subValue->resourceTypes;
zhanghch058d1b46d2021-04-01 11:18:24 +0800545
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700546 asyncResp->res.jsonValue["MessageIds"] =
547 subValue->registryMsgIds;
548 asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
549 subValue->retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530550
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700551 std::vector<nlohmann::json> mrdJsonArray;
552 for (const auto& mdrUri : subValue->metricReportDefinitions)
553 {
554 mrdJsonArray.push_back({{"@odata.id", mdrUri}});
555 }
556 asyncResp->res.jsonValue["MetricReportDefinitions"] =
557 mrdJsonArray;
558 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500559 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700560 // The below privilege is wrong, it should be ConfigureManager OR
561 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500562 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700563 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700564 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700565 .methods(boost::beast::http::verb::patch)(
566 [](const crow::Request& req,
567 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
568 const std::string& param) {
569 std::shared_ptr<Subscription> subValue =
570 EventServiceManager::getInstance().getSubscription(param);
571 if (subValue == nullptr)
572 {
573 asyncResp->res.result(
574 boost::beast::http::status::not_found);
575 return;
576 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530577
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700578 std::optional<std::string> context;
579 std::optional<std::string> retryPolicy;
580 std::optional<std::vector<nlohmann::json>> headers;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500581
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700582 if (!json_util::readJson(req, asyncResp->res, "Context",
583 context, "DeliveryRetryPolicy",
584 retryPolicy, "HttpHeaders", headers))
585 {
586 return;
587 }
AppaRao Puli144b6312020-08-03 22:23:12 +0530588
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700589 if (context)
590 {
591 subValue->customText = *context;
592 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530593
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700594 if (headers)
595 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700596 boost::beast::http::fields fields;
597 for (const nlohmann::json& headerChunk : *headers)
598 {
599 for (auto& it : headerChunk.items())
600 {
601 const std::string* value =
602 it.value().get_ptr<const std::string*>();
603 if (value == nullptr)
604 {
605 messages::propertyValueFormatError(
606 asyncResp->res,
607 it.value().dump(2, ' ', true),
608 "HttpHeaders/" + it.key());
609 return;
610 }
611 fields.set(it.key(), *value);
612 }
613 }
614 subValue->httpHeaders = fields;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700615 }
zhanghch058d1b46d2021-04-01 11:18:24 +0800616
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700617 if (retryPolicy)
618 {
619 if (std::find(supportedRetryPolicies.begin(),
620 supportedRetryPolicies.end(),
621 *retryPolicy) == supportedRetryPolicies.end())
622 {
623 messages::propertyValueNotInList(asyncResp->res,
624 *retryPolicy,
625 "DeliveryRetryPolicy");
626 return;
627 }
628 subValue->retryPolicy = *retryPolicy;
629 subValue->updateRetryPolicy();
630 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530631
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700632 EventServiceManager::getInstance().updateSubscriptionData();
633 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500634 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700635 // The below privilege is wrong, it should be ConfigureManager OR
636 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500637 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700638 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700639 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700640 .methods(boost::beast::http::verb::delete_)(
641 [](const crow::Request&,
642 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
643 const std::string& param) {
644 if (!EventServiceManager::getInstance().isSubscriptionExist(
645 param))
646 {
647 asyncResp->res.result(
648 boost::beast::http::status::not_found);
649 return;
650 }
651 EventServiceManager::getInstance().deleteSubscription(param);
652 });
653}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530654
655} // namespace redfish