blob: 115bfee1644b648d3f55099de06ce6f286508b0b [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
Patrick Williams1e270c52021-12-04 06:06:56 -060023#include <span>
24
AppaRao Pulie5aaf042020-03-20 01:05:52 +053025namespace redfish
26{
27
AppaRao Puli156d6b02020-04-25 06:04:05 +053028static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
29 eventFormatType, metricReportFormatType};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053030static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +053031 "Base", "OpenBMC", "TaskEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053032static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
33 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
34
Sunitha Harishe56f2542020-07-22 02:38:59 -050035#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
36static constexpr const std::array<const char*, 2> supportedResourceTypes = {
37 "IBMConfigFile", "Task"};
38#else
39static constexpr const std::array<const char*, 1> supportedResourceTypes = {
40 "Task"};
41#endif
42
AppaRao Pulie5aaf042020-03-20 01:05:52 +053043static constexpr const uint8_t maxNoOfSubscriptions = 20;
44
John Edward Broadbent7e860f12021-04-08 15:57:16 -070045inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053046{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070047 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070048 .privileges(redfish::privileges::getEventService)
George Liu0fda0f12021-11-16 10:06:17 +080049 .methods(
50 boost::beast::http::verb::
51 get)([](const crow::Request&,
52 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
53 asyncResp->res.jsonValue = {
54 {"@odata.type", "#EventService.v1_5_0.EventService"},
55 {"Id", "EventService"},
56 {"Name", "Event Service"},
57 {"Subscriptions",
58 {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
59 {"Actions",
60 {{"#EventService.SubmitTestEvent",
61 {{"target",
62 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"}}}}},
63 {"@odata.id", "/redfish/v1/EventService"}};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053064
George Liu0fda0f12021-11-16 10:06:17 +080065 const persistent_data::EventServiceConfig eventServiceConfig =
66 persistent_data::EventServiceStore::getInstance()
67 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080068
George Liu0fda0f12021-11-16 10:06:17 +080069 asyncResp->res.jsonValue["Status"]["State"] =
70 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
71 asyncResp->res.jsonValue["ServiceEnabled"] =
72 eventServiceConfig.enabled;
73 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
74 eventServiceConfig.retryAttempts;
75 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
76 eventServiceConfig.retryTimeoutInterval;
77 asyncResp->res.jsonValue["EventFormatTypes"] =
78 supportedEvtFormatTypes;
79 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
80 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053081
George Liu0fda0f12021-11-16 10:06:17 +080082 nlohmann::json supportedSSEFilters = {
83 {"EventFormatType", true}, {"MessageId", true},
84 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
85 {"OriginResource", false}, {"ResourceType", false}};
AppaRao Puli7d1cc382020-05-16 02:42:22 +053086
George Liu0fda0f12021-11-16 10:06:17 +080087 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
88 supportedSSEFilters;
89 });
Ayushi Smriti07941a82020-05-21 15:55:34 +053090
John Edward Broadbent7e860f12021-04-08 15:57:16 -070091 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070092 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -070093 .methods(boost::beast::http::verb::patch)(
94 [](const crow::Request& req,
95 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ayushi Smriti07941a82020-05-21 15:55:34 +053096
AppaRao Pulie5aaf042020-03-20 01:05:52 +053097 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -070098 std::optional<bool> serviceEnabled;
99 std::optional<uint32_t> retryAttemps;
100 std::optional<uint32_t> retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530101
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700102 if (!json_util::readJson(
103 req, asyncResp->res, "ServiceEnabled", serviceEnabled,
104 "DeliveryRetryAttempts", retryAttemps,
105 "DeliveryRetryIntervalSeconds", retryInterval))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530106 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530107 return;
108 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530109
JunLin Chen28afb492021-02-24 17:13:29 +0800110 persistent_data::EventServiceConfig eventServiceConfig =
111 persistent_data::EventServiceStore::getInstance()
112 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700113
114 if (serviceEnabled)
Sunitha Harishe56f2542020-07-22 02:38:59 -0500115 {
JunLin Chen28afb492021-02-24 17:13:29 +0800116 eventServiceConfig.enabled = *serviceEnabled;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500117 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500118
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700119 if (retryAttemps)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530120 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700121 // Supported range [1-3]
122 if ((*retryAttemps < 1) || (*retryAttemps > 3))
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530123 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700124 messages::queryParameterOutOfRange(
125 asyncResp->res, std::to_string(*retryAttemps),
126 "DeliveryRetryAttempts", "[1-3]");
127 }
128 else
129 {
JunLin Chen28afb492021-02-24 17:13:29 +0800130 eventServiceConfig.retryAttempts = *retryAttemps;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530131 }
132 }
133
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700134 if (retryInterval)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530135 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700136 // Supported range [30 - 180]
137 if ((*retryInterval < 30) || (*retryInterval > 180))
138 {
139 messages::queryParameterOutOfRange(
140 asyncResp->res, std::to_string(*retryInterval),
141 "DeliveryRetryIntervalSeconds", "[30-180]");
142 }
143 else
144 {
JunLin Chen28afb492021-02-24 17:13:29 +0800145 eventServiceConfig.retryTimeoutInterval =
146 *retryInterval;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700147 }
148 }
149
150 EventServiceManager::getInstance().setEventServiceConfig(
JunLin Chen28afb492021-02-24 17:13:29 +0800151 eventServiceConfig);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700152 });
153}
154
155inline void requestRoutesSubmitTestEvent(App& app)
156{
157
158 BMCWEB_ROUTE(
159 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700160 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700161 .methods(boost::beast::http::verb::post)(
162 [](const crow::Request&,
163 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
164 EventServiceManager::getInstance().sendTestEventLog();
165 asyncResp->res.result(boost::beast::http::status::no_content);
166 });
167}
168
169inline void requestRoutesEventDestinationCollection(App& app)
170{
171 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions")
Ed Tanoused398212021-06-09 17:05:54 -0700172 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700173 .methods(boost::beast::http::verb::get)(
174 [](const crow::Request&,
175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
176 asyncResp->res.jsonValue = {
177 {"@odata.type",
178 "#EventDestinationCollection.EventDestinationCollection"},
179 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
180 {"Name", "Event Destination Collections"}};
181
182 nlohmann::json& memberArray =
183 asyncResp->res.jsonValue["Members"];
184
185 std::vector<std::string> subscripIds =
186 EventServiceManager::getInstance().getAllIDs();
187 memberArray = nlohmann::json::array();
188 asyncResp->res.jsonValue["Members@odata.count"] =
189 subscripIds.size();
190
191 for (const std::string& id : subscripIds)
192 {
193 memberArray.push_back(
194 {{"@odata.id",
195 "/redfish/v1/EventService/Subscriptions/" + id}});
196 }
197 });
198 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500199 .privileges(redfish::privileges::postEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700200 .methods(boost::beast::http::verb::post)(
201 [](const crow::Request& req,
202 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
203 if (EventServiceManager::getInstance()
204 .getNumberOfSubscriptions() >= maxNoOfSubscriptions)
205 {
206 messages::eventSubscriptionLimitExceeded(asyncResp->res);
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530207 return;
208 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700209 std::string destUrl;
210 std::string protocol;
211 std::optional<std::string> context;
212 std::optional<std::string> subscriptionType;
213 std::optional<std::string> eventFormatType2;
214 std::optional<std::string> retryPolicy;
215 std::optional<std::vector<std::string>> msgIds;
216 std::optional<std::vector<std::string>> regPrefixes;
217 std::optional<std::vector<std::string>> resTypes;
218 std::optional<std::vector<nlohmann::json>> headers;
219 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530220
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700221 if (!json_util::readJson(
222 req, asyncResp->res, "Destination", destUrl, "Context",
223 context, "Protocol", protocol, "SubscriptionType",
224 subscriptionType, "EventFormatType", eventFormatType2,
225 "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
226 "MessageIds", msgIds, "DeliveryRetryPolicy",
227 retryPolicy, "MetricReportDefinitions", mrdJsonArray,
228 "ResourceTypes", resTypes))
AppaRao Puli144b6312020-08-03 22:23:12 +0530229 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700230 return;
231 }
232
233 if (regPrefixes && msgIds)
234 {
Ed Tanous26f69762022-01-25 09:49:11 -0800235 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700236 {
237 messages::mutualExclusiveProperties(
238 asyncResp->res, "RegistryPrefixes", "MessageIds");
239 return;
240 }
241 }
242
243 // Validate the URL using regex expression
244 // Format: <protocol>://<host>:<port>/<uri>
245 // protocol: http/https
246 // host: Exclude ' ', ':', '#', '?'
247 // port: Empty or numeric value with ':' separator.
248 // uri: Start with '/' and Exclude '#', ' '
249 // Can include query params(ex: '/event?test=1')
250 // TODO: Need to validate hostname extensively(as per rfc)
251 const std::regex urlRegex(
252 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
253 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
254 std::cmatch match;
255 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
256 {
257 messages::propertyValueFormatError(asyncResp->res, destUrl,
258 "Destination");
259 return;
260 }
261
262 std::string uriProto =
263 std::string(match[1].first, match[1].second);
264 if (uriProto == "http")
265 {
266#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
267 messages::propertyValueFormatError(asyncResp->res, destUrl,
268 "Destination");
269 return;
270#endif
271 }
272
273 std::string host = std::string(match[2].first, match[2].second);
274 std::string port = std::string(match[3].first, match[3].second);
275 std::string path = std::string(match[4].first, match[4].second);
276 if (port.empty())
277 {
278 if (uriProto == "http")
279 {
280 port = "80";
281 }
282 else
283 {
284 port = "443";
285 }
286 }
287 if (path.empty())
288 {
289 path = "/";
290 }
291
292 std::shared_ptr<Subscription> subValue =
293 std::make_shared<Subscription>(host, port, path, uriProto);
294
295 subValue->destinationUrl = destUrl;
296
297 if (subscriptionType)
298 {
299 if (*subscriptionType != "RedfishEvent")
300 {
301 messages::propertyValueNotInList(asyncResp->res,
302 *subscriptionType,
303 "SubscriptionType");
304 return;
305 }
306 subValue->subscriptionType = *subscriptionType;
AppaRao Puli144b6312020-08-03 22:23:12 +0530307 }
308 else
309 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700310 subValue->subscriptionType = "RedfishEvent"; // Default
311 }
312
313 if (protocol != "Redfish")
314 {
315 messages::propertyValueNotInList(asyncResp->res, protocol,
316 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530317 return;
318 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700319 subValue->protocol = protocol;
AppaRao Puli156d6b02020-04-25 06:04:05 +0530320
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700321 if (eventFormatType2)
322 {
323 if (std::find(supportedEvtFormatTypes.begin(),
324 supportedEvtFormatTypes.end(),
325 *eventFormatType2) ==
326 supportedEvtFormatTypes.end())
327 {
328 messages::propertyValueNotInList(asyncResp->res,
329 *eventFormatType2,
330 "EventFormatType");
331 return;
332 }
333 subValue->eventFormatType = *eventFormatType2;
334 }
335 else
336 {
337 // If not specified, use default "Event"
338 subValue->eventFormatType = "Event";
339 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530340
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700341 if (context)
342 {
343 subValue->customText = *context;
344 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530345
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700346 if (headers)
347 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700348 for (const nlohmann::json& headerChunk : *headers)
349 {
350 for (const auto& item : headerChunk.items())
351 {
352 const std::string* value =
353 item.value().get_ptr<const std::string*>();
354 if (value == nullptr)
355 {
356 messages::propertyValueFormatError(
357 asyncResp->res, item.value().dump(2, true),
358 "HttpHeaders/" + item.key());
359 return;
360 }
361 subValue->httpHeaders.set(item.key(), *value);
362 }
363 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700364 }
365
366 if (regPrefixes)
367 {
368 for (const std::string& it : *regPrefixes)
369 {
370 if (std::find(supportedRegPrefixes.begin(),
371 supportedRegPrefixes.end(),
372 it) == supportedRegPrefixes.end())
373 {
374 messages::propertyValueNotInList(
375 asyncResp->res, it, "RegistryPrefixes");
376 return;
377 }
378 }
379 subValue->registryPrefixes = *regPrefixes;
380 }
381
382 if (resTypes)
383 {
384 for (const std::string& it : *resTypes)
385 {
386 if (std::find(supportedResourceTypes.begin(),
387 supportedResourceTypes.end(),
388 it) == supportedResourceTypes.end())
389 {
390 messages::propertyValueNotInList(asyncResp->res, it,
391 "ResourceTypes");
392 return;
393 }
394 }
395 subValue->resourceTypes = *resTypes;
396 }
397
398 if (msgIds)
399 {
400 std::vector<std::string> registryPrefix;
401
402 // If no registry prefixes are mentioned, consider all
403 // supported prefixes
404 if (subValue->registryPrefixes.empty())
405 {
406 registryPrefix.assign(supportedRegPrefixes.begin(),
407 supportedRegPrefixes.end());
408 }
409 else
410 {
411 registryPrefix = subValue->registryPrefixes;
412 }
413
414 for (const std::string& id : *msgIds)
415 {
416 bool validId = false;
417
418 // Check for Message ID in each of the selected Registry
419 for (const std::string& it : registryPrefix)
420 {
Ed Tanous26702d02021-11-03 15:02:33 -0700421 const std::span<
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700422 const redfish::message_registries::MessageEntry>
423 registry = redfish::message_registries::
424 getRegistryFromPrefix(it);
425
426 if (std::any_of(
Ed Tanous26702d02021-11-03 15:02:33 -0700427 registry.begin(), registry.end(),
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700428 [&id](const redfish::message_registries::
429 MessageEntry& messageEntry) {
430 return !id.compare(messageEntry.first);
431 }))
432 {
433 validId = true;
434 break;
435 }
436 }
437
438 if (!validId)
439 {
440 messages::propertyValueNotInList(asyncResp->res, id,
441 "MessageIds");
442 return;
443 }
444 }
445
446 subValue->registryMsgIds = *msgIds;
447 }
448
449 if (retryPolicy)
450 {
451 if (std::find(supportedRetryPolicies.begin(),
452 supportedRetryPolicies.end(),
453 *retryPolicy) == supportedRetryPolicies.end())
454 {
455 messages::propertyValueNotInList(asyncResp->res,
456 *retryPolicy,
457 "DeliveryRetryPolicy");
458 return;
459 }
460 subValue->retryPolicy = *retryPolicy;
461 }
462 else
463 {
464 // Default "TerminateAfterRetries"
465 subValue->retryPolicy = "TerminateAfterRetries";
466 }
467
468 if (mrdJsonArray)
469 {
470 for (nlohmann::json& mrdObj : *mrdJsonArray)
471 {
472 std::string mrdUri;
473 if (json_util::getValueFromJsonObject(
474 mrdObj, "@odata.id", mrdUri))
475 {
476 subValue->metricReportDefinitions.emplace_back(
477 mrdUri);
478 }
479 else
480 {
481 messages::propertyValueFormatError(
482 asyncResp->res,
483 mrdObj.dump(
484 2, ' ', true,
485 nlohmann::json::error_handler_t::replace),
486 "MetricReportDefinitions");
487 return;
488 }
489 }
490 }
491
492 std::string id =
493 EventServiceManager::getInstance().addSubscription(
494 subValue);
495 if (id.empty())
496 {
497 messages::internalError(asyncResp->res);
498 return;
499 }
500
501 messages::created(asyncResp->res);
502 asyncResp->res.addHeader(
503 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
504 });
505}
506
507inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530508{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500509 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700510 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700511 .methods(boost::beast::http::verb::get)(
512 [](const crow::Request&,
513 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
514 const std::string& param) {
515 std::shared_ptr<Subscription> subValue =
516 EventServiceManager::getInstance().getSubscription(param);
517 if (subValue == nullptr)
518 {
519 asyncResp->res.result(
520 boost::beast::http::status::not_found);
521 return;
522 }
523 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530524
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700525 asyncResp->res.jsonValue = {
526 {"@odata.type",
527 "#EventDestination.v1_7_0.EventDestination"},
528 {"Protocol", "Redfish"}};
529 asyncResp->res.jsonValue["@odata.id"] =
530 "/redfish/v1/EventService/Subscriptions/" + id;
531 asyncResp->res.jsonValue["Id"] = id;
532 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
533 asyncResp->res.jsonValue["Destination"] =
534 subValue->destinationUrl;
535 asyncResp->res.jsonValue["Context"] = subValue->customText;
536 asyncResp->res.jsonValue["SubscriptionType"] =
537 subValue->subscriptionType;
Ed Tanousad22fef2021-09-13 13:07:32 -0700538 asyncResp->res.jsonValue["HttpHeaders"] =
539 nlohmann::json::array();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700540 asyncResp->res.jsonValue["EventFormatType"] =
541 subValue->eventFormatType;
542 asyncResp->res.jsonValue["RegistryPrefixes"] =
543 subValue->registryPrefixes;
544 asyncResp->res.jsonValue["ResourceTypes"] =
545 subValue->resourceTypes;
zhanghch058d1b46d2021-04-01 11:18:24 +0800546
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700547 asyncResp->res.jsonValue["MessageIds"] =
548 subValue->registryMsgIds;
549 asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
550 subValue->retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530551
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700552 std::vector<nlohmann::json> mrdJsonArray;
553 for (const auto& mdrUri : subValue->metricReportDefinitions)
554 {
555 mrdJsonArray.push_back({{"@odata.id", mdrUri}});
556 }
557 asyncResp->res.jsonValue["MetricReportDefinitions"] =
558 mrdJsonArray;
559 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500560 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700561 // The below privilege is wrong, it should be ConfigureManager OR
562 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500563 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700564 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700565 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700566 .methods(boost::beast::http::verb::patch)(
567 [](const crow::Request& req,
568 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
569 const std::string& param) {
570 std::shared_ptr<Subscription> subValue =
571 EventServiceManager::getInstance().getSubscription(param);
572 if (subValue == nullptr)
573 {
574 asyncResp->res.result(
575 boost::beast::http::status::not_found);
576 return;
577 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530578
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700579 std::optional<std::string> context;
580 std::optional<std::string> retryPolicy;
581 std::optional<std::vector<nlohmann::json>> headers;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500582
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700583 if (!json_util::readJson(req, asyncResp->res, "Context",
584 context, "DeliveryRetryPolicy",
585 retryPolicy, "HttpHeaders", headers))
586 {
587 return;
588 }
AppaRao Puli144b6312020-08-03 22:23:12 +0530589
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700590 if (context)
591 {
592 subValue->customText = *context;
593 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530594
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700595 if (headers)
596 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700597 boost::beast::http::fields fields;
598 for (const nlohmann::json& headerChunk : *headers)
599 {
600 for (auto& it : headerChunk.items())
601 {
602 const std::string* value =
603 it.value().get_ptr<const std::string*>();
604 if (value == nullptr)
605 {
606 messages::propertyValueFormatError(
607 asyncResp->res,
608 it.value().dump(2, ' ', true),
609 "HttpHeaders/" + it.key());
610 return;
611 }
612 fields.set(it.key(), *value);
613 }
614 }
615 subValue->httpHeaders = fields;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700616 }
zhanghch058d1b46d2021-04-01 11:18:24 +0800617
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700618 if (retryPolicy)
619 {
620 if (std::find(supportedRetryPolicies.begin(),
621 supportedRetryPolicies.end(),
622 *retryPolicy) == supportedRetryPolicies.end())
623 {
624 messages::propertyValueNotInList(asyncResp->res,
625 *retryPolicy,
626 "DeliveryRetryPolicy");
627 return;
628 }
629 subValue->retryPolicy = *retryPolicy;
630 subValue->updateRetryPolicy();
631 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530632
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700633 EventServiceManager::getInstance().updateSubscriptionData();
634 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500635 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700636 // The below privilege is wrong, it should be ConfigureManager OR
637 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500638 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700639 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700640 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700641 .methods(boost::beast::http::verb::delete_)(
642 [](const crow::Request&,
643 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
644 const std::string& param) {
645 if (!EventServiceManager::getInstance().isSubscriptionExist(
646 param))
647 {
648 asyncResp->res.result(
649 boost::beast::http::status::not_found);
650 return;
651 }
652 EventServiceManager::getInstance().deleteSubscription(param);
653 });
654}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530655
656} // namespace redfish