1e5aaf047SAppaRao Puli /*
2e5aaf047SAppaRao Puli // Copyright (c) 2020 Intel Corporation
3e5aaf047SAppaRao Puli //
4e5aaf047SAppaRao Puli // Licensed under the Apache License, Version 2.0 (the "License");
5e5aaf047SAppaRao Puli // you may not use this file except in compliance with the License.
6e5aaf047SAppaRao Puli // You may obtain a copy of the License at
7e5aaf047SAppaRao Puli //
8e5aaf047SAppaRao Puli // http://www.apache.org/licenses/LICENSE-2.0
9e5aaf047SAppaRao Puli //
10e5aaf047SAppaRao Puli // Unless required by applicable law or agreed to in writing, software
11e5aaf047SAppaRao Puli // distributed under the License is distributed on an "AS IS" BASIS,
12e5aaf047SAppaRao Puli // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5aaf047SAppaRao Puli // See the License for the specific language governing permissions and
14e5aaf047SAppaRao Puli // limitations under the License.
15e5aaf047SAppaRao Puli */
16e5aaf047SAppaRao Puli #pragma once
173ccb3adbSEd Tanous #include "app.hpp"
18b52664e2SAppaRao Puli #include "event_service_manager.hpp"
193ccb3adbSEd Tanous #include "http/utility.hpp"
203ccb3adbSEd Tanous #include "logging.hpp"
213ccb3adbSEd Tanous #include "query.hpp"
223ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
233d30708fSChicago Duan #include "snmp_trap_event_clients.hpp"
24e5aaf047SAppaRao Puli
25601c71aeSEd Tanous #include <boost/beast/http/fields.hpp>
263d30708fSChicago Duan #include <boost/system/error_code.hpp>
27a716aa74SEd Tanous #include <boost/url/parse.hpp>
283d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp>
293d30708fSChicago Duan #include <utils/dbus_utils.hpp>
30ed398213SEd Tanous
313d30708fSChicago Duan #include <charconv>
323d30708fSChicago Duan #include <memory>
333544d2a7SEd Tanous #include <ranges>
341e270c5fSPatrick Williams #include <span>
353d30708fSChicago Duan #include <string>
361e270c5fSPatrick Williams
37e5aaf047SAppaRao Puli namespace redfish
38e5aaf047SAppaRao Puli {
39e5aaf047SAppaRao Puli
40156d6b00SAppaRao Puli static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
41156d6b00SAppaRao Puli eventFormatType, metricReportFormatType};
42e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
43b304bd79SP Dheeraj Srujan Kumar "Base", "OpenBMC", "TaskEvent"};
44e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
45e5aaf047SAppaRao Puli "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
46e5aaf047SAppaRao Puli
47e56f254cSSunitha Harish static constexpr const std::array<const char*, 1> supportedResourceTypes = {
48e56f254cSSunitha Harish "Task"};
49e56f254cSSunitha Harish
requestRoutesEventService(App & app)507e860f15SJohn Edward Broadbent inline void requestRoutesEventService(App& app)
51e5aaf047SAppaRao Puli {
527e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
53ed398213SEd Tanous .privileges(redfish::privileges::getEventService)
54002d39b4SEd Tanous .methods(boost::beast::http::verb::get)(
55002d39b4SEd Tanous [&app](const crow::Request& req,
56002d39b4SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
573ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
5845ca1b86SEd Tanous {
5945ca1b86SEd Tanous return;
6045ca1b86SEd Tanous }
611476687dSEd Tanous
621476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
631476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] =
641476687dSEd Tanous "#EventService.v1_5_0.EventService";
651476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "EventService";
661476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Event Service";
675e44e3d8SAppaRao Puli asyncResp->res.jsonValue["ServerSentEventUri"] =
685e44e3d8SAppaRao Puli "/redfish/v1/EventService/SSE";
695e44e3d8SAppaRao Puli
701476687dSEd Tanous asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
711476687dSEd Tanous "/redfish/v1/EventService/Subscriptions";
72002d39b4SEd Tanous asyncResp->res
73002d39b4SEd Tanous .jsonValue["Actions"]["#EventService.SubmitTestEvent"]["target"] =
741476687dSEd Tanous "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
75e5aaf047SAppaRao Puli
7628afb49cSJunLin Chen const persistent_data::EventServiceConfig eventServiceConfig =
7728afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance()
7828afb49cSJunLin Chen .getEventServiceConfig();
797d1cc387SAppaRao Puli
807d1cc387SAppaRao Puli asyncResp->res.jsonValue["Status"]["State"] =
8128afb49cSJunLin Chen (eventServiceConfig.enabled ? "Enabled" : "Disabled");
82002d39b4SEd Tanous asyncResp->res.jsonValue["ServiceEnabled"] = eventServiceConfig.enabled;
837e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
8428afb49cSJunLin Chen eventServiceConfig.retryAttempts;
85e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
8628afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval;
87002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
880fda0f12SGeorge Liu asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
890fda0f12SGeorge Liu asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
9007941a88SAyushi Smriti
91613dabeaSEd Tanous nlohmann::json::object_t supportedSSEFilters;
92613dabeaSEd Tanous supportedSSEFilters["EventFormatType"] = true;
93613dabeaSEd Tanous supportedSSEFilters["MessageId"] = true;
94613dabeaSEd Tanous supportedSSEFilters["MetricReportDefinition"] = true;
95613dabeaSEd Tanous supportedSSEFilters["RegistryPrefix"] = true;
96613dabeaSEd Tanous supportedSSEFilters["OriginResource"] = false;
97613dabeaSEd Tanous supportedSSEFilters["ResourceType"] = false;
9807941a88SAyushi Smriti
9907941a88SAyushi Smriti asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
100613dabeaSEd Tanous std::move(supportedSSEFilters);
1017e860f15SJohn Edward Broadbent });
102e5aaf047SAppaRao Puli
1037e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
104ed398213SEd Tanous .privileges(redfish::privileges::patchEventService)
1057e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)(
10645ca1b86SEd Tanous [&app](const crow::Request& req,
10745ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
1083ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
109e5aaf047SAppaRao Puli {
11045ca1b86SEd Tanous return;
11145ca1b86SEd Tanous }
112e5aaf047SAppaRao Puli std::optional<bool> serviceEnabled;
113e5aaf047SAppaRao Puli std::optional<uint32_t> retryAttemps;
114e5aaf047SAppaRao Puli std::optional<uint32_t> retryInterval;
115e5aaf047SAppaRao Puli
11615ed6780SWilly Tu if (!json_util::readJsonPatch(
1177e860f15SJohn Edward Broadbent req, asyncResp->res, "ServiceEnabled", serviceEnabled,
1187e860f15SJohn Edward Broadbent "DeliveryRetryAttempts", retryAttemps,
1197e860f15SJohn Edward Broadbent "DeliveryRetryIntervalSeconds", retryInterval))
120e5aaf047SAppaRao Puli {
121e5aaf047SAppaRao Puli return;
122e5aaf047SAppaRao Puli }
123e5aaf047SAppaRao Puli
12428afb49cSJunLin Chen persistent_data::EventServiceConfig eventServiceConfig =
12528afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance()
12628afb49cSJunLin Chen .getEventServiceConfig();
1277d1cc387SAppaRao Puli
128e5aaf047SAppaRao Puli if (serviceEnabled)
129e5aaf047SAppaRao Puli {
13028afb49cSJunLin Chen eventServiceConfig.enabled = *serviceEnabled;
131e5aaf047SAppaRao Puli }
132e5aaf047SAppaRao Puli
133e5aaf047SAppaRao Puli if (retryAttemps)
134e5aaf047SAppaRao Puli {
135e5aaf047SAppaRao Puli // Supported range [1-3]
136e5aaf047SAppaRao Puli if ((*retryAttemps < 1) || (*retryAttemps > 3))
137e5aaf047SAppaRao Puli {
138e5aaf047SAppaRao Puli messages::queryParameterOutOfRange(
139e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryAttemps),
140e5aaf047SAppaRao Puli "DeliveryRetryAttempts", "[1-3]");
141e5aaf047SAppaRao Puli }
142e5aaf047SAppaRao Puli else
143e5aaf047SAppaRao Puli {
14428afb49cSJunLin Chen eventServiceConfig.retryAttempts = *retryAttemps;
145e5aaf047SAppaRao Puli }
146e5aaf047SAppaRao Puli }
147e5aaf047SAppaRao Puli
148e5aaf047SAppaRao Puli if (retryInterval)
149e5aaf047SAppaRao Puli {
15033a32b34SGunnar Mills // Supported range [5 - 180]
15133a32b34SGunnar Mills if ((*retryInterval < 5) || (*retryInterval > 180))
152e5aaf047SAppaRao Puli {
153e5aaf047SAppaRao Puli messages::queryParameterOutOfRange(
154e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryInterval),
15533a32b34SGunnar Mills "DeliveryRetryIntervalSeconds", "[5-180]");
156e5aaf047SAppaRao Puli }
157e5aaf047SAppaRao Puli else
158e5aaf047SAppaRao Puli {
159002d39b4SEd Tanous eventServiceConfig.retryTimeoutInterval = *retryInterval;
160e5aaf047SAppaRao Puli }
161e5aaf047SAppaRao Puli }
162e5aaf047SAppaRao Puli
1637d1cc387SAppaRao Puli EventServiceManager::getInstance().setEventServiceConfig(
16428afb49cSJunLin Chen eventServiceConfig);
1657e860f15SJohn Edward Broadbent });
1660b4bdd93SAppaRao Puli }
1670b4bdd93SAppaRao Puli
requestRoutesSubmitTestEvent(App & app)1687e860f15SJohn Edward Broadbent inline void requestRoutesSubmitTestEvent(App& app)
1690b4bdd93SAppaRao Puli {
1707e860f15SJohn Edward Broadbent BMCWEB_ROUTE(
1717e860f15SJohn Edward Broadbent app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
172ed398213SEd Tanous .privileges(redfish::privileges::postEventService)
1737e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)(
17445ca1b86SEd Tanous [&app](const crow::Request& req,
1757e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
1763ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
17745ca1b86SEd Tanous {
17845ca1b86SEd Tanous return;
17945ca1b86SEd Tanous }
1806ba8c82eSsunharis_in if (!EventServiceManager::getInstance().sendTestEventLog())
1816ba8c82eSsunharis_in {
1826ba8c82eSsunharis_in messages::serviceDisabled(asyncResp->res,
1836ba8c82eSsunharis_in "/redfish/v1/EventService/");
1846ba8c82eSsunharis_in return;
1856ba8c82eSsunharis_in }
1868d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content);
1877e860f15SJohn Edward Broadbent });
188e5aaf047SAppaRao Puli }
189e5aaf047SAppaRao Puli
doSubscriptionCollection(const boost::system::error_code & ec,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const dbus::utility::ManagedObjectType & resp)1903d30708fSChicago Duan inline void doSubscriptionCollection(
191e81de512SEd Tanous const boost::system::error_code& ec,
1923d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1933d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp)
1943d30708fSChicago Duan {
1953d30708fSChicago Duan if (ec)
1963d30708fSChicago Duan {
1971306101eSEd Tanous if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
1983d30708fSChicago Duan {
1993d30708fSChicago Duan // This is an optional process so just return if it isn't there
2003d30708fSChicago Duan return;
2013d30708fSChicago Duan }
2023d30708fSChicago Duan
20362598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
2043d30708fSChicago Duan messages::internalError(asyncResp->res);
2053d30708fSChicago Duan return;
2063d30708fSChicago Duan }
2073d30708fSChicago Duan nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
2083d30708fSChicago Duan for (const auto& objpath : resp)
2093d30708fSChicago Duan {
2103d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first);
2113d30708fSChicago Duan const std::string snmpId = path.filename();
2123d30708fSChicago Duan if (snmpId.empty())
2133d30708fSChicago Duan {
21462598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
2153d30708fSChicago Duan messages::internalError(asyncResp->res);
2163d30708fSChicago Duan return;
2173d30708fSChicago Duan }
2183d30708fSChicago Duan
2193d30708fSChicago Duan getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
2203d30708fSChicago Duan }
2213d30708fSChicago Duan }
2223d30708fSChicago Duan
requestRoutesEventDestinationCollection(App & app)2237e860f15SJohn Edward Broadbent inline void requestRoutesEventDestinationCollection(App& app)
224e5aaf047SAppaRao Puli {
2251ebe3e41SGayathri Leburu BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
226ed398213SEd Tanous .privileges(redfish::privileges::getEventDestinationCollection)
2277e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)(
22845ca1b86SEd Tanous [&app](const crow::Request& req,
2297e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2303ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
23145ca1b86SEd Tanous {
23245ca1b86SEd Tanous return;
23345ca1b86SEd Tanous }
2341476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] =
2351476687dSEd Tanous "#EventDestinationCollection.EventDestinationCollection";
2361476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] =
2371476687dSEd Tanous "/redfish/v1/EventService/Subscriptions";
238002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Event Destination Collections";
239e5aaf047SAppaRao Puli
240002d39b4SEd Tanous nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
241e5aaf047SAppaRao Puli
242b52664e2SAppaRao Puli std::vector<std::string> subscripIds =
243b52664e2SAppaRao Puli EventServiceManager::getInstance().getAllIDs();
244b52664e2SAppaRao Puli memberArray = nlohmann::json::array();
245002d39b4SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
246b52664e2SAppaRao Puli
247b52664e2SAppaRao Puli for (const std::string& id : subscripIds)
248e5aaf047SAppaRao Puli {
2491476687dSEd Tanous nlohmann::json::object_t member;
2503d30708fSChicago Duan member["@odata.id"] = boost::urls::format(
2513d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}" + id);
252b2ba3072SPatrick Williams memberArray.emplace_back(std::move(member));
253e5aaf047SAppaRao Puli }
2543d30708fSChicago Duan crow::connections::systemBus->async_method_call(
255e81de512SEd Tanous [asyncResp](const boost::system::error_code& ec,
2563d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) {
2573d30708fSChicago Duan doSubscriptionCollection(ec, asyncResp, resp);
2583d30708fSChicago Duan },
2593d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP",
2603d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager",
2613d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
2627e860f15SJohn Edward Broadbent });
2633d30708fSChicago Duan
2647e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
2657eeafa76SAbhishek Patel .privileges(redfish::privileges::postEventDestinationCollection)
266002d39b4SEd Tanous .methods(boost::beast::http::verb::post)(
267002d39b4SEd Tanous [&app](const crow::Request& req,
2687e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2693ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
27045ca1b86SEd Tanous {
27145ca1b86SEd Tanous return;
27245ca1b86SEd Tanous }
273fffb8c1fSEd Tanous if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
274fffb8c1fSEd Tanous maxNoOfSubscriptions)
275e5aaf047SAppaRao Puli {
276e5aaf047SAppaRao Puli messages::eventSubscriptionLimitExceeded(asyncResp->res);
277e5aaf047SAppaRao Puli return;
278e5aaf047SAppaRao Puli }
279e5aaf047SAppaRao Puli std::string destUrl;
280e5aaf047SAppaRao Puli std::string protocol;
281e5aaf047SAppaRao Puli std::optional<std::string> context;
282e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType;
28323a21a1cSEd Tanous std::optional<std::string> eventFormatType2;
284e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy;
285e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds;
286e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes;
287e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes;
288*78d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers;
289*78d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
290e5aaf047SAppaRao Puli
29115ed6780SWilly Tu if (!json_util::readJsonPatch(
292002d39b4SEd Tanous req, asyncResp->res, "Destination", destUrl, "Context", context,
293002d39b4SEd Tanous "Protocol", protocol, "SubscriptionType", subscriptionType,
294002d39b4SEd Tanous "EventFormatType", eventFormatType2, "HttpHeaders", headers,
295002d39b4SEd Tanous "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
296002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
297002d39b4SEd Tanous mrdJsonArray, "ResourceTypes", resTypes))
298e5aaf047SAppaRao Puli {
299e5aaf047SAppaRao Puli return;
300e5aaf047SAppaRao Puli }
301e5aaf047SAppaRao Puli
302600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
303600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000;
304600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize)
305600af5f1SAppaRao Puli {
306600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination",
307600af5f1SAppaRao Puli maxDestinationSize);
308600af5f1SAppaRao Puli return;
309600af5f1SAppaRao Puli }
310600af5f1SAppaRao Puli
311dd28ba82SAppaRao Puli if (regPrefixes && msgIds)
312dd28ba82SAppaRao Puli {
31326f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty())
314dd28ba82SAppaRao Puli {
315002d39b4SEd Tanous messages::propertyValueConflict(asyncResp->res, "MessageIds",
316002d39b4SEd Tanous "RegistryPrefixes");
317dd28ba82SAppaRao Puli return;
318dd28ba82SAppaRao Puli }
319dd28ba82SAppaRao Puli }
320dd28ba82SAppaRao Puli
3216fd29553SEd Tanous boost::system::result<boost::urls::url> url =
322a716aa74SEd Tanous boost::urls::parse_absolute_uri(destUrl);
323a716aa74SEd Tanous if (!url)
324e5aaf047SAppaRao Puli {
32562598e31SEd Tanous BMCWEB_LOG_WARNING("Failed to validate and split destination url");
326e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl,
327e5aaf047SAppaRao Puli "Destination");
328e5aaf047SAppaRao Puli return;
329e5aaf047SAppaRao Puli }
330a716aa74SEd Tanous url->normalize();
331a716aa74SEd Tanous crow::utility::setProtocolDefaults(*url, protocol);
332a716aa74SEd Tanous crow::utility::setPortDefaults(*url);
333a716aa74SEd Tanous
334a716aa74SEd Tanous if (url->path().empty())
335a716aa74SEd Tanous {
336a716aa74SEd Tanous url->set_path("/");
337a716aa74SEd Tanous }
338a716aa74SEd Tanous
339a716aa74SEd Tanous if (url->has_userinfo())
340a716aa74SEd Tanous {
341a716aa74SEd Tanous messages::propertyValueFormatError(asyncResp->res, destUrl,
342a716aa74SEd Tanous "Destination");
343a716aa74SEd Tanous return;
344a716aa74SEd Tanous }
345b52664e2SAppaRao Puli
3463d30708fSChicago Duan if (protocol == "SNMPv2c")
3473d30708fSChicago Duan {
3483d30708fSChicago Duan if (context)
3493d30708fSChicago Duan {
3503d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context",
3513d30708fSChicago Duan "Protocol");
3523d30708fSChicago Duan return;
3533d30708fSChicago Duan }
3543d30708fSChicago Duan if (eventFormatType2)
3553d30708fSChicago Duan {
3563d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res,
3573d30708fSChicago Duan "EventFormatType", "Protocol");
3583d30708fSChicago Duan return;
3593d30708fSChicago Duan }
3603d30708fSChicago Duan if (retryPolicy)
3613d30708fSChicago Duan {
3623d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "RetryPolicy",
3633d30708fSChicago Duan "Protocol");
3643d30708fSChicago Duan return;
3653d30708fSChicago Duan }
3663d30708fSChicago Duan if (msgIds)
3673d30708fSChicago Duan {
3683d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "MessageIds",
3693d30708fSChicago Duan "Protocol");
3703d30708fSChicago Duan return;
3713d30708fSChicago Duan }
3723d30708fSChicago Duan if (regPrefixes)
3733d30708fSChicago Duan {
3743d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res,
3753d30708fSChicago Duan "RegistryPrefixes", "Protocol");
3763d30708fSChicago Duan return;
3773d30708fSChicago Duan }
3783d30708fSChicago Duan if (resTypes)
3793d30708fSChicago Duan {
3803d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "ResourceTypes",
3813d30708fSChicago Duan "Protocol");
3823d30708fSChicago Duan return;
3833d30708fSChicago Duan }
3843d30708fSChicago Duan if (headers)
3853d30708fSChicago Duan {
3863d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "HttpHeaders",
3873d30708fSChicago Duan "Protocol");
3883d30708fSChicago Duan return;
3893d30708fSChicago Duan }
3903d30708fSChicago Duan if (mrdJsonArray)
3913d30708fSChicago Duan {
3923d30708fSChicago Duan messages::propertyValueConflict(
3933d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol");
3943d30708fSChicago Duan return;
3953d30708fSChicago Duan }
396a716aa74SEd Tanous if (url->scheme() != "snmp")
397a716aa74SEd Tanous {
398a716aa74SEd Tanous messages::propertyValueConflict(asyncResp->res, "Destination",
399a716aa74SEd Tanous "Protocol");
4003d30708fSChicago Duan return;
4013d30708fSChicago Duan }
4023d30708fSChicago Duan
403a716aa74SEd Tanous addSnmpTrapClient(asyncResp, url->host_address(),
404a716aa74SEd Tanous url->port_number());
405a716aa74SEd Tanous return;
406b52664e2SAppaRao Puli }
4073d30708fSChicago Duan
408a716aa74SEd Tanous std::shared_ptr<Subscription> subValue =
409a716aa74SEd Tanous std::make_shared<Subscription>(*url, app.ioContext());
410b52664e2SAppaRao Puli
411a716aa74SEd Tanous subValue->destinationUrl = std::move(*url);
412e5aaf047SAppaRao Puli
413e5aaf047SAppaRao Puli if (subscriptionType)
414e5aaf047SAppaRao Puli {
415e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent")
416e5aaf047SAppaRao Puli {
417fffb8c1fSEd Tanous messages::propertyValueNotInList(
418fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType");
419e5aaf047SAppaRao Puli return;
420e5aaf047SAppaRao Puli }
421b52664e2SAppaRao Puli subValue->subscriptionType = *subscriptionType;
422e5aaf047SAppaRao Puli }
423e5aaf047SAppaRao Puli else
424e5aaf047SAppaRao Puli {
425b52664e2SAppaRao Puli subValue->subscriptionType = "RedfishEvent"; // Default
426e5aaf047SAppaRao Puli }
427e5aaf047SAppaRao Puli
428e5aaf047SAppaRao Puli if (protocol != "Redfish")
429e5aaf047SAppaRao Puli {
430e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol,
431e5aaf047SAppaRao Puli "Protocol");
432e5aaf047SAppaRao Puli return;
433e5aaf047SAppaRao Puli }
434b52664e2SAppaRao Puli subValue->protocol = protocol;
435e5aaf047SAppaRao Puli
43623a21a1cSEd Tanous if (eventFormatType2)
437e5aaf047SAppaRao Puli {
4383544d2a7SEd Tanous if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) ==
4393544d2a7SEd Tanous supportedEvtFormatTypes.end())
440e5aaf047SAppaRao Puli {
441fffb8c1fSEd Tanous messages::propertyValueNotInList(
442fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType");
443e5aaf047SAppaRao Puli return;
444e5aaf047SAppaRao Puli }
44523a21a1cSEd Tanous subValue->eventFormatType = *eventFormatType2;
446e5aaf047SAppaRao Puli }
447e5aaf047SAppaRao Puli else
448e5aaf047SAppaRao Puli {
449e5aaf047SAppaRao Puli // If not specified, use default "Event"
45023a21a1cSEd Tanous subValue->eventFormatType = "Event";
451e5aaf047SAppaRao Puli }
452e5aaf047SAppaRao Puli
453e5aaf047SAppaRao Puli if (context)
454e5aaf047SAppaRao Puli {
4558ece0e45SEd Tanous // This value is selected arbitrarily.
456600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256;
457600af5f1SAppaRao Puli if (context->size() > maxContextSize)
458600af5f1SAppaRao Puli {
459600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context",
460600af5f1SAppaRao Puli maxContextSize);
461600af5f1SAppaRao Puli return;
462600af5f1SAppaRao Puli }
463b52664e2SAppaRao Puli subValue->customText = *context;
464e5aaf047SAppaRao Puli }
465e5aaf047SAppaRao Puli
466e5aaf047SAppaRao Puli if (headers)
467e5aaf047SAppaRao Puli {
468600af5f1SAppaRao Puli size_t cumulativeLen = 0;
469600af5f1SAppaRao Puli
470*78d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers)
471601c71aeSEd Tanous {
472*78d4ec4fSEd Tanous for (const auto& item : headerChunk)
473*78d4ec4fSEd Tanous {
474*78d4ec4fSEd Tanous const std::string* value =
475*78d4ec4fSEd Tanous item.second.get_ptr<const std::string*>();
476*78d4ec4fSEd Tanous if (value == nullptr)
477*78d4ec4fSEd Tanous {
478*78d4ec4fSEd Tanous messages::propertyValueFormatError(
479*78d4ec4fSEd Tanous asyncResp->res, item.second,
480*78d4ec4fSEd Tanous "HttpHeaders/" + item.first);
481*78d4ec4fSEd Tanous return;
482*78d4ec4fSEd Tanous }
483*78d4ec4fSEd Tanous // Adding a new json value is the size of the key, +
484*78d4ec4fSEd Tanous // the size of the value + 2 * 2 quotes for each, +
485*78d4ec4fSEd Tanous // the colon and space between. example:
486*78d4ec4fSEd Tanous // "key": "value"
487*78d4ec4fSEd Tanous cumulativeLen += item.first.size() + value->size() + 6;
488600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp
489600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096;
490600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED)
491600af5f1SAppaRao Puli {
492*78d4ec4fSEd Tanous messages::arraySizeTooLong(
493*78d4ec4fSEd Tanous asyncResp->res, "HttpHeaders", maxHeaderSizeED);
494600af5f1SAppaRao Puli return;
495600af5f1SAppaRao Puli }
496*78d4ec4fSEd Tanous subValue->httpHeaders.set(item.first, *value);
497601c71aeSEd Tanous }
498601c71aeSEd Tanous }
499e5aaf047SAppaRao Puli }
500e5aaf047SAppaRao Puli
501e5aaf047SAppaRao Puli if (regPrefixes)
502e5aaf047SAppaRao Puli {
503e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes)
504e5aaf047SAppaRao Puli {
5053544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) ==
5063544d2a7SEd Tanous supportedRegPrefixes.end())
507e5aaf047SAppaRao Puli {
508fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it,
509fffb8c1fSEd Tanous "RegistryPrefixes");
510e5aaf047SAppaRao Puli return;
511e5aaf047SAppaRao Puli }
512e5aaf047SAppaRao Puli }
513b52664e2SAppaRao Puli subValue->registryPrefixes = *regPrefixes;
514e5aaf047SAppaRao Puli }
515e5aaf047SAppaRao Puli
516e56f254cSSunitha Harish if (resTypes)
517e56f254cSSunitha Harish {
518e56f254cSSunitha Harish for (const std::string& it : *resTypes)
519e56f254cSSunitha Harish {
5203544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) ==
5213544d2a7SEd Tanous supportedResourceTypes.end())
522e56f254cSSunitha Harish {
523e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it,
524e56f254cSSunitha Harish "ResourceTypes");
525e56f254cSSunitha Harish return;
526e56f254cSSunitha Harish }
527e56f254cSSunitha Harish }
528e56f254cSSunitha Harish subValue->resourceTypes = *resTypes;
529e56f254cSSunitha Harish }
530e56f254cSSunitha Harish
531e5aaf047SAppaRao Puli if (msgIds)
532e5aaf047SAppaRao Puli {
533b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix;
534b304bd79SP Dheeraj Srujan Kumar
5357e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all
5367e860f15SJohn Edward Broadbent // supported prefixes
537b304bd79SP Dheeraj Srujan Kumar if (subValue->registryPrefixes.empty())
538b304bd79SP Dheeraj Srujan Kumar {
539b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(),
540b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end());
541b304bd79SP Dheeraj Srujan Kumar }
542b304bd79SP Dheeraj Srujan Kumar else
543b304bd79SP Dheeraj Srujan Kumar {
544b304bd79SP Dheeraj Srujan Kumar registryPrefix = subValue->registryPrefixes;
545b304bd79SP Dheeraj Srujan Kumar }
546b304bd79SP Dheeraj Srujan Kumar
547b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds)
548b304bd79SP Dheeraj Srujan Kumar {
549b304bd79SP Dheeraj Srujan Kumar bool validId = false;
550b304bd79SP Dheeraj Srujan Kumar
551b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry
552b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix)
553b304bd79SP Dheeraj Srujan Kumar {
554fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry>
555fffb8c1fSEd Tanous registry =
556fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it);
557b304bd79SP Dheeraj Srujan Kumar
5583544d2a7SEd Tanous if (std::ranges::any_of(
5593544d2a7SEd Tanous registry,
560fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry&
561fffb8c1fSEd Tanous messageEntry) {
56255f79e6fSEd Tanous return id == messageEntry.first;
563b304bd79SP Dheeraj Srujan Kumar }))
564b304bd79SP Dheeraj Srujan Kumar {
565b304bd79SP Dheeraj Srujan Kumar validId = true;
566b304bd79SP Dheeraj Srujan Kumar break;
567b304bd79SP Dheeraj Srujan Kumar }
568b304bd79SP Dheeraj Srujan Kumar }
569b304bd79SP Dheeraj Srujan Kumar
570b304bd79SP Dheeraj Srujan Kumar if (!validId)
571b304bd79SP Dheeraj Srujan Kumar {
572b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id,
573b304bd79SP Dheeraj Srujan Kumar "MessageIds");
574b304bd79SP Dheeraj Srujan Kumar return;
575b304bd79SP Dheeraj Srujan Kumar }
576b304bd79SP Dheeraj Srujan Kumar }
577b304bd79SP Dheeraj Srujan Kumar
578b52664e2SAppaRao Puli subValue->registryMsgIds = *msgIds;
579e5aaf047SAppaRao Puli }
580e5aaf047SAppaRao Puli
581e5aaf047SAppaRao Puli if (retryPolicy)
582e5aaf047SAppaRao Puli {
5833544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
5843544d2a7SEd Tanous supportedRetryPolicies.end())
585e5aaf047SAppaRao Puli {
586002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
587002d39b4SEd Tanous "DeliveryRetryPolicy");
588e5aaf047SAppaRao Puli return;
589e5aaf047SAppaRao Puli }
590b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy;
591e5aaf047SAppaRao Puli }
592e5aaf047SAppaRao Puli else
593e5aaf047SAppaRao Puli {
594e5aaf047SAppaRao Puli // Default "TerminateAfterRetries"
595b52664e2SAppaRao Puli subValue->retryPolicy = "TerminateAfterRetries";
596e5aaf047SAppaRao Puli }
597e5aaf047SAppaRao Puli
598144b6318SAppaRao Puli if (mrdJsonArray)
599156d6b00SAppaRao Puli {
600*78d4ec4fSEd Tanous for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
601144b6318SAppaRao Puli {
602144b6318SAppaRao Puli std::string mrdUri;
603ea2e6eecSWilly Tu
604*78d4ec4fSEd Tanous if (!json_util::readJsonObject(mrdObj, asyncResp->res,
605*78d4ec4fSEd Tanous "@odata.id", mrdUri))
606ea2e6eecSWilly Tu
607144b6318SAppaRao Puli {
608144b6318SAppaRao Puli return;
609144b6318SAppaRao Puli }
610ea2e6eecSWilly Tu subValue->metricReportDefinitions.emplace_back(mrdUri);
611144b6318SAppaRao Puli }
612156d6b00SAppaRao Puli }
613156d6b00SAppaRao Puli
614b52664e2SAppaRao Puli std::string id =
615fffb8c1fSEd Tanous EventServiceManager::getInstance().addSubscription(subValue);
616b52664e2SAppaRao Puli if (id.empty())
617e5aaf047SAppaRao Puli {
618e5aaf047SAppaRao Puli messages::internalError(asyncResp->res);
619e5aaf047SAppaRao Puli return;
620e5aaf047SAppaRao Puli }
621e5aaf047SAppaRao Puli
622e5aaf047SAppaRao Puli messages::created(asyncResp->res);
623e5aaf047SAppaRao Puli asyncResp->res.addHeader(
624e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id);
6257e860f15SJohn Edward Broadbent });
626e5aaf047SAppaRao Puli }
627e5aaf047SAppaRao Puli
requestRoutesEventDestination(App & app)6287e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app)
629e5aaf047SAppaRao Puli {
6309d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
631ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination)
6327e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)(
63345ca1b86SEd Tanous [&app](const crow::Request& req,
6347e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
6357e860f15SJohn Edward Broadbent const std::string& param) {
6363ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
63745ca1b86SEd Tanous {
63845ca1b86SEd Tanous return;
63945ca1b86SEd Tanous }
6403d30708fSChicago Duan
6413d30708fSChicago Duan if (param.starts_with("snmp"))
6423d30708fSChicago Duan {
6433d30708fSChicago Duan getSnmpTrapClient(asyncResp, param);
6443d30708fSChicago Duan return;
6453d30708fSChicago Duan }
6463d30708fSChicago Duan
647b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue =
6487e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param);
649b52664e2SAppaRao Puli if (subValue == nullptr)
650e5aaf047SAppaRao Puli {
651002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found);
652e5aaf047SAppaRao Puli return;
653e5aaf047SAppaRao Puli }
6547e860f15SJohn Edward Broadbent const std::string& id = param;
655e5aaf047SAppaRao Puli
6561476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] =
6573d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination";
6581476687dSEd Tanous asyncResp->res.jsonValue["Protocol"] = "Redfish";
6593b32780dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
6603b32780dSEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id);
661e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Id"] = id;
662e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
663002d39b4SEd Tanous asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
664b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText;
665e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] =
666b52664e2SAppaRao Puli subValue->subscriptionType;
667002d39b4SEd Tanous asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array();
668002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
669e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] =
670b52664e2SAppaRao Puli subValue->registryPrefixes;
671002d39b4SEd Tanous asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
672e56f254cSSunitha Harish
673002d39b4SEd Tanous asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
674002d39b4SEd Tanous asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
675144b6318SAppaRao Puli
6761476687dSEd Tanous nlohmann::json::array_t mrdJsonArray;
677144b6318SAppaRao Puli for (const auto& mdrUri : subValue->metricReportDefinitions)
678144b6318SAppaRao Puli {
6791476687dSEd Tanous nlohmann::json::object_t mdr;
6801476687dSEd Tanous mdr["@odata.id"] = mdrUri;
6811476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr));
682144b6318SAppaRao Puli }
683002d39b4SEd Tanous asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
6847e860f15SJohn Edward Broadbent });
6859d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
686ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR
687ed398213SEd Tanous // ConfigureSelf
6887eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220
689ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination)
690432a890cSEd Tanous .privileges({{"ConfigureManager"}})
6917e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)(
69245ca1b86SEd Tanous [&app](const crow::Request& req,
6937e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
6947e860f15SJohn Edward Broadbent const std::string& param) {
6953ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
69645ca1b86SEd Tanous {
69745ca1b86SEd Tanous return;
69845ca1b86SEd Tanous }
699b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue =
7007e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param);
701b52664e2SAppaRao Puli if (subValue == nullptr)
702e5aaf047SAppaRao Puli {
703002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found);
704e5aaf047SAppaRao Puli return;
705e5aaf047SAppaRao Puli }
706e5aaf047SAppaRao Puli
707e5aaf047SAppaRao Puli std::optional<std::string> context;
708e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy;
709*78d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers;
710e5aaf047SAppaRao Puli
711002d39b4SEd Tanous if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context,
712002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy,
713002d39b4SEd Tanous "HttpHeaders", headers))
714e5aaf047SAppaRao Puli {
715e5aaf047SAppaRao Puli return;
716e5aaf047SAppaRao Puli }
717e5aaf047SAppaRao Puli
718e5aaf047SAppaRao Puli if (context)
719e5aaf047SAppaRao Puli {
720b52664e2SAppaRao Puli subValue->customText = *context;
721e5aaf047SAppaRao Puli }
722e5aaf047SAppaRao Puli
723e5aaf047SAppaRao Puli if (headers)
724e5aaf047SAppaRao Puli {
725601c71aeSEd Tanous boost::beast::http::fields fields;
726*78d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers)
727601c71aeSEd Tanous {
728*78d4ec4fSEd Tanous for (const auto& it : headerChunk)
729601c71aeSEd Tanous {
730601c71aeSEd Tanous const std::string* value =
731*78d4ec4fSEd Tanous it.second.get_ptr<const std::string*>();
732601c71aeSEd Tanous if (value == nullptr)
733601c71aeSEd Tanous {
734601c71aeSEd Tanous messages::propertyValueFormatError(
735*78d4ec4fSEd Tanous asyncResp->res, it.second,
736*78d4ec4fSEd Tanous "HttpHeaders/" + it.first);
737601c71aeSEd Tanous return;
738601c71aeSEd Tanous }
739*78d4ec4fSEd Tanous fields.set(it.first, *value);
740601c71aeSEd Tanous }
741601c71aeSEd Tanous }
742*78d4ec4fSEd Tanous subValue->httpHeaders = std::move(fields);
743e5aaf047SAppaRao Puli }
744e5aaf047SAppaRao Puli
745e5aaf047SAppaRao Puli if (retryPolicy)
746e5aaf047SAppaRao Puli {
7473544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
7483544d2a7SEd Tanous supportedRetryPolicies.end())
749e5aaf047SAppaRao Puli {
750002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
751e5aaf047SAppaRao Puli "DeliveryRetryPolicy");
752e5aaf047SAppaRao Puli return;
753e5aaf047SAppaRao Puli }
754b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy;
755e5aaf047SAppaRao Puli }
756e5aaf047SAppaRao Puli
757b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData();
7587e860f15SJohn Edward Broadbent });
7599d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
760ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR
761ed398213SEd Tanous // ConfigureSelf
7627eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220
763ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination)
764432a890cSEd Tanous .privileges({{"ConfigureManager"}})
7657e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)(
76645ca1b86SEd Tanous [&app](const crow::Request& req,
7677e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7687e860f15SJohn Edward Broadbent const std::string& param) {
7693ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
77045ca1b86SEd Tanous {
77145ca1b86SEd Tanous return;
77245ca1b86SEd Tanous }
7733d30708fSChicago Duan
7743d30708fSChicago Duan if (param.starts_with("snmp"))
7753d30708fSChicago Duan {
7763d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param);
7773d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(param);
7783d30708fSChicago Duan return;
7793d30708fSChicago Duan }
7803d30708fSChicago Duan
781002d39b4SEd Tanous if (!EventServiceManager::getInstance().isSubscriptionExist(param))
782e5aaf047SAppaRao Puli {
783002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found);
784e5aaf047SAppaRao Puli return;
785e5aaf047SAppaRao Puli }
7867e860f15SJohn Edward Broadbent EventServiceManager::getInstance().deleteSubscription(param);
7877e860f15SJohn Edward Broadbent });
788e5aaf047SAppaRao Puli }
789e5aaf047SAppaRao Puli
790e5aaf047SAppaRao Puli } // namespace redfish
791