blob: fd26864ea351dd2cbaed8188875df2b1f4943b0d [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2020 Intel Corporation
AppaRao Pulie5aaf042020-03-20 01:05:52 +05304#pragma once
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
AppaRao Pulib52664e2020-04-09 21:36:51 +05306#include "event_service_manager.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -07007#include "generated/enums/event_service.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "http/utility.hpp"
9#include "logging.hpp"
10#include "query.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010011#include "registries.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "registries/privilege_registry.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010013#include "registries_selector.hpp"
Chicago Duan3d307082020-11-26 14:12:12 +080014#include "snmp_trap_event_clients.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010015#include "utils/json_utils.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053016
Ed Tanous601c71a2021-09-08 16:40:12 -070017#include <boost/beast/http/fields.hpp>
Chicago Duan3d307082020-11-26 14:12:12 +080018#include <boost/system/error_code.hpp>
Ed Tanousa716aa72023-08-01 11:35:53 -070019#include <boost/url/parse.hpp>
Chicago Duan3d307082020-11-26 14:12:12 +080020#include <sdbusplus/unpack_properties.hpp>
21#include <utils/dbus_utils.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070022
Chicago Duan3d307082020-11-26 14:12:12 +080023#include <charconv>
24#include <memory>
Myung Bae5064a252024-10-04 09:34:25 -070025#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070026#include <ranges>
Patrick Williams1e270c52021-12-04 06:06:56 -060027#include <span>
Chicago Duan3d307082020-11-26 14:12:12 +080028#include <string>
Ed Tanousa14c9112024-09-04 10:46:47 -070029#include <vector>
Patrick Williams1e270c52021-12-04 06:06:56 -060030
AppaRao Pulie5aaf042020-03-20 01:05:52 +053031namespace redfish
32{
33
AppaRao Puli156d6b02020-04-25 06:04:05 +053034static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
35 eventFormatType, metricReportFormatType};
Myung Baefb546102024-10-29 10:21:26 -050036static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
37 "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053038static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
39 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
40
Myung Baefb546102024-10-29 10:21:26 -050041static constexpr const std::array<const char*, 2> supportedResourceTypes = {
42 "Task", "Heartbeat"};
Sunitha Harishe56f2542020-07-22 02:38:59 -050043
John Edward Broadbent7e860f12021-04-08 15:57:16 -070044inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053045{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070046 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070047 .privileges(redfish::privileges::getEventService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -040048 .methods(
49 boost::beast::http::verb::
50 get)([&app](
51 const crow::Request& req,
52 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
53 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
54 {
55 return;
56 }
Ed Tanous14766872022-03-15 10:44:42 -070057
Patrick Williamsbd79bce2024-08-16 15:22:20 -040058 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
59 asyncResp->res.jsonValue["@odata.type"] =
60 "#EventService.v1_5_0.EventService";
61 asyncResp->res.jsonValue["Id"] = "EventService";
62 asyncResp->res.jsonValue["Name"] = "Event Service";
63 asyncResp->res.jsonValue["ServerSentEventUri"] =
64 "/redfish/v1/EventService/SSE";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000065
Patrick Williamsbd79bce2024-08-16 15:22:20 -040066 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
67 "/redfish/v1/EventService/Subscriptions";
68 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
69 ["target"] =
70 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053071
Patrick Williamsbd79bce2024-08-16 15:22:20 -040072 const persistent_data::EventServiceConfig eventServiceConfig =
73 persistent_data::EventServiceStore::getInstance()
74 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080075
Patrick Williamsbd79bce2024-08-16 15:22:20 -040076 asyncResp->res.jsonValue["Status"]["State"] =
77 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
78 asyncResp->res.jsonValue["ServiceEnabled"] =
79 eventServiceConfig.enabled;
80 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
81 eventServiceConfig.retryAttempts;
82 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
83 eventServiceConfig.retryTimeoutInterval;
84 asyncResp->res.jsonValue["EventFormatTypes"] =
85 supportedEvtFormatTypes;
86 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
87 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053088
Patrick Williamsbd79bce2024-08-16 15:22:20 -040089 nlohmann::json::object_t supportedSSEFilters;
90 supportedSSEFilters["EventFormatType"] = true;
91 supportedSSEFilters["MessageId"] = true;
92 supportedSSEFilters["MetricReportDefinition"] = true;
93 supportedSSEFilters["RegistryPrefix"] = true;
94 supportedSSEFilters["OriginResource"] = false;
95 supportedSSEFilters["ResourceType"] = false;
AppaRao Puli7d1cc382020-05-16 02:42:22 +053096
Patrick Williamsbd79bce2024-08-16 15:22:20 -040097 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
98 std::move(supportedSSEFilters);
99 });
Ayushi Smriti07941a82020-05-21 15:55:34 +0530100
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700101 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -0700102 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700103 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700104 [&app](const crow::Request& req,
105 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400106 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
107 {
108 return;
109 }
110 std::optional<bool> serviceEnabled;
111 std::optional<uint32_t> retryAttemps;
112 std::optional<uint32_t> retryInterval;
Myung Baeafc474a2024-10-09 00:53:29 -0700113 if (!json_util::readJsonPatch( //
114 req, asyncResp->res, //
115 "DeliveryRetryAttempts", retryAttemps, //
116 "DeliveryRetryIntervalSeconds", retryInterval, //
117 "ServiceEnabled", serviceEnabled //
118 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400119 {
120 return;
121 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530122
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400123 persistent_data::EventServiceConfig eventServiceConfig =
124 persistent_data::EventServiceStore::getInstance()
125 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700126
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400127 if (serviceEnabled)
128 {
129 eventServiceConfig.enabled = *serviceEnabled;
130 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500131
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400132 if (retryAttemps)
133 {
134 // Supported range [1-3]
135 if ((*retryAttemps < 1) || (*retryAttemps > 3))
136 {
137 messages::queryParameterOutOfRange(
138 asyncResp->res, std::to_string(*retryAttemps),
139 "DeliveryRetryAttempts", "[1-3]");
140 }
141 else
142 {
143 eventServiceConfig.retryAttempts = *retryAttemps;
144 }
145 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530146
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400147 if (retryInterval)
148 {
149 // Supported range [5 - 180]
150 if ((*retryInterval < 5) || (*retryInterval > 180))
151 {
152 messages::queryParameterOutOfRange(
153 asyncResp->res, std::to_string(*retryInterval),
154 "DeliveryRetryIntervalSeconds", "[5-180]");
155 }
156 else
157 {
158 eventServiceConfig.retryTimeoutInterval =
159 *retryInterval;
160 }
161 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700162
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400163 EventServiceManager::getInstance().setEventServiceConfig(
164 eventServiceConfig);
165 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700166}
167
168inline void requestRoutesSubmitTestEvent(App& app)
169{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700170 BMCWEB_ROUTE(
171 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700172 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700173 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700174 [&app](const crow::Request& req,
175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400176 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
177 {
178 return;
179 }
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530180
181 TestEvent testEvent;
182 // clang-format off
183 if (!json_util::readJsonAction(
184 req, asyncResp->res,
185 "EventGroupId", testEvent.eventGroupId,
186 "EventId", testEvent.eventId,
187 "EventTimestamp", testEvent.eventTimestamp,
188 "Message", testEvent.message,
189 "MessageArgs", testEvent.messageArgs,
190 "MessageId", testEvent.messageId,
191 "OriginOfCondition", testEvent.originOfCondition,
192 "Resolution", testEvent.resolution,
193 "Severity", testEvent.severity))
194 {
195 return;
196 }
197 // clang-format on
198
199 if (!EventServiceManager::getInstance().sendTestEventLog(
200 testEvent))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400201 {
202 messages::serviceDisabled(asyncResp->res,
203 "/redfish/v1/EventService/");
204 return;
205 }
206 asyncResp->res.result(boost::beast::http::status::no_content);
207 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700208}
209
Chicago Duan3d307082020-11-26 14:12:12 +0800210inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700211 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800212 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
213 const dbus::utility::ManagedObjectType& resp)
214{
215 if (ec)
216 {
Ed Tanous13061012023-07-25 11:12:19 -0700217 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800218 {
219 // This is an optional process so just return if it isn't there
220 return;
221 }
222
Ed Tanous62598e32023-07-17 17:06:25 -0700223 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800224 messages::internalError(asyncResp->res);
225 return;
226 }
227 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
228 for (const auto& objpath : resp)
229 {
230 sdbusplus::message::object_path path(objpath.first);
231 const std::string snmpId = path.filename();
232 if (snmpId.empty())
233 {
Ed Tanous62598e32023-07-17 17:06:25 -0700234 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800235 messages::internalError(asyncResp->res);
236 return;
237 }
238
239 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
240 }
241}
242
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700243inline void requestRoutesEventDestinationCollection(App& app)
244{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000245 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700246 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700247 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700248 [&app](const crow::Request& req,
249 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400250 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
251 {
252 return;
253 }
254 asyncResp->res.jsonValue["@odata.type"] =
255 "#EventDestinationCollection.EventDestinationCollection";
256 asyncResp->res.jsonValue["@odata.id"] =
257 "/redfish/v1/EventService/Subscriptions";
258 asyncResp->res.jsonValue["Name"] =
259 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700260
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400261 nlohmann::json& memberArray =
262 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700263
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400264 std::vector<std::string> subscripIds =
265 EventServiceManager::getInstance().getAllIDs();
266 memberArray = nlohmann::json::array();
267 asyncResp->res.jsonValue["Members@odata.count"] =
268 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700269
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400270 for (const std::string& id : subscripIds)
271 {
272 nlohmann::json::object_t member;
273 member["@odata.id"] = boost::urls::format(
274 "/redfish/v1/EventService/Subscriptions/{}" + id);
275 memberArray.emplace_back(std::move(member));
276 }
277 crow::connections::systemBus->async_method_call(
278 [asyncResp](const boost::system::error_code& ec,
279 const dbus::utility::ManagedObjectType& resp) {
280 doSubscriptionCollection(ec, asyncResp, resp);
281 },
282 "xyz.openbmc_project.Network.SNMP",
283 "/xyz/openbmc_project/network/snmp/manager",
284 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
285 });
Chicago Duan3d307082020-11-26 14:12:12 +0800286
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700287 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500288 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400289 .methods(
290 boost::beast::http::verb::
291 post)([&app](
292 const crow::Request& req,
293 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
294 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
295 {
296 return;
297 }
298 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
299 maxNoOfSubscriptions)
300 {
301 messages::eventSubscriptionLimitExceeded(asyncResp->res);
302 return;
303 }
304 std::string destUrl;
305 std::string protocol;
306 std::optional<bool> verifyCertificate;
307 std::optional<std::string> context;
308 std::optional<std::string> subscriptionType;
309 std::optional<std::string> eventFormatType2;
310 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700311 std::optional<bool> sendHeartbeat;
312 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400313 std::optional<std::vector<std::string>> msgIds;
314 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700315 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400316 std::optional<std::vector<std::string>> resTypes;
317 std::optional<std::vector<nlohmann::json::object_t>> headers;
318 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800319
Myung Baeafc474a2024-10-09 00:53:29 -0700320 if (!json_util::readJsonPatch( //
321 req, asyncResp->res, //
322 "Context", context, //
323 "DeliveryRetryPolicy", retryPolicy, //
324 "Destination", destUrl, //
325 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700326 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700327 "HttpHeaders", headers, //
328 "MessageIds", msgIds, //
329 "MetricReportDefinitions", mrdJsonArray, //
330 "OriginResources", originResources, //
331 "Protocol", protocol, //
332 "RegistryPrefixes", regPrefixes, //
333 "ResourceTypes", resTypes, //
Myung Bae5064a252024-10-04 09:34:25 -0700334 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700335 "SubscriptionType", subscriptionType, //
336 "VerifyCertificate", verifyCertificate //
337 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800338 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700339 return;
340 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700341 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800342
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400343 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
344 static constexpr const uint16_t maxDestinationSize = 2000;
345 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800346 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400347 messages::stringValueTooLong(asyncResp->res, "Destination",
348 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700349 return;
350 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700351
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400352 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700353 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400354 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700355 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400356 messages::propertyValueConflict(
357 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530358 return;
359 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800360 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530361
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400362 boost::system::result<boost::urls::url> url =
363 boost::urls::parse_absolute_uri(destUrl);
364 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800365 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400366 BMCWEB_LOG_WARNING(
367 "Failed to validate and split destination url");
368 messages::propertyValueFormatError(asyncResp->res, destUrl,
369 "Destination");
370 return;
371 }
372 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800373
374 // port_number returns zero if it is not a valid representable port
375 if (url->has_port() && url->port_number() == 0)
376 {
377 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
378 url->port());
379 messages::propertyValueFormatError(asyncResp->res, destUrl,
380 "Destination");
381 return;
382 }
383
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400384 crow::utility::setProtocolDefaults(*url, protocol);
385 crow::utility::setPortDefaults(*url);
386
387 if (url->path().empty())
388 {
389 url->set_path("/");
390 }
391
392 if (url->has_userinfo())
393 {
394 messages::propertyValueFormatError(asyncResp->res, destUrl,
395 "Destination");
396 return;
397 }
398
399 if (protocol == "SNMPv2c")
400 {
401 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700402 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400403 messages::propertyValueConflict(asyncResp->res, "Context",
404 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530405 return;
406 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400407 if (eventFormatType2)
408 {
409 messages::propertyValueConflict(
410 asyncResp->res, "EventFormatType", "Protocol");
411 return;
412 }
413 if (retryPolicy)
414 {
415 messages::propertyValueConflict(asyncResp->res,
416 "RetryPolicy", "Protocol");
417 return;
418 }
Myung Bae5064a252024-10-04 09:34:25 -0700419 if (sendHeartbeat)
420 {
421 messages::propertyValueConflict(
422 asyncResp->res, "SendHeartbeat", "Protocol");
423 return;
424 }
425 if (hbIntervalMinutes)
426 {
427 messages::propertyValueConflict(
428 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
429 return;
430 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400431 if (msgIds)
432 {
433 messages::propertyValueConflict(asyncResp->res,
434 "MessageIds", "Protocol");
435 return;
436 }
437 if (regPrefixes)
438 {
439 messages::propertyValueConflict(
440 asyncResp->res, "RegistryPrefixes", "Protocol");
441 return;
442 }
443 if (resTypes)
444 {
445 messages::propertyValueConflict(
446 asyncResp->res, "ResourceTypes", "Protocol");
447 return;
448 }
449 if (headers)
450 {
451 messages::propertyValueConflict(asyncResp->res,
452 "HttpHeaders", "Protocol");
453 return;
454 }
455 if (mrdJsonArray)
456 {
457 messages::propertyValueConflict(
458 asyncResp->res, "MetricReportDefinitions", "Protocol");
459 return;
460 }
461 if (url->scheme() != "snmp")
462 {
463 messages::propertyValueConflict(asyncResp->res,
464 "Destination", "Protocol");
465 return;
466 }
467
468 addSnmpTrapClient(asyncResp, url->host_address(),
469 url->port_number());
470 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700471 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700472
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400473 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700474 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400475 std::make_shared<persistent_data::UserSubscription>(), *url,
476 app.ioContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400477
478 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700479 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400480 if (*subscriptionType != "RedfishEvent")
481 {
482 messages::propertyValueNotInList(
483 asyncResp->res, *subscriptionType, "SubscriptionType");
484 return;
485 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400486 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800487 }
488 else
489 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700490 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400491 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800492 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530493
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400494 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800495 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400496 messages::propertyValueNotInList(asyncResp->res, protocol,
497 "Protocol");
498 return;
499 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400500 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800501
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400502 if (verifyCertificate)
503 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400504 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400505 }
506
507 if (eventFormatType2)
508 {
509 if (std::ranges::find(supportedEvtFormatTypes,
510 *eventFormatType2) ==
511 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700512 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400513 messages::propertyValueNotInList(
514 asyncResp->res, *eventFormatType2, "EventFormatType");
515 return;
516 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400517 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400518 }
519 else
520 {
521 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400522 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400523 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700524
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400525 if (context)
526 {
527 // This value is selected arbitrarily.
528 constexpr const size_t maxContextSize = 256;
529 if (context->size() > maxContextSize)
530 {
531 messages::stringValueTooLong(asyncResp->res, "Context",
532 maxContextSize);
533 return;
534 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400535 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400536 }
537
538 if (headers)
539 {
540 size_t cumulativeLen = 0;
541
542 for (const nlohmann::json::object_t& headerChunk : *headers)
543 {
544 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700545 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400546 const std::string* value =
547 item.second.get_ptr<const std::string*>();
548 if (value == nullptr)
549 {
550 messages::propertyValueFormatError(
551 asyncResp->res, item.second,
552 "HttpHeaders/" + item.first);
553 return;
554 }
555 // Adding a new json value is the size of the key, +
556 // the size of the value + 2 * 2 quotes for each, +
557 // the colon and space between. example:
558 // "key": "value"
559 cumulativeLen += item.first.size() + value->size() + 6;
560 // This value is selected to mirror http_connection.hpp
561 constexpr const uint16_t maxHeaderSizeED = 8096;
562 if (cumulativeLen > maxHeaderSizeED)
563 {
564 messages::arraySizeTooLong(
565 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
566 return;
567 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400568 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400569 }
570 }
571 }
572
573 if (regPrefixes)
574 {
575 for (const std::string& it : *regPrefixes)
576 {
577 if (std::ranges::find(supportedRegPrefixes, it) ==
578 supportedRegPrefixes.end())
579 {
580 messages::propertyValueNotInList(asyncResp->res, it,
581 "RegistryPrefixes");
582 return;
583 }
584 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400585 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400586 }
587
Ed Tanousa14c9112024-09-04 10:46:47 -0700588 if (originResources)
589 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400590 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700591 }
592
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400593 if (resTypes)
594 {
595 for (const std::string& it : *resTypes)
596 {
597 if (std::ranges::find(supportedResourceTypes, it) ==
598 supportedResourceTypes.end())
599 {
600 messages::propertyValueNotInList(asyncResp->res, it,
601 "ResourceTypes");
602 return;
603 }
604 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400605 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400606 }
607
608 if (msgIds)
609 {
610 std::vector<std::string> registryPrefix;
611
612 // If no registry prefixes are mentioned, consider all
613 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400614 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400615 {
616 registryPrefix.assign(supportedRegPrefixes.begin(),
617 supportedRegPrefixes.end());
618 }
619 else
620 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400621 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400622 }
623
624 for (const std::string& id : *msgIds)
625 {
626 bool validId = false;
627
628 // Check for Message ID in each of the selected Registry
629 for (const std::string& it : registryPrefix)
630 {
631 const std::span<const redfish::registries::MessageEntry>
632 registry =
633 redfish::registries::getRegistryFromPrefix(it);
634
635 if (std::ranges::any_of(
636 registry,
637 [&id](const redfish::registries::MessageEntry&
638 messageEntry) {
639 return id == messageEntry.first;
640 }))
641 {
642 validId = true;
643 break;
644 }
645 }
646
647 if (!validId)
648 {
649 messages::propertyValueNotInList(asyncResp->res, id,
650 "MessageIds");
651 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700652 }
653 }
654
Myung Bae5fe4ef32024-10-19 09:56:02 -0400655 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400656 }
657
658 if (retryPolicy)
659 {
660 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
661 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700662 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400663 messages::propertyValueNotInList(
664 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800665 return;
666 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400667 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400668 }
669 else
670 {
671 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400672 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400673 }
Myung Bae5064a252024-10-04 09:34:25 -0700674 if (sendHeartbeat)
675 {
676 subValue->userSub->sendHeartbeat = *sendHeartbeat;
677 }
678 if (hbIntervalMinutes)
679 {
680 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
681 {
682 messages::propertyValueOutOfRange(
683 asyncResp->res, *hbIntervalMinutes,
684 "HeartbeatIntervalMinutes");
685 return;
686 }
687 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
688 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400689
690 if (mrdJsonArray)
691 {
692 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
693 {
694 std::string mrdUri;
695
696 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
697 "@odata.id", mrdUri))
698
699 {
700 return;
701 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400702 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700703 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400704 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800705 }
706
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400707 std::string id =
708 EventServiceManager::getInstance().addPushSubscription(
709 subValue);
710 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800711 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400712 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800713 return;
714 }
715
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400716 messages::created(asyncResp->res);
717 asyncResp->res.addHeader(
718 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500719
720 // schedule a heartbeat
721 if (subValue->userSub->sendHeartbeat)
722 {
723 subValue->scheduleNextHeartbeatEvent();
724 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400725 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700726}
727
728inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530729{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500730 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700731 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700732 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700733 [&app](const crow::Request& req,
734 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
735 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400736 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
737 {
738 return;
739 }
Chicago Duan3d307082020-11-26 14:12:12 +0800740
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400741 if (param.starts_with("snmp"))
742 {
743 getSnmpTrapClient(asyncResp, param);
744 return;
745 }
Chicago Duan3d307082020-11-26 14:12:12 +0800746
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400747 std::shared_ptr<Subscription> subValue =
748 EventServiceManager::getInstance().getSubscription(param);
749 if (subValue == nullptr)
750 {
751 asyncResp->res.result(
752 boost::beast::http::status::not_found);
753 return;
754 }
755 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530756
Ed Tanous4b712a22023-08-02 12:56:52 -0700757 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400758 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800759
Ed Tanous4b712a22023-08-02 12:56:52 -0700760 nlohmann::json& jVal = asyncResp->res.jsonValue;
761 jVal["@odata.type"] =
762 "#EventDestination.v1_14_1.EventDestination";
763 jVal["Protocol"] =
764 event_destination::EventDestinationProtocol::Redfish;
765 jVal["@odata.id"] = boost::urls::format(
766 "/redfish/v1/EventService/Subscriptions/{}", id);
767 jVal["Id"] = id;
768 jVal["Name"] = "Event Destination " + id;
769 jVal["Destination"] = userSub.destinationUrl;
770 jVal["Context"] = userSub.customText;
771 jVal["SubscriptionType"] = userSub.subscriptionType;
772 jVal["HttpHeaders"] = nlohmann::json::array();
773 jVal["EventFormatType"] = userSub.eventFormatType;
774 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
775 jVal["ResourceTypes"] = userSub.resourceTypes;
776
777 jVal["MessageIds"] = userSub.registryMsgIds;
778 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700779 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
780 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700781 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530782
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400783 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700784 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400785 {
786 nlohmann::json::object_t mdr;
787 mdr["@odata.id"] = mdrUri;
788 mrdJsonArray.emplace_back(std::move(mdr));
789 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700790 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400791 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500792 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700793 // The below privilege is wrong, it should be ConfigureManager OR
794 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500795 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700796 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700797 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700798 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700799 [&app](const crow::Request& req,
800 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
801 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400802 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700803 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400804 return;
805 }
806 std::shared_ptr<Subscription> subValue =
807 EventServiceManager::getInstance().getSubscription(param);
808 if (subValue == nullptr)
809 {
810 asyncResp->res.result(
811 boost::beast::http::status::not_found);
812 return;
813 }
814
815 std::optional<std::string> context;
816 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700817 std::optional<bool> sendHeartbeat;
818 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400819 std::optional<bool> verifyCertificate;
820 std::optional<std::vector<nlohmann::json::object_t>> headers;
821
Myung Baeafc474a2024-10-09 00:53:29 -0700822 if (!json_util::readJsonPatch( //
823 req, asyncResp->res, //
824 "Context", context, //
825 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700826 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700827 "HttpHeaders", headers, //
Myung Bae5064a252024-10-04 09:34:25 -0700828 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700829 "VerifyCertificate", verifyCertificate //
830 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400831 {
832 return;
833 }
834
835 if (context)
836 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400837 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400838 }
839
840 if (headers)
841 {
842 boost::beast::http::fields fields;
843 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700844 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400845 for (const auto& it : headerChunk)
846 {
847 const std::string* value =
848 it.second.get_ptr<const std::string*>();
849 if (value == nullptr)
850 {
851 messages::propertyValueFormatError(
852 asyncResp->res, it.second,
853 "HttpHeaders/" + it.first);
854 return;
855 }
856 fields.set(it.first, *value);
857 }
858 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400859 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400860 }
861
862 if (retryPolicy)
863 {
864 if (std::ranges::find(supportedRetryPolicies,
865 *retryPolicy) ==
866 supportedRetryPolicies.end())
867 {
868 messages::propertyValueNotInList(asyncResp->res,
869 *retryPolicy,
870 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700871 return;
872 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400873 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700874 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530875
Myung Bae5064a252024-10-04 09:34:25 -0700876 if (sendHeartbeat)
877 {
878 subValue->userSub->sendHeartbeat = *sendHeartbeat;
879 }
880 if (hbIntervalMinutes)
881 {
882 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
883 {
884 messages::propertyValueOutOfRange(
885 asyncResp->res, *hbIntervalMinutes,
886 "HeartbeatIntervalMinutes");
887 return;
888 }
889 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
890 }
891
Myung Baefb546102024-10-29 10:21:26 -0500892 if (hbIntervalMinutes || sendHeartbeat)
893 {
894 // if Heartbeat interval or send heart were changed, cancel
895 // the heartbeat timer if running and start a new heartbeat
896 // if needed
897 subValue->heartbeatParametersChanged();
898 }
899
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400900 if (verifyCertificate)
901 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400902 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400903 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700904
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400905 EventServiceManager::getInstance().updateSubscriptionData();
906 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500907 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700908 // The below privilege is wrong, it should be ConfigureManager OR
909 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500910 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700911 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700912 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700913 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700914 [&app](const crow::Request& req,
915 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
916 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400917 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
918 {
919 return;
920 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700921 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400922 if (param.starts_with("snmp"))
923 {
924 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700925 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400926 return;
927 }
Chicago Duan3d307082020-11-26 14:12:12 +0800928
Ed Tanous4b712a22023-08-02 12:56:52 -0700929 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400930 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700931 messages::resourceNotFound(asyncResp->res,
932 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400933 return;
934 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700935 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400936 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700937}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530938
939} // namespace redfish