blob: 57385a2d8c5bbfc8b00aa62c516f933fb23a1cb6 [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 }
192 if (!EventServiceManager::getInstance().sendTestEventLog())
193 {
194 messages::serviceDisabled(asyncResp->res,
195 "/redfish/v1/EventService/");
196 return;
197 }
198 asyncResp->res.result(boost::beast::http::status::no_content);
199 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700200}
201
Chicago Duan3d307082020-11-26 14:12:12 +0800202inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700203 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800204 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
205 const dbus::utility::ManagedObjectType& resp)
206{
207 if (ec)
208 {
Ed Tanous13061012023-07-25 11:12:19 -0700209 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800210 {
211 // This is an optional process so just return if it isn't there
212 return;
213 }
214
Ed Tanous62598e32023-07-17 17:06:25 -0700215 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800216 messages::internalError(asyncResp->res);
217 return;
218 }
219 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
220 for (const auto& objpath : resp)
221 {
222 sdbusplus::message::object_path path(objpath.first);
223 const std::string snmpId = path.filename();
224 if (snmpId.empty())
225 {
Ed Tanous62598e32023-07-17 17:06:25 -0700226 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800227 messages::internalError(asyncResp->res);
228 return;
229 }
230
231 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
232 }
233}
234
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700235inline void requestRoutesEventDestinationCollection(App& app)
236{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000237 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700238 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700239 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700240 [&app](const crow::Request& req,
241 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400242 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
243 {
244 return;
245 }
246 asyncResp->res.jsonValue["@odata.type"] =
247 "#EventDestinationCollection.EventDestinationCollection";
248 asyncResp->res.jsonValue["@odata.id"] =
249 "/redfish/v1/EventService/Subscriptions";
250 asyncResp->res.jsonValue["Name"] =
251 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700252
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400253 nlohmann::json& memberArray =
254 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700255
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400256 std::vector<std::string> subscripIds =
257 EventServiceManager::getInstance().getAllIDs();
258 memberArray = nlohmann::json::array();
259 asyncResp->res.jsonValue["Members@odata.count"] =
260 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700261
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400262 for (const std::string& id : subscripIds)
263 {
264 nlohmann::json::object_t member;
265 member["@odata.id"] = boost::urls::format(
266 "/redfish/v1/EventService/Subscriptions/{}" + id);
267 memberArray.emplace_back(std::move(member));
268 }
269 crow::connections::systemBus->async_method_call(
270 [asyncResp](const boost::system::error_code& ec,
271 const dbus::utility::ManagedObjectType& resp) {
272 doSubscriptionCollection(ec, asyncResp, resp);
273 },
274 "xyz.openbmc_project.Network.SNMP",
275 "/xyz/openbmc_project/network/snmp/manager",
276 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
277 });
Chicago Duan3d307082020-11-26 14:12:12 +0800278
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700279 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500280 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400281 .methods(
282 boost::beast::http::verb::
283 post)([&app](
284 const crow::Request& req,
285 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
286 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
287 {
288 return;
289 }
290 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
291 maxNoOfSubscriptions)
292 {
293 messages::eventSubscriptionLimitExceeded(asyncResp->res);
294 return;
295 }
296 std::string destUrl;
297 std::string protocol;
298 std::optional<bool> verifyCertificate;
299 std::optional<std::string> context;
300 std::optional<std::string> subscriptionType;
301 std::optional<std::string> eventFormatType2;
302 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700303 std::optional<bool> sendHeartbeat;
304 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400305 std::optional<std::vector<std::string>> msgIds;
306 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700307 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400308 std::optional<std::vector<std::string>> resTypes;
309 std::optional<std::vector<nlohmann::json::object_t>> headers;
310 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800311
Myung Baeafc474a2024-10-09 00:53:29 -0700312 if (!json_util::readJsonPatch( //
313 req, asyncResp->res, //
314 "Context", context, //
315 "DeliveryRetryPolicy", retryPolicy, //
316 "Destination", destUrl, //
317 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700318 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700319 "HttpHeaders", headers, //
320 "MessageIds", msgIds, //
321 "MetricReportDefinitions", mrdJsonArray, //
322 "OriginResources", originResources, //
323 "Protocol", protocol, //
324 "RegistryPrefixes", regPrefixes, //
325 "ResourceTypes", resTypes, //
Myung Bae5064a252024-10-04 09:34:25 -0700326 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700327 "SubscriptionType", subscriptionType, //
328 "VerifyCertificate", verifyCertificate //
329 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800330 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700331 return;
332 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700333 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800334
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
336 static constexpr const uint16_t maxDestinationSize = 2000;
337 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800338 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400339 messages::stringValueTooLong(asyncResp->res, "Destination",
340 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700341 return;
342 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700343
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400344 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700345 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400346 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700347 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400348 messages::propertyValueConflict(
349 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530350 return;
351 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800352 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530353
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400354 boost::system::result<boost::urls::url> url =
355 boost::urls::parse_absolute_uri(destUrl);
356 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800357 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400358 BMCWEB_LOG_WARNING(
359 "Failed to validate and split destination url");
360 messages::propertyValueFormatError(asyncResp->res, destUrl,
361 "Destination");
362 return;
363 }
364 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800365
366 // port_number returns zero if it is not a valid representable port
367 if (url->has_port() && url->port_number() == 0)
368 {
369 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
370 url->port());
371 messages::propertyValueFormatError(asyncResp->res, destUrl,
372 "Destination");
373 return;
374 }
375
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400376 crow::utility::setProtocolDefaults(*url, protocol);
377 crow::utility::setPortDefaults(*url);
378
379 if (url->path().empty())
380 {
381 url->set_path("/");
382 }
383
384 if (url->has_userinfo())
385 {
386 messages::propertyValueFormatError(asyncResp->res, destUrl,
387 "Destination");
388 return;
389 }
390
391 if (protocol == "SNMPv2c")
392 {
393 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700394 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400395 messages::propertyValueConflict(asyncResp->res, "Context",
396 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530397 return;
398 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400399 if (eventFormatType2)
400 {
401 messages::propertyValueConflict(
402 asyncResp->res, "EventFormatType", "Protocol");
403 return;
404 }
405 if (retryPolicy)
406 {
407 messages::propertyValueConflict(asyncResp->res,
408 "RetryPolicy", "Protocol");
409 return;
410 }
Myung Bae5064a252024-10-04 09:34:25 -0700411 if (sendHeartbeat)
412 {
413 messages::propertyValueConflict(
414 asyncResp->res, "SendHeartbeat", "Protocol");
415 return;
416 }
417 if (hbIntervalMinutes)
418 {
419 messages::propertyValueConflict(
420 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
421 return;
422 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400423 if (msgIds)
424 {
425 messages::propertyValueConflict(asyncResp->res,
426 "MessageIds", "Protocol");
427 return;
428 }
429 if (regPrefixes)
430 {
431 messages::propertyValueConflict(
432 asyncResp->res, "RegistryPrefixes", "Protocol");
433 return;
434 }
435 if (resTypes)
436 {
437 messages::propertyValueConflict(
438 asyncResp->res, "ResourceTypes", "Protocol");
439 return;
440 }
441 if (headers)
442 {
443 messages::propertyValueConflict(asyncResp->res,
444 "HttpHeaders", "Protocol");
445 return;
446 }
447 if (mrdJsonArray)
448 {
449 messages::propertyValueConflict(
450 asyncResp->res, "MetricReportDefinitions", "Protocol");
451 return;
452 }
453 if (url->scheme() != "snmp")
454 {
455 messages::propertyValueConflict(asyncResp->res,
456 "Destination", "Protocol");
457 return;
458 }
459
460 addSnmpTrapClient(asyncResp, url->host_address(),
461 url->port_number());
462 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700463 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700464
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400465 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700466 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400467 std::make_shared<persistent_data::UserSubscription>(), *url,
468 app.ioContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400469
470 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700471 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400472 if (*subscriptionType != "RedfishEvent")
473 {
474 messages::propertyValueNotInList(
475 asyncResp->res, *subscriptionType, "SubscriptionType");
476 return;
477 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400478 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800479 }
480 else
481 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700482 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400483 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800484 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530485
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400486 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800487 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400488 messages::propertyValueNotInList(asyncResp->res, protocol,
489 "Protocol");
490 return;
491 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400492 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800493
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400494 if (verifyCertificate)
495 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400496 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400497 }
498
499 if (eventFormatType2)
500 {
501 if (std::ranges::find(supportedEvtFormatTypes,
502 *eventFormatType2) ==
503 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700504 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400505 messages::propertyValueNotInList(
506 asyncResp->res, *eventFormatType2, "EventFormatType");
507 return;
508 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400509 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400510 }
511 else
512 {
513 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400514 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400515 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700516
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400517 if (context)
518 {
519 // This value is selected arbitrarily.
520 constexpr const size_t maxContextSize = 256;
521 if (context->size() > maxContextSize)
522 {
523 messages::stringValueTooLong(asyncResp->res, "Context",
524 maxContextSize);
525 return;
526 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400527 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400528 }
529
530 if (headers)
531 {
532 size_t cumulativeLen = 0;
533
534 for (const nlohmann::json::object_t& headerChunk : *headers)
535 {
536 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700537 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400538 const std::string* value =
539 item.second.get_ptr<const std::string*>();
540 if (value == nullptr)
541 {
542 messages::propertyValueFormatError(
543 asyncResp->res, item.second,
544 "HttpHeaders/" + item.first);
545 return;
546 }
547 // Adding a new json value is the size of the key, +
548 // the size of the value + 2 * 2 quotes for each, +
549 // the colon and space between. example:
550 // "key": "value"
551 cumulativeLen += item.first.size() + value->size() + 6;
552 // This value is selected to mirror http_connection.hpp
553 constexpr const uint16_t maxHeaderSizeED = 8096;
554 if (cumulativeLen > maxHeaderSizeED)
555 {
556 messages::arraySizeTooLong(
557 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
558 return;
559 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400560 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400561 }
562 }
563 }
564
565 if (regPrefixes)
566 {
567 for (const std::string& it : *regPrefixes)
568 {
569 if (std::ranges::find(supportedRegPrefixes, it) ==
570 supportedRegPrefixes.end())
571 {
572 messages::propertyValueNotInList(asyncResp->res, it,
573 "RegistryPrefixes");
574 return;
575 }
576 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400577 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400578 }
579
Ed Tanousa14c9112024-09-04 10:46:47 -0700580 if (originResources)
581 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400582 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700583 }
584
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400585 if (resTypes)
586 {
587 for (const std::string& it : *resTypes)
588 {
589 if (std::ranges::find(supportedResourceTypes, it) ==
590 supportedResourceTypes.end())
591 {
592 messages::propertyValueNotInList(asyncResp->res, it,
593 "ResourceTypes");
594 return;
595 }
596 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400597 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400598 }
599
600 if (msgIds)
601 {
602 std::vector<std::string> registryPrefix;
603
604 // If no registry prefixes are mentioned, consider all
605 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400606 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400607 {
608 registryPrefix.assign(supportedRegPrefixes.begin(),
609 supportedRegPrefixes.end());
610 }
611 else
612 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400613 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400614 }
615
616 for (const std::string& id : *msgIds)
617 {
618 bool validId = false;
619
620 // Check for Message ID in each of the selected Registry
621 for (const std::string& it : registryPrefix)
622 {
623 const std::span<const redfish::registries::MessageEntry>
624 registry =
625 redfish::registries::getRegistryFromPrefix(it);
626
627 if (std::ranges::any_of(
628 registry,
629 [&id](const redfish::registries::MessageEntry&
630 messageEntry) {
631 return id == messageEntry.first;
632 }))
633 {
634 validId = true;
635 break;
636 }
637 }
638
639 if (!validId)
640 {
641 messages::propertyValueNotInList(asyncResp->res, id,
642 "MessageIds");
643 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700644 }
645 }
646
Myung Bae5fe4ef32024-10-19 09:56:02 -0400647 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400648 }
649
650 if (retryPolicy)
651 {
652 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
653 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700654 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400655 messages::propertyValueNotInList(
656 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800657 return;
658 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400659 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400660 }
661 else
662 {
663 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400664 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400665 }
Myung Bae5064a252024-10-04 09:34:25 -0700666 if (sendHeartbeat)
667 {
668 subValue->userSub->sendHeartbeat = *sendHeartbeat;
669 }
670 if (hbIntervalMinutes)
671 {
672 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
673 {
674 messages::propertyValueOutOfRange(
675 asyncResp->res, *hbIntervalMinutes,
676 "HeartbeatIntervalMinutes");
677 return;
678 }
679 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
680 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400681
682 if (mrdJsonArray)
683 {
684 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
685 {
686 std::string mrdUri;
687
688 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
689 "@odata.id", mrdUri))
690
691 {
692 return;
693 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400694 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700695 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400696 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800697 }
698
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400699 std::string id =
700 EventServiceManager::getInstance().addPushSubscription(
701 subValue);
702 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800703 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400704 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800705 return;
706 }
707
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400708 messages::created(asyncResp->res);
709 asyncResp->res.addHeader(
710 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500711
712 // schedule a heartbeat
713 if (subValue->userSub->sendHeartbeat)
714 {
715 subValue->scheduleNextHeartbeatEvent();
716 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400717 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700718}
719
720inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530721{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500722 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700723 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700724 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700725 [&app](const crow::Request& req,
726 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
727 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400728 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
729 {
730 return;
731 }
Chicago Duan3d307082020-11-26 14:12:12 +0800732
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400733 if (param.starts_with("snmp"))
734 {
735 getSnmpTrapClient(asyncResp, param);
736 return;
737 }
Chicago Duan3d307082020-11-26 14:12:12 +0800738
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400739 std::shared_ptr<Subscription> subValue =
740 EventServiceManager::getInstance().getSubscription(param);
741 if (subValue == nullptr)
742 {
743 asyncResp->res.result(
744 boost::beast::http::status::not_found);
745 return;
746 }
747 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530748
Ed Tanous4b712a22023-08-02 12:56:52 -0700749 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400750 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800751
Ed Tanous4b712a22023-08-02 12:56:52 -0700752 nlohmann::json& jVal = asyncResp->res.jsonValue;
753 jVal["@odata.type"] =
754 "#EventDestination.v1_14_1.EventDestination";
755 jVal["Protocol"] =
756 event_destination::EventDestinationProtocol::Redfish;
757 jVal["@odata.id"] = boost::urls::format(
758 "/redfish/v1/EventService/Subscriptions/{}", id);
759 jVal["Id"] = id;
760 jVal["Name"] = "Event Destination " + id;
761 jVal["Destination"] = userSub.destinationUrl;
762 jVal["Context"] = userSub.customText;
763 jVal["SubscriptionType"] = userSub.subscriptionType;
764 jVal["HttpHeaders"] = nlohmann::json::array();
765 jVal["EventFormatType"] = userSub.eventFormatType;
766 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
767 jVal["ResourceTypes"] = userSub.resourceTypes;
768
769 jVal["MessageIds"] = userSub.registryMsgIds;
770 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700771 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
772 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700773 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530774
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400775 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700776 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400777 {
778 nlohmann::json::object_t mdr;
779 mdr["@odata.id"] = mdrUri;
780 mrdJsonArray.emplace_back(std::move(mdr));
781 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700782 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400783 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500784 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700785 // The below privilege is wrong, it should be ConfigureManager OR
786 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500787 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700788 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700789 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700790 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700791 [&app](const crow::Request& req,
792 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
793 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400794 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700795 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400796 return;
797 }
798 std::shared_ptr<Subscription> subValue =
799 EventServiceManager::getInstance().getSubscription(param);
800 if (subValue == nullptr)
801 {
802 asyncResp->res.result(
803 boost::beast::http::status::not_found);
804 return;
805 }
806
807 std::optional<std::string> context;
808 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700809 std::optional<bool> sendHeartbeat;
810 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400811 std::optional<bool> verifyCertificate;
812 std::optional<std::vector<nlohmann::json::object_t>> headers;
813
Myung Baeafc474a2024-10-09 00:53:29 -0700814 if (!json_util::readJsonPatch( //
815 req, asyncResp->res, //
816 "Context", context, //
817 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700818 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Myung Baeafc474a2024-10-09 00:53:29 -0700819 "HttpHeaders", headers, //
Myung Bae5064a252024-10-04 09:34:25 -0700820 "SendHeartbeat", sendHeartbeat, //
Myung Baeafc474a2024-10-09 00:53:29 -0700821 "VerifyCertificate", verifyCertificate //
822 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400823 {
824 return;
825 }
826
827 if (context)
828 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400829 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400830 }
831
832 if (headers)
833 {
834 boost::beast::http::fields fields;
835 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700836 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400837 for (const auto& it : headerChunk)
838 {
839 const std::string* value =
840 it.second.get_ptr<const std::string*>();
841 if (value == nullptr)
842 {
843 messages::propertyValueFormatError(
844 asyncResp->res, it.second,
845 "HttpHeaders/" + it.first);
846 return;
847 }
848 fields.set(it.first, *value);
849 }
850 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400851 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400852 }
853
854 if (retryPolicy)
855 {
856 if (std::ranges::find(supportedRetryPolicies,
857 *retryPolicy) ==
858 supportedRetryPolicies.end())
859 {
860 messages::propertyValueNotInList(asyncResp->res,
861 *retryPolicy,
862 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700863 return;
864 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400865 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700866 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530867
Myung Bae5064a252024-10-04 09:34:25 -0700868 if (sendHeartbeat)
869 {
870 subValue->userSub->sendHeartbeat = *sendHeartbeat;
871 }
872 if (hbIntervalMinutes)
873 {
874 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
875 {
876 messages::propertyValueOutOfRange(
877 asyncResp->res, *hbIntervalMinutes,
878 "HeartbeatIntervalMinutes");
879 return;
880 }
881 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
882 }
883
Myung Baefb546102024-10-29 10:21:26 -0500884 if (hbIntervalMinutes || sendHeartbeat)
885 {
886 // if Heartbeat interval or send heart were changed, cancel
887 // the heartbeat timer if running and start a new heartbeat
888 // if needed
889 subValue->heartbeatParametersChanged();
890 }
891
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400892 if (verifyCertificate)
893 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400894 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400895 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700896
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400897 EventServiceManager::getInstance().updateSubscriptionData();
898 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500899 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700900 // The below privilege is wrong, it should be ConfigureManager OR
901 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500902 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700903 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700904 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700905 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700906 [&app](const crow::Request& req,
907 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
908 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400909 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
910 {
911 return;
912 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700913 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400914 if (param.starts_with("snmp"))
915 {
916 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700917 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400918 return;
919 }
Chicago Duan3d307082020-11-26 14:12:12 +0800920
Ed Tanous4b712a22023-08-02 12:56:52 -0700921 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400922 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700923 messages::resourceNotFound(asyncResp->res,
924 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400925 return;
926 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700927 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400928 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700929}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530930
931} // namespace redfish