blob: cf32bcf344a3eba8bcc1da441c76fbb58623599c [file] [log] [blame]
AppaRao Pulie5aaf042020-03-20 01:05:52 +05301/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2020 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
AppaRao Pulie5aaf042020-03-20 01:05:52 +053015*/
16#pragma once
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080017#include "app.hpp"
AppaRao Pulib52664e2020-04-09 21:36:51 +053018#include "event_service_manager.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070019#include "generated/enums/event_service.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "http/utility.hpp"
21#include "logging.hpp"
22#include "query.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010023#include "registries.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "registries/privilege_registry.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010025#include "registries_selector.hpp"
Chicago Duan3d307082020-11-26 14:12:12 +080026#include "snmp_trap_event_clients.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010027#include "utils/json_utils.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053028
Ed Tanous601c71a2021-09-08 16:40:12 -070029#include <boost/beast/http/fields.hpp>
Chicago Duan3d307082020-11-26 14:12:12 +080030#include <boost/system/error_code.hpp>
Ed Tanousa716aa72023-08-01 11:35:53 -070031#include <boost/url/parse.hpp>
Chicago Duan3d307082020-11-26 14:12:12 +080032#include <sdbusplus/unpack_properties.hpp>
33#include <utils/dbus_utils.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070034
Chicago Duan3d307082020-11-26 14:12:12 +080035#include <charconv>
36#include <memory>
Myung Bae5064a252024-10-04 09:34:25 -070037#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070038#include <ranges>
Patrick Williams1e270c52021-12-04 06:06:56 -060039#include <span>
Chicago Duan3d307082020-11-26 14:12:12 +080040#include <string>
Ed Tanousa14c9112024-09-04 10:46:47 -070041#include <vector>
Patrick Williams1e270c52021-12-04 06:06:56 -060042
AppaRao Pulie5aaf042020-03-20 01:05:52 +053043namespace redfish
44{
45
AppaRao Puli156d6b02020-04-25 06:04:05 +053046static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
47 eventFormatType, metricReportFormatType};
Myung Baefb546102024-10-29 10:21:26 -050048static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
49 "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053050static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
51 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
52
Myung Baefb546102024-10-29 10:21:26 -050053static constexpr const std::array<const char*, 2> supportedResourceTypes = {
54 "Task", "Heartbeat"};
Sunitha Harishe56f2542020-07-22 02:38:59 -050055
John Edward Broadbent7e860f12021-04-08 15:57:16 -070056inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053057{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070058 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070059 .privileges(redfish::privileges::getEventService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -040060 .methods(
61 boost::beast::http::verb::
62 get)([&app](
63 const crow::Request& req,
64 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
65 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
66 {
67 return;
68 }
Ed Tanous14766872022-03-15 10:44:42 -070069
Patrick Williamsbd79bce2024-08-16 15:22:20 -040070 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
71 asyncResp->res.jsonValue["@odata.type"] =
72 "#EventService.v1_5_0.EventService";
73 asyncResp->res.jsonValue["Id"] = "EventService";
74 asyncResp->res.jsonValue["Name"] = "Event Service";
75 asyncResp->res.jsonValue["ServerSentEventUri"] =
76 "/redfish/v1/EventService/SSE";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000077
Patrick Williamsbd79bce2024-08-16 15:22:20 -040078 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
79 "/redfish/v1/EventService/Subscriptions";
80 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
81 ["target"] =
82 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053083
Patrick Williamsbd79bce2024-08-16 15:22:20 -040084 const persistent_data::EventServiceConfig eventServiceConfig =
85 persistent_data::EventServiceStore::getInstance()
86 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080087
Patrick Williamsbd79bce2024-08-16 15:22:20 -040088 asyncResp->res.jsonValue["Status"]["State"] =
89 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
90 asyncResp->res.jsonValue["ServiceEnabled"] =
91 eventServiceConfig.enabled;
92 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
93 eventServiceConfig.retryAttempts;
94 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
95 eventServiceConfig.retryTimeoutInterval;
96 asyncResp->res.jsonValue["EventFormatTypes"] =
97 supportedEvtFormatTypes;
98 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
99 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530100
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400101 nlohmann::json::object_t supportedSSEFilters;
102 supportedSSEFilters["EventFormatType"] = true;
103 supportedSSEFilters["MessageId"] = true;
104 supportedSSEFilters["MetricReportDefinition"] = true;
105 supportedSSEFilters["RegistryPrefix"] = true;
106 supportedSSEFilters["OriginResource"] = false;
107 supportedSSEFilters["ResourceType"] = false;
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530108
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400109 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
110 std::move(supportedSSEFilters);
111 });
Ayushi Smriti07941a82020-05-21 15:55:34 +0530112
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700113 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -0700114 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700115 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700116 [&app](const crow::Request& req,
117 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400118 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
119 {
120 return;
121 }
122 std::optional<bool> serviceEnabled;
123 std::optional<uint32_t> retryAttemps;
124 std::optional<uint32_t> retryInterval;
Myung Baeafc474a2024-10-09 00:53:29 -0700125 if (!json_util::readJsonPatch( //
126 req, asyncResp->res, //
127 "DeliveryRetryAttempts", retryAttemps, //
128 "DeliveryRetryIntervalSeconds", retryInterval, //
129 "ServiceEnabled", serviceEnabled //
130 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400131 {
132 return;
133 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530134
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400135 persistent_data::EventServiceConfig eventServiceConfig =
136 persistent_data::EventServiceStore::getInstance()
137 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700138
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400139 if (serviceEnabled)
140 {
141 eventServiceConfig.enabled = *serviceEnabled;
142 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500143
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400144 if (retryAttemps)
145 {
146 // Supported range [1-3]
147 if ((*retryAttemps < 1) || (*retryAttemps > 3))
148 {
149 messages::queryParameterOutOfRange(
150 asyncResp->res, std::to_string(*retryAttemps),
151 "DeliveryRetryAttempts", "[1-3]");
152 }
153 else
154 {
155 eventServiceConfig.retryAttempts = *retryAttemps;
156 }
157 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530158
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400159 if (retryInterval)
160 {
161 // Supported range [5 - 180]
162 if ((*retryInterval < 5) || (*retryInterval > 180))
163 {
164 messages::queryParameterOutOfRange(
165 asyncResp->res, std::to_string(*retryInterval),
166 "DeliveryRetryIntervalSeconds", "[5-180]");
167 }
168 else
169 {
170 eventServiceConfig.retryTimeoutInterval =
171 *retryInterval;
172 }
173 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700174
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400175 EventServiceManager::getInstance().setEventServiceConfig(
176 eventServiceConfig);
177 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700178}
179
180inline void requestRoutesSubmitTestEvent(App& app)
181{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700182 BMCWEB_ROUTE(
183 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700184 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700185 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700186 [&app](const crow::Request& req,
187 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400188 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
189 {
190 return;
191 }
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530192
193 TestEvent testEvent;
194 // clang-format off
195 if (!json_util::readJsonAction(
196 req, asyncResp->res,
197 "EventGroupId", testEvent.eventGroupId,
198 "EventId", testEvent.eventId,
199 "EventTimestamp", testEvent.eventTimestamp,
200 "Message", testEvent.message,
201 "MessageArgs", testEvent.messageArgs,
202 "MessageId", testEvent.messageId,
203 "OriginOfCondition", testEvent.originOfCondition,
204 "Resolution", testEvent.resolution,
205 "Severity", testEvent.severity))
206 {
207 return;
208 }
209 // clang-format on
210
211 if (!EventServiceManager::getInstance().sendTestEventLog(
212 testEvent))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400213 {
214 messages::serviceDisabled(asyncResp->res,
215 "/redfish/v1/EventService/");
216 return;
217 }
218 asyncResp->res.result(boost::beast::http::status::no_content);
219 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700220}
221
Chicago Duan3d307082020-11-26 14:12:12 +0800222inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700223 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800224 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
225 const dbus::utility::ManagedObjectType& resp)
226{
227 if (ec)
228 {
Ed Tanous13061012023-07-25 11:12:19 -0700229 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800230 {
231 // This is an optional process so just return if it isn't there
232 return;
233 }
234
Ed Tanous62598e32023-07-17 17:06:25 -0700235 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800236 messages::internalError(asyncResp->res);
237 return;
238 }
239 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
240 for (const auto& objpath : resp)
241 {
242 sdbusplus::message::object_path path(objpath.first);
243 const std::string snmpId = path.filename();
244 if (snmpId.empty())
245 {
Ed Tanous62598e32023-07-17 17:06:25 -0700246 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800247 messages::internalError(asyncResp->res);
248 return;
249 }
250
251 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
252 }
253}
254
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700255inline void requestRoutesEventDestinationCollection(App& app)
256{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000257 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700258 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700259 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700260 [&app](const crow::Request& req,
261 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400262 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
263 {
264 return;
265 }
266 asyncResp->res.jsonValue["@odata.type"] =
267 "#EventDestinationCollection.EventDestinationCollection";
268 asyncResp->res.jsonValue["@odata.id"] =
269 "/redfish/v1/EventService/Subscriptions";
270 asyncResp->res.jsonValue["Name"] =
271 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700272
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400273 nlohmann::json& memberArray =
274 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700275
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400276 std::vector<std::string> subscripIds =
277 EventServiceManager::getInstance().getAllIDs();
278 memberArray = nlohmann::json::array();
279 asyncResp->res.jsonValue["Members@odata.count"] =
280 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700281
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400282 for (const std::string& id : subscripIds)
283 {
284 nlohmann::json::object_t member;
285 member["@odata.id"] = boost::urls::format(
286 "/redfish/v1/EventService/Subscriptions/{}" + id);
287 memberArray.emplace_back(std::move(member));
288 }
289 crow::connections::systemBus->async_method_call(
290 [asyncResp](const boost::system::error_code& ec,
291 const dbus::utility::ManagedObjectType& resp) {
292 doSubscriptionCollection(ec, asyncResp, resp);
293 },
294 "xyz.openbmc_project.Network.SNMP",
295 "/xyz/openbmc_project/network/snmp/manager",
296 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
297 });
Chicago Duan3d307082020-11-26 14:12:12 +0800298
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700299 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500300 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400301 .methods(
302 boost::beast::http::verb::
303 post)([&app](
304 const crow::Request& req,
305 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
306 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
307 {
308 return;
309 }
310 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
311 maxNoOfSubscriptions)
312 {
313 messages::eventSubscriptionLimitExceeded(asyncResp->res);
314 return;
315 }
316 std::string destUrl;
317 std::string protocol;
318 std::optional<bool> verifyCertificate;
319 std::optional<std::string> context;
320 std::optional<std::string> subscriptionType;
321 std::optional<std::string> eventFormatType2;
322 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700323 std::optional<bool> sendHeartbeat;
324 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400325 std::optional<std::vector<std::string>> msgIds;
326 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700327 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400328 std::optional<std::vector<std::string>> resTypes;
329 std::optional<std::vector<nlohmann::json::object_t>> headers;
330 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800331
Myung Baeafc474a2024-10-09 00:53:29 -0700332 if (!json_util::readJsonPatch( //
333 req, asyncResp->res, //
334 "Context", context, //
335 "DeliveryRetryPolicy", retryPolicy, //
336 "Destination", destUrl, //
337 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700338 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700339 "HttpHeaders", headers, //
340 "MessageIds", msgIds, //
341 "MetricReportDefinitions", mrdJsonArray, //
342 "OriginResources", originResources, //
343 "Protocol", protocol, //
344 "RegistryPrefixes", regPrefixes, //
345 "ResourceTypes", resTypes, //
Myung Bae5064a252024-10-04 09:34:25 -0700346 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700347 "SubscriptionType", subscriptionType, //
348 "VerifyCertificate", verifyCertificate //
349 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800350 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700351 return;
352 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700353 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800354
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400355 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
356 static constexpr const uint16_t maxDestinationSize = 2000;
357 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800358 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400359 messages::stringValueTooLong(asyncResp->res, "Destination",
360 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700361 return;
362 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700363
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400364 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700365 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400366 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700367 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400368 messages::propertyValueConflict(
369 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530370 return;
371 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800372 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530373
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400374 boost::system::result<boost::urls::url> url =
375 boost::urls::parse_absolute_uri(destUrl);
376 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800377 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400378 BMCWEB_LOG_WARNING(
379 "Failed to validate and split destination url");
380 messages::propertyValueFormatError(asyncResp->res, destUrl,
381 "Destination");
382 return;
383 }
384 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800385
386 // port_number returns zero if it is not a valid representable port
387 if (url->has_port() && url->port_number() == 0)
388 {
389 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
390 url->port());
391 messages::propertyValueFormatError(asyncResp->res, destUrl,
392 "Destination");
393 return;
394 }
395
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400396 crow::utility::setProtocolDefaults(*url, protocol);
397 crow::utility::setPortDefaults(*url);
398
399 if (url->path().empty())
400 {
401 url->set_path("/");
402 }
403
404 if (url->has_userinfo())
405 {
406 messages::propertyValueFormatError(asyncResp->res, destUrl,
407 "Destination");
408 return;
409 }
410
411 if (protocol == "SNMPv2c")
412 {
413 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700414 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400415 messages::propertyValueConflict(asyncResp->res, "Context",
416 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530417 return;
418 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400419 if (eventFormatType2)
420 {
421 messages::propertyValueConflict(
422 asyncResp->res, "EventFormatType", "Protocol");
423 return;
424 }
425 if (retryPolicy)
426 {
427 messages::propertyValueConflict(asyncResp->res,
428 "RetryPolicy", "Protocol");
429 return;
430 }
Myung Bae5064a252024-10-04 09:34:25 -0700431 if (sendHeartbeat)
432 {
433 messages::propertyValueConflict(
434 asyncResp->res, "SendHeartbeat", "Protocol");
435 return;
436 }
437 if (hbIntervalMinutes)
438 {
439 messages::propertyValueConflict(
440 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
441 return;
442 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400443 if (msgIds)
444 {
445 messages::propertyValueConflict(asyncResp->res,
446 "MessageIds", "Protocol");
447 return;
448 }
449 if (regPrefixes)
450 {
451 messages::propertyValueConflict(
452 asyncResp->res, "RegistryPrefixes", "Protocol");
453 return;
454 }
455 if (resTypes)
456 {
457 messages::propertyValueConflict(
458 asyncResp->res, "ResourceTypes", "Protocol");
459 return;
460 }
461 if (headers)
462 {
463 messages::propertyValueConflict(asyncResp->res,
464 "HttpHeaders", "Protocol");
465 return;
466 }
467 if (mrdJsonArray)
468 {
469 messages::propertyValueConflict(
470 asyncResp->res, "MetricReportDefinitions", "Protocol");
471 return;
472 }
473 if (url->scheme() != "snmp")
474 {
475 messages::propertyValueConflict(asyncResp->res,
476 "Destination", "Protocol");
477 return;
478 }
479
480 addSnmpTrapClient(asyncResp, url->host_address(),
481 url->port_number());
482 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700483 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700484
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400485 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700486 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400487 std::make_shared<persistent_data::UserSubscription>(), *url,
488 app.ioContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400489
490 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700491 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400492 if (*subscriptionType != "RedfishEvent")
493 {
494 messages::propertyValueNotInList(
495 asyncResp->res, *subscriptionType, "SubscriptionType");
496 return;
497 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400498 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800499 }
500 else
501 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700502 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400503 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800504 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530505
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400506 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800507 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400508 messages::propertyValueNotInList(asyncResp->res, protocol,
509 "Protocol");
510 return;
511 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400512 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800513
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400514 if (verifyCertificate)
515 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400516 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400517 }
518
519 if (eventFormatType2)
520 {
521 if (std::ranges::find(supportedEvtFormatTypes,
522 *eventFormatType2) ==
523 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700524 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400525 messages::propertyValueNotInList(
526 asyncResp->res, *eventFormatType2, "EventFormatType");
527 return;
528 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400529 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400530 }
531 else
532 {
533 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400534 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400535 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700536
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400537 if (context)
538 {
539 // This value is selected arbitrarily.
540 constexpr const size_t maxContextSize = 256;
541 if (context->size() > maxContextSize)
542 {
543 messages::stringValueTooLong(asyncResp->res, "Context",
544 maxContextSize);
545 return;
546 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400547 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400548 }
549
550 if (headers)
551 {
552 size_t cumulativeLen = 0;
553
554 for (const nlohmann::json::object_t& headerChunk : *headers)
555 {
556 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700557 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400558 const std::string* value =
559 item.second.get_ptr<const std::string*>();
560 if (value == nullptr)
561 {
562 messages::propertyValueFormatError(
563 asyncResp->res, item.second,
564 "HttpHeaders/" + item.first);
565 return;
566 }
567 // Adding a new json value is the size of the key, +
568 // the size of the value + 2 * 2 quotes for each, +
569 // the colon and space between. example:
570 // "key": "value"
571 cumulativeLen += item.first.size() + value->size() + 6;
572 // This value is selected to mirror http_connection.hpp
573 constexpr const uint16_t maxHeaderSizeED = 8096;
574 if (cumulativeLen > maxHeaderSizeED)
575 {
576 messages::arraySizeTooLong(
577 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
578 return;
579 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400580 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400581 }
582 }
583 }
584
585 if (regPrefixes)
586 {
587 for (const std::string& it : *regPrefixes)
588 {
589 if (std::ranges::find(supportedRegPrefixes, it) ==
590 supportedRegPrefixes.end())
591 {
592 messages::propertyValueNotInList(asyncResp->res, it,
593 "RegistryPrefixes");
594 return;
595 }
596 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400597 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400598 }
599
Ed Tanousa14c9112024-09-04 10:46:47 -0700600 if (originResources)
601 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400602 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700603 }
604
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400605 if (resTypes)
606 {
607 for (const std::string& it : *resTypes)
608 {
609 if (std::ranges::find(supportedResourceTypes, it) ==
610 supportedResourceTypes.end())
611 {
612 messages::propertyValueNotInList(asyncResp->res, it,
613 "ResourceTypes");
614 return;
615 }
616 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400617 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400618 }
619
620 if (msgIds)
621 {
622 std::vector<std::string> registryPrefix;
623
624 // If no registry prefixes are mentioned, consider all
625 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400626 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400627 {
628 registryPrefix.assign(supportedRegPrefixes.begin(),
629 supportedRegPrefixes.end());
630 }
631 else
632 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400633 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400634 }
635
636 for (const std::string& id : *msgIds)
637 {
638 bool validId = false;
639
640 // Check for Message ID in each of the selected Registry
641 for (const std::string& it : registryPrefix)
642 {
643 const std::span<const redfish::registries::MessageEntry>
644 registry =
645 redfish::registries::getRegistryFromPrefix(it);
646
647 if (std::ranges::any_of(
648 registry,
649 [&id](const redfish::registries::MessageEntry&
650 messageEntry) {
651 return id == messageEntry.first;
652 }))
653 {
654 validId = true;
655 break;
656 }
657 }
658
659 if (!validId)
660 {
661 messages::propertyValueNotInList(asyncResp->res, id,
662 "MessageIds");
663 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700664 }
665 }
666
Myung Bae5fe4ef32024-10-19 09:56:02 -0400667 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400668 }
669
670 if (retryPolicy)
671 {
672 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
673 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700674 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400675 messages::propertyValueNotInList(
676 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800677 return;
678 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400679 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400680 }
681 else
682 {
683 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400684 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400685 }
Myung Bae5064a252024-10-04 09:34:25 -0700686 if (sendHeartbeat)
687 {
688 subValue->userSub->sendHeartbeat = *sendHeartbeat;
689 }
690 if (hbIntervalMinutes)
691 {
692 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
693 {
694 messages::propertyValueOutOfRange(
695 asyncResp->res, *hbIntervalMinutes,
696 "HeartbeatIntervalMinutes");
697 return;
698 }
699 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
700 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400701
702 if (mrdJsonArray)
703 {
704 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
705 {
706 std::string mrdUri;
707
708 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
709 "@odata.id", mrdUri))
710
711 {
712 return;
713 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400714 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700715 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400716 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800717 }
718
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400719 std::string id =
720 EventServiceManager::getInstance().addPushSubscription(
721 subValue);
722 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800723 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400724 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800725 return;
726 }
727
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400728 messages::created(asyncResp->res);
729 asyncResp->res.addHeader(
730 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500731
732 // schedule a heartbeat
733 if (subValue->userSub->sendHeartbeat)
734 {
735 subValue->scheduleNextHeartbeatEvent();
736 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400737 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700738}
739
740inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530741{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500742 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700743 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700744 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700745 [&app](const crow::Request& req,
746 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
747 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400748 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
749 {
750 return;
751 }
Chicago Duan3d307082020-11-26 14:12:12 +0800752
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400753 if (param.starts_with("snmp"))
754 {
755 getSnmpTrapClient(asyncResp, param);
756 return;
757 }
Chicago Duan3d307082020-11-26 14:12:12 +0800758
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400759 std::shared_ptr<Subscription> subValue =
760 EventServiceManager::getInstance().getSubscription(param);
761 if (subValue == nullptr)
762 {
763 asyncResp->res.result(
764 boost::beast::http::status::not_found);
765 return;
766 }
767 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530768
Ed Tanous4b712a22023-08-02 12:56:52 -0700769 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400770 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800771
Ed Tanous4b712a22023-08-02 12:56:52 -0700772 nlohmann::json& jVal = asyncResp->res.jsonValue;
773 jVal["@odata.type"] =
774 "#EventDestination.v1_14_1.EventDestination";
775 jVal["Protocol"] =
776 event_destination::EventDestinationProtocol::Redfish;
777 jVal["@odata.id"] = boost::urls::format(
778 "/redfish/v1/EventService/Subscriptions/{}", id);
779 jVal["Id"] = id;
780 jVal["Name"] = "Event Destination " + id;
781 jVal["Destination"] = userSub.destinationUrl;
782 jVal["Context"] = userSub.customText;
783 jVal["SubscriptionType"] = userSub.subscriptionType;
784 jVal["HttpHeaders"] = nlohmann::json::array();
785 jVal["EventFormatType"] = userSub.eventFormatType;
786 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
787 jVal["ResourceTypes"] = userSub.resourceTypes;
788
789 jVal["MessageIds"] = userSub.registryMsgIds;
790 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700791 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
792 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700793 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530794
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400795 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700796 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400797 {
798 nlohmann::json::object_t mdr;
799 mdr["@odata.id"] = mdrUri;
800 mrdJsonArray.emplace_back(std::move(mdr));
801 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700802 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400803 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500804 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700805 // The below privilege is wrong, it should be ConfigureManager OR
806 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500807 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700808 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700809 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700810 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700811 [&app](const crow::Request& req,
812 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
813 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400814 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700815 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400816 return;
817 }
818 std::shared_ptr<Subscription> subValue =
819 EventServiceManager::getInstance().getSubscription(param);
820 if (subValue == nullptr)
821 {
822 asyncResp->res.result(
823 boost::beast::http::status::not_found);
824 return;
825 }
826
827 std::optional<std::string> context;
828 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700829 std::optional<bool> sendHeartbeat;
830 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400831 std::optional<bool> verifyCertificate;
832 std::optional<std::vector<nlohmann::json::object_t>> headers;
833
Myung Baeafc474a2024-10-09 00:53:29 -0700834 if (!json_util::readJsonPatch( //
835 req, asyncResp->res, //
836 "Context", context, //
837 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700838 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700839 "HttpHeaders", headers, //
Myung Bae5064a252024-10-04 09:34:25 -0700840 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700841 "VerifyCertificate", verifyCertificate //
842 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400843 {
844 return;
845 }
846
847 if (context)
848 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400849 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400850 }
851
852 if (headers)
853 {
854 boost::beast::http::fields fields;
855 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700856 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400857 for (const auto& it : headerChunk)
858 {
859 const std::string* value =
860 it.second.get_ptr<const std::string*>();
861 if (value == nullptr)
862 {
863 messages::propertyValueFormatError(
864 asyncResp->res, it.second,
865 "HttpHeaders/" + it.first);
866 return;
867 }
868 fields.set(it.first, *value);
869 }
870 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400871 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400872 }
873
874 if (retryPolicy)
875 {
876 if (std::ranges::find(supportedRetryPolicies,
877 *retryPolicy) ==
878 supportedRetryPolicies.end())
879 {
880 messages::propertyValueNotInList(asyncResp->res,
881 *retryPolicy,
882 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700883 return;
884 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400885 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700886 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530887
Myung Bae5064a252024-10-04 09:34:25 -0700888 if (sendHeartbeat)
889 {
890 subValue->userSub->sendHeartbeat = *sendHeartbeat;
891 }
892 if (hbIntervalMinutes)
893 {
894 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
895 {
896 messages::propertyValueOutOfRange(
897 asyncResp->res, *hbIntervalMinutes,
898 "HeartbeatIntervalMinutes");
899 return;
900 }
901 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
902 }
903
Myung Baefb546102024-10-29 10:21:26 -0500904 if (hbIntervalMinutes || sendHeartbeat)
905 {
906 // if Heartbeat interval or send heart were changed, cancel
907 // the heartbeat timer if running and start a new heartbeat
908 // if needed
909 subValue->heartbeatParametersChanged();
910 }
911
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400912 if (verifyCertificate)
913 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400914 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400915 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700916
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400917 EventServiceManager::getInstance().updateSubscriptionData();
918 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500919 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700920 // The below privilege is wrong, it should be ConfigureManager OR
921 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500922 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700923 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700924 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700925 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700926 [&app](const crow::Request& req,
927 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
928 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400929 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
930 {
931 return;
932 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700933 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400934 if (param.starts_with("snmp"))
935 {
936 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700937 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400938 return;
939 }
Chicago Duan3d307082020-11-26 14:12:12 +0800940
Ed Tanous4b712a22023-08-02 12:56:52 -0700941 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400942 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700943 messages::resourceNotFound(asyncResp->res,
944 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400945 return;
946 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700947 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400948 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700949}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530950
951} // namespace redfish