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> 273d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp> 283d30708fSChicago Duan #include <utils/dbus_utils.hpp> 29ed398213SEd Tanous 303d30708fSChicago Duan #include <charconv> 313d30708fSChicago Duan #include <memory> 32*3544d2a7SEd Tanous #include <ranges> 331e270c5fSPatrick Williams #include <span> 343d30708fSChicago Duan #include <string> 351e270c5fSPatrick Williams 36e5aaf047SAppaRao Puli namespace redfish 37e5aaf047SAppaRao Puli { 38e5aaf047SAppaRao Puli 39156d6b00SAppaRao Puli static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = { 40156d6b00SAppaRao Puli eventFormatType, metricReportFormatType}; 41e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRegPrefixes = { 42b304bd79SP Dheeraj Srujan Kumar "Base", "OpenBMC", "TaskEvent"}; 43e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRetryPolicies = { 44e5aaf047SAppaRao Puli "TerminateAfterRetries", "SuspendRetries", "RetryForever"}; 45e5aaf047SAppaRao Puli 46e56f254cSSunitha Harish static constexpr const std::array<const char*, 1> supportedResourceTypes = { 47e56f254cSSunitha Harish "Task"}; 48e56f254cSSunitha Harish 497e860f15SJohn Edward Broadbent inline void requestRoutesEventService(App& app) 50e5aaf047SAppaRao Puli { 517e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 52ed398213SEd Tanous .privileges(redfish::privileges::getEventService) 53002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 54002d39b4SEd Tanous [&app](const crow::Request& req, 55002d39b4SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 563ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 5745ca1b86SEd Tanous { 5845ca1b86SEd Tanous return; 5945ca1b86SEd Tanous } 601476687dSEd Tanous 611476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService"; 621476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 631476687dSEd Tanous "#EventService.v1_5_0.EventService"; 641476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "EventService"; 651476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Event Service"; 665e44e3d8SAppaRao Puli asyncResp->res.jsonValue["ServerSentEventUri"] = 675e44e3d8SAppaRao Puli "/redfish/v1/EventService/SSE"; 685e44e3d8SAppaRao Puli 691476687dSEd Tanous asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] = 701476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 71002d39b4SEd Tanous asyncResp->res 72002d39b4SEd Tanous .jsonValue["Actions"]["#EventService.SubmitTestEvent"]["target"] = 731476687dSEd Tanous "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"; 74e5aaf047SAppaRao Puli 7528afb49cSJunLin Chen const persistent_data::EventServiceConfig eventServiceConfig = 7628afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 7728afb49cSJunLin Chen .getEventServiceConfig(); 787d1cc387SAppaRao Puli 797d1cc387SAppaRao Puli asyncResp->res.jsonValue["Status"]["State"] = 8028afb49cSJunLin Chen (eventServiceConfig.enabled ? "Enabled" : "Disabled"); 81002d39b4SEd Tanous asyncResp->res.jsonValue["ServiceEnabled"] = eventServiceConfig.enabled; 827e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] = 8328afb49cSJunLin Chen eventServiceConfig.retryAttempts; 84e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] = 8528afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval; 86002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes; 870fda0f12SGeorge Liu asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes; 880fda0f12SGeorge Liu asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes; 8907941a88SAyushi Smriti 90613dabeaSEd Tanous nlohmann::json::object_t supportedSSEFilters; 91613dabeaSEd Tanous supportedSSEFilters["EventFormatType"] = true; 92613dabeaSEd Tanous supportedSSEFilters["MessageId"] = true; 93613dabeaSEd Tanous supportedSSEFilters["MetricReportDefinition"] = true; 94613dabeaSEd Tanous supportedSSEFilters["RegistryPrefix"] = true; 95613dabeaSEd Tanous supportedSSEFilters["OriginResource"] = false; 96613dabeaSEd Tanous supportedSSEFilters["ResourceType"] = false; 9707941a88SAyushi Smriti 9807941a88SAyushi Smriti asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] = 99613dabeaSEd Tanous std::move(supportedSSEFilters); 1007e860f15SJohn Edward Broadbent }); 101e5aaf047SAppaRao Puli 1027e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 103ed398213SEd Tanous .privileges(redfish::privileges::patchEventService) 1047e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 10545ca1b86SEd Tanous [&app](const crow::Request& req, 10645ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1073ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 108e5aaf047SAppaRao Puli { 10945ca1b86SEd Tanous return; 11045ca1b86SEd Tanous } 111e5aaf047SAppaRao Puli std::optional<bool> serviceEnabled; 112e5aaf047SAppaRao Puli std::optional<uint32_t> retryAttemps; 113e5aaf047SAppaRao Puli std::optional<uint32_t> retryInterval; 114e5aaf047SAppaRao Puli 11515ed6780SWilly Tu if (!json_util::readJsonPatch( 1167e860f15SJohn Edward Broadbent req, asyncResp->res, "ServiceEnabled", serviceEnabled, 1177e860f15SJohn Edward Broadbent "DeliveryRetryAttempts", retryAttemps, 1187e860f15SJohn Edward Broadbent "DeliveryRetryIntervalSeconds", retryInterval)) 119e5aaf047SAppaRao Puli { 120e5aaf047SAppaRao Puli return; 121e5aaf047SAppaRao Puli } 122e5aaf047SAppaRao Puli 12328afb49cSJunLin Chen persistent_data::EventServiceConfig eventServiceConfig = 12428afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 12528afb49cSJunLin Chen .getEventServiceConfig(); 1267d1cc387SAppaRao Puli 127e5aaf047SAppaRao Puli if (serviceEnabled) 128e5aaf047SAppaRao Puli { 12928afb49cSJunLin Chen eventServiceConfig.enabled = *serviceEnabled; 130e5aaf047SAppaRao Puli } 131e5aaf047SAppaRao Puli 132e5aaf047SAppaRao Puli if (retryAttemps) 133e5aaf047SAppaRao Puli { 134e5aaf047SAppaRao Puli // Supported range [1-3] 135e5aaf047SAppaRao Puli if ((*retryAttemps < 1) || (*retryAttemps > 3)) 136e5aaf047SAppaRao Puli { 137e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 138e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryAttemps), 139e5aaf047SAppaRao Puli "DeliveryRetryAttempts", "[1-3]"); 140e5aaf047SAppaRao Puli } 141e5aaf047SAppaRao Puli else 142e5aaf047SAppaRao Puli { 14328afb49cSJunLin Chen eventServiceConfig.retryAttempts = *retryAttemps; 144e5aaf047SAppaRao Puli } 145e5aaf047SAppaRao Puli } 146e5aaf047SAppaRao Puli 147e5aaf047SAppaRao Puli if (retryInterval) 148e5aaf047SAppaRao Puli { 14933a32b34SGunnar Mills // Supported range [5 - 180] 15033a32b34SGunnar Mills if ((*retryInterval < 5) || (*retryInterval > 180)) 151e5aaf047SAppaRao Puli { 152e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 153e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryInterval), 15433a32b34SGunnar Mills "DeliveryRetryIntervalSeconds", "[5-180]"); 155e5aaf047SAppaRao Puli } 156e5aaf047SAppaRao Puli else 157e5aaf047SAppaRao Puli { 158002d39b4SEd Tanous eventServiceConfig.retryTimeoutInterval = *retryInterval; 159e5aaf047SAppaRao Puli } 160e5aaf047SAppaRao Puli } 161e5aaf047SAppaRao Puli 1627d1cc387SAppaRao Puli EventServiceManager::getInstance().setEventServiceConfig( 16328afb49cSJunLin Chen eventServiceConfig); 1647e860f15SJohn Edward Broadbent }); 1650b4bdd93SAppaRao Puli } 1660b4bdd93SAppaRao Puli 1677e860f15SJohn Edward Broadbent inline void requestRoutesSubmitTestEvent(App& app) 1680b4bdd93SAppaRao Puli { 1697e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 1707e860f15SJohn Edward Broadbent app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/") 171ed398213SEd Tanous .privileges(redfish::privileges::postEventService) 1727e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 17345ca1b86SEd Tanous [&app](const crow::Request& req, 1747e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1753ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 17645ca1b86SEd Tanous { 17745ca1b86SEd Tanous return; 17845ca1b86SEd Tanous } 1796ba8c82eSsunharis_in if (!EventServiceManager::getInstance().sendTestEventLog()) 1806ba8c82eSsunharis_in { 1816ba8c82eSsunharis_in messages::serviceDisabled(asyncResp->res, 1826ba8c82eSsunharis_in "/redfish/v1/EventService/"); 1836ba8c82eSsunharis_in return; 1846ba8c82eSsunharis_in } 1858d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 1867e860f15SJohn Edward Broadbent }); 187e5aaf047SAppaRao Puli } 188e5aaf047SAppaRao Puli 1893d30708fSChicago Duan inline void doSubscriptionCollection( 190e81de512SEd Tanous const boost::system::error_code& ec, 1913d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1923d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) 1933d30708fSChicago Duan { 1943d30708fSChicago Duan if (ec) 1953d30708fSChicago Duan { 1961306101eSEd Tanous if (ec.value() == EBADR || ec.value() == EHOSTUNREACH) 1973d30708fSChicago Duan { 1983d30708fSChicago Duan // This is an optional process so just return if it isn't there 1993d30708fSChicago Duan return; 2003d30708fSChicago Duan } 2013d30708fSChicago Duan 20262598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec); 2033d30708fSChicago Duan messages::internalError(asyncResp->res); 2043d30708fSChicago Duan return; 2053d30708fSChicago Duan } 2063d30708fSChicago Duan nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 2073d30708fSChicago Duan for (const auto& objpath : resp) 2083d30708fSChicago Duan { 2093d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first); 2103d30708fSChicago Duan const std::string snmpId = path.filename(); 2113d30708fSChicago Duan if (snmpId.empty()) 2123d30708fSChicago Duan { 21362598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong"); 2143d30708fSChicago Duan messages::internalError(asyncResp->res); 2153d30708fSChicago Duan return; 2163d30708fSChicago Duan } 2173d30708fSChicago Duan 2183d30708fSChicago Duan getSnmpSubscriptionList(asyncResp, snmpId, memberArray); 2193d30708fSChicago Duan } 2203d30708fSChicago Duan } 2213d30708fSChicago Duan 2227e860f15SJohn Edward Broadbent inline void requestRoutesEventDestinationCollection(App& app) 223e5aaf047SAppaRao Puli { 2241ebe3e41SGayathri Leburu BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 225ed398213SEd Tanous .privileges(redfish::privileges::getEventDestinationCollection) 2267e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 22745ca1b86SEd Tanous [&app](const crow::Request& req, 2287e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2293ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 23045ca1b86SEd Tanous { 23145ca1b86SEd Tanous return; 23245ca1b86SEd Tanous } 2331476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2341476687dSEd Tanous "#EventDestinationCollection.EventDestinationCollection"; 2351476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2361476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 237002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Event Destination Collections"; 238e5aaf047SAppaRao Puli 239002d39b4SEd Tanous nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 240e5aaf047SAppaRao Puli 241b52664e2SAppaRao Puli std::vector<std::string> subscripIds = 242b52664e2SAppaRao Puli EventServiceManager::getInstance().getAllIDs(); 243b52664e2SAppaRao Puli memberArray = nlohmann::json::array(); 244002d39b4SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size(); 245b52664e2SAppaRao Puli 246b52664e2SAppaRao Puli for (const std::string& id : subscripIds) 247e5aaf047SAppaRao Puli { 2481476687dSEd Tanous nlohmann::json::object_t member; 2493d30708fSChicago Duan member["@odata.id"] = boost::urls::format( 2503d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}" + id); 251b2ba3072SPatrick Williams memberArray.emplace_back(std::move(member)); 252e5aaf047SAppaRao Puli } 2533d30708fSChicago Duan crow::connections::systemBus->async_method_call( 254e81de512SEd Tanous [asyncResp](const boost::system::error_code& ec, 2553d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) { 2563d30708fSChicago Duan doSubscriptionCollection(ec, asyncResp, resp); 2573d30708fSChicago Duan }, 2583d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 2593d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 2603d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 2617e860f15SJohn Edward Broadbent }); 2623d30708fSChicago Duan 2637e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 2647eeafa76SAbhishek Patel .privileges(redfish::privileges::postEventDestinationCollection) 265002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 266002d39b4SEd Tanous [&app](const crow::Request& req, 2677e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2683ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 26945ca1b86SEd Tanous { 27045ca1b86SEd Tanous return; 27145ca1b86SEd Tanous } 272fffb8c1fSEd Tanous if (EventServiceManager::getInstance().getNumberOfSubscriptions() >= 273fffb8c1fSEd Tanous maxNoOfSubscriptions) 274e5aaf047SAppaRao Puli { 275e5aaf047SAppaRao Puli messages::eventSubscriptionLimitExceeded(asyncResp->res); 276e5aaf047SAppaRao Puli return; 277e5aaf047SAppaRao Puli } 278e5aaf047SAppaRao Puli std::string destUrl; 279e5aaf047SAppaRao Puli std::string protocol; 280e5aaf047SAppaRao Puli std::optional<std::string> context; 281e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType; 28223a21a1cSEd Tanous std::optional<std::string> eventFormatType2; 283e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 284e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds; 285e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes; 286e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes; 287e5aaf047SAppaRao Puli std::optional<std::vector<nlohmann::json>> headers; 288144b6318SAppaRao Puli std::optional<std::vector<nlohmann::json>> mrdJsonArray; 289e5aaf047SAppaRao Puli 29015ed6780SWilly Tu if (!json_util::readJsonPatch( 291002d39b4SEd Tanous req, asyncResp->res, "Destination", destUrl, "Context", context, 292002d39b4SEd Tanous "Protocol", protocol, "SubscriptionType", subscriptionType, 293002d39b4SEd Tanous "EventFormatType", eventFormatType2, "HttpHeaders", headers, 294002d39b4SEd Tanous "RegistryPrefixes", regPrefixes, "MessageIds", msgIds, 295002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions", 296002d39b4SEd Tanous mrdJsonArray, "ResourceTypes", resTypes)) 297e5aaf047SAppaRao Puli { 298e5aaf047SAppaRao Puli return; 299e5aaf047SAppaRao Puli } 300e5aaf047SAppaRao Puli 301600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers 302600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000; 303600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize) 304600af5f1SAppaRao Puli { 305600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination", 306600af5f1SAppaRao Puli maxDestinationSize); 307600af5f1SAppaRao Puli return; 308600af5f1SAppaRao Puli } 309600af5f1SAppaRao Puli 310dd28ba82SAppaRao Puli if (regPrefixes && msgIds) 311dd28ba82SAppaRao Puli { 31226f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty()) 313dd28ba82SAppaRao Puli { 314002d39b4SEd Tanous messages::propertyValueConflict(asyncResp->res, "MessageIds", 315002d39b4SEd Tanous "RegistryPrefixes"); 316dd28ba82SAppaRao Puli return; 317dd28ba82SAppaRao Puli } 318dd28ba82SAppaRao Puli } 319dd28ba82SAppaRao Puli 320eb1c47d3SEd Tanous std::string host; 321eb1c47d3SEd Tanous std::string urlProto; 322eb1c47d3SEd Tanous uint16_t port = 0; 323eb1c47d3SEd Tanous std::string path; 324eb1c47d3SEd Tanous 325002d39b4SEd Tanous if (!crow::utility::validateAndSplitUrl(destUrl, urlProto, host, port, 326002d39b4SEd Tanous path)) 327e5aaf047SAppaRao Puli { 32862598e31SEd Tanous BMCWEB_LOG_WARNING("Failed to validate and split destination url"); 329e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl, 330e5aaf047SAppaRao Puli "Destination"); 331e5aaf047SAppaRao Puli return; 332e5aaf047SAppaRao Puli } 333b52664e2SAppaRao Puli 3343d30708fSChicago Duan if (protocol == "SNMPv2c") 3353d30708fSChicago Duan { 3363d30708fSChicago Duan if (context) 3373d30708fSChicago Duan { 3383d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context", 3393d30708fSChicago Duan "Protocol"); 3403d30708fSChicago Duan return; 3413d30708fSChicago Duan } 3423d30708fSChicago Duan if (eventFormatType2) 3433d30708fSChicago Duan { 3443d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3453d30708fSChicago Duan "EventFormatType", "Protocol"); 3463d30708fSChicago Duan return; 3473d30708fSChicago Duan } 3483d30708fSChicago Duan if (retryPolicy) 3493d30708fSChicago Duan { 3503d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "RetryPolicy", 3513d30708fSChicago Duan "Protocol"); 3523d30708fSChicago Duan return; 3533d30708fSChicago Duan } 3543d30708fSChicago Duan if (msgIds) 3553d30708fSChicago Duan { 3563d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "MessageIds", 3573d30708fSChicago Duan "Protocol"); 3583d30708fSChicago Duan return; 3593d30708fSChicago Duan } 3603d30708fSChicago Duan if (regPrefixes) 3613d30708fSChicago Duan { 3623d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3633d30708fSChicago Duan "RegistryPrefixes", "Protocol"); 3643d30708fSChicago Duan return; 3653d30708fSChicago Duan } 3663d30708fSChicago Duan if (resTypes) 3673d30708fSChicago Duan { 3683d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "ResourceTypes", 3693d30708fSChicago Duan "Protocol"); 3703d30708fSChicago Duan return; 3713d30708fSChicago Duan } 3723d30708fSChicago Duan if (headers) 3733d30708fSChicago Duan { 3743d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "HttpHeaders", 3753d30708fSChicago Duan "Protocol"); 3763d30708fSChicago Duan return; 3773d30708fSChicago Duan } 3783d30708fSChicago Duan if (mrdJsonArray) 3793d30708fSChicago Duan { 3803d30708fSChicago Duan messages::propertyValueConflict( 3813d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol"); 3823d30708fSChicago Duan return; 3833d30708fSChicago Duan } 3843d30708fSChicago Duan 3853d30708fSChicago Duan addSnmpTrapClient(asyncResp, host, port); 3863d30708fSChicago Duan return; 3873d30708fSChicago Duan } 3883d30708fSChicago Duan 389b52664e2SAppaRao Puli if (path.empty()) 390b52664e2SAppaRao Puli { 391b52664e2SAppaRao Puli path = "/"; 392b52664e2SAppaRao Puli } 3933d30708fSChicago Duan 394f8ca6d79SEd Tanous std::shared_ptr<Subscription> subValue = std::make_shared<Subscription>( 395f8ca6d79SEd Tanous host, port, path, urlProto, app.ioContext()); 396b52664e2SAppaRao Puli 397b52664e2SAppaRao Puli subValue->destinationUrl = destUrl; 398e5aaf047SAppaRao Puli 399e5aaf047SAppaRao Puli if (subscriptionType) 400e5aaf047SAppaRao Puli { 401e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent") 402e5aaf047SAppaRao Puli { 403fffb8c1fSEd Tanous messages::propertyValueNotInList( 404fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType"); 405e5aaf047SAppaRao Puli return; 406e5aaf047SAppaRao Puli } 407b52664e2SAppaRao Puli subValue->subscriptionType = *subscriptionType; 408e5aaf047SAppaRao Puli } 409e5aaf047SAppaRao Puli else 410e5aaf047SAppaRao Puli { 411b52664e2SAppaRao Puli subValue->subscriptionType = "RedfishEvent"; // Default 412e5aaf047SAppaRao Puli } 413e5aaf047SAppaRao Puli 414e5aaf047SAppaRao Puli if (protocol != "Redfish") 415e5aaf047SAppaRao Puli { 416e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol, 417e5aaf047SAppaRao Puli "Protocol"); 418e5aaf047SAppaRao Puli return; 419e5aaf047SAppaRao Puli } 420b52664e2SAppaRao Puli subValue->protocol = protocol; 421e5aaf047SAppaRao Puli 42223a21a1cSEd Tanous if (eventFormatType2) 423e5aaf047SAppaRao Puli { 424*3544d2a7SEd Tanous if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) == 425*3544d2a7SEd Tanous supportedEvtFormatTypes.end()) 426e5aaf047SAppaRao Puli { 427fffb8c1fSEd Tanous messages::propertyValueNotInList( 428fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType"); 429e5aaf047SAppaRao Puli return; 430e5aaf047SAppaRao Puli } 43123a21a1cSEd Tanous subValue->eventFormatType = *eventFormatType2; 432e5aaf047SAppaRao Puli } 433e5aaf047SAppaRao Puli else 434e5aaf047SAppaRao Puli { 435e5aaf047SAppaRao Puli // If not specified, use default "Event" 43623a21a1cSEd Tanous subValue->eventFormatType = "Event"; 437e5aaf047SAppaRao Puli } 438e5aaf047SAppaRao Puli 439e5aaf047SAppaRao Puli if (context) 440e5aaf047SAppaRao Puli { 441600af5f1SAppaRao Puli // This value is selected aribitrarily. 442600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256; 443600af5f1SAppaRao Puli if (context->size() > maxContextSize) 444600af5f1SAppaRao Puli { 445600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context", 446600af5f1SAppaRao Puli maxContextSize); 447600af5f1SAppaRao Puli return; 448600af5f1SAppaRao Puli } 449b52664e2SAppaRao Puli subValue->customText = *context; 450e5aaf047SAppaRao Puli } 451e5aaf047SAppaRao Puli 452e5aaf047SAppaRao Puli if (headers) 453e5aaf047SAppaRao Puli { 454600af5f1SAppaRao Puli size_t cumulativeLen = 0; 455600af5f1SAppaRao Puli 456601c71aeSEd Tanous for (const nlohmann::json& headerChunk : *headers) 457601c71aeSEd Tanous { 458600af5f1SAppaRao Puli std::string hdr{headerChunk.dump( 459600af5f1SAppaRao Puli -1, ' ', true, nlohmann::json::error_handler_t::replace)}; 460600af5f1SAppaRao Puli cumulativeLen += hdr.length(); 461600af5f1SAppaRao Puli 462600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp 463600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096; 464600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED) 465600af5f1SAppaRao Puli { 466600af5f1SAppaRao Puli messages::arraySizeTooLong(asyncResp->res, "HttpHeaders", 467600af5f1SAppaRao Puli maxHeaderSizeED); 468600af5f1SAppaRao Puli return; 469600af5f1SAppaRao Puli } 470601c71aeSEd Tanous for (const auto& item : headerChunk.items()) 471601c71aeSEd Tanous { 472601c71aeSEd Tanous const std::string* value = 473601c71aeSEd Tanous item.value().get_ptr<const std::string*>(); 474601c71aeSEd Tanous if (value == nullptr) 475601c71aeSEd Tanous { 476601c71aeSEd Tanous messages::propertyValueFormatError( 477f818b04dSEd Tanous asyncResp->res, item.value(), 478601c71aeSEd Tanous "HttpHeaders/" + item.key()); 479601c71aeSEd Tanous return; 480601c71aeSEd Tanous } 481601c71aeSEd Tanous subValue->httpHeaders.set(item.key(), *value); 482601c71aeSEd Tanous } 483601c71aeSEd Tanous } 484e5aaf047SAppaRao Puli } 485e5aaf047SAppaRao Puli 486e5aaf047SAppaRao Puli if (regPrefixes) 487e5aaf047SAppaRao Puli { 488e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes) 489e5aaf047SAppaRao Puli { 490*3544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) == 491*3544d2a7SEd Tanous supportedRegPrefixes.end()) 492e5aaf047SAppaRao Puli { 493fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it, 494fffb8c1fSEd Tanous "RegistryPrefixes"); 495e5aaf047SAppaRao Puli return; 496e5aaf047SAppaRao Puli } 497e5aaf047SAppaRao Puli } 498b52664e2SAppaRao Puli subValue->registryPrefixes = *regPrefixes; 499e5aaf047SAppaRao Puli } 500e5aaf047SAppaRao Puli 501e56f254cSSunitha Harish if (resTypes) 502e56f254cSSunitha Harish { 503e56f254cSSunitha Harish for (const std::string& it : *resTypes) 504e56f254cSSunitha Harish { 505*3544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) == 506*3544d2a7SEd Tanous supportedResourceTypes.end()) 507e56f254cSSunitha Harish { 508e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it, 509e56f254cSSunitha Harish "ResourceTypes"); 510e56f254cSSunitha Harish return; 511e56f254cSSunitha Harish } 512e56f254cSSunitha Harish } 513e56f254cSSunitha Harish subValue->resourceTypes = *resTypes; 514e56f254cSSunitha Harish } 515e56f254cSSunitha Harish 516e5aaf047SAppaRao Puli if (msgIds) 517e5aaf047SAppaRao Puli { 518b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix; 519b304bd79SP Dheeraj Srujan Kumar 5207e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all 5217e860f15SJohn Edward Broadbent // supported prefixes 522b304bd79SP Dheeraj Srujan Kumar if (subValue->registryPrefixes.empty()) 523b304bd79SP Dheeraj Srujan Kumar { 524b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(), 525b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end()); 526b304bd79SP Dheeraj Srujan Kumar } 527b304bd79SP Dheeraj Srujan Kumar else 528b304bd79SP Dheeraj Srujan Kumar { 529b304bd79SP Dheeraj Srujan Kumar registryPrefix = subValue->registryPrefixes; 530b304bd79SP Dheeraj Srujan Kumar } 531b304bd79SP Dheeraj Srujan Kumar 532b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds) 533b304bd79SP Dheeraj Srujan Kumar { 534b304bd79SP Dheeraj Srujan Kumar bool validId = false; 535b304bd79SP Dheeraj Srujan Kumar 536b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry 537b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix) 538b304bd79SP Dheeraj Srujan Kumar { 539fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry> 540fffb8c1fSEd Tanous registry = 541fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it); 542b304bd79SP Dheeraj Srujan Kumar 543*3544d2a7SEd Tanous if (std::ranges::any_of( 544*3544d2a7SEd Tanous registry, 545fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry& 546fffb8c1fSEd Tanous messageEntry) { 54755f79e6fSEd Tanous return id == messageEntry.first; 548b304bd79SP Dheeraj Srujan Kumar })) 549b304bd79SP Dheeraj Srujan Kumar { 550b304bd79SP Dheeraj Srujan Kumar validId = true; 551b304bd79SP Dheeraj Srujan Kumar break; 552b304bd79SP Dheeraj Srujan Kumar } 553b304bd79SP Dheeraj Srujan Kumar } 554b304bd79SP Dheeraj Srujan Kumar 555b304bd79SP Dheeraj Srujan Kumar if (!validId) 556b304bd79SP Dheeraj Srujan Kumar { 557b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id, 558b304bd79SP Dheeraj Srujan Kumar "MessageIds"); 559b304bd79SP Dheeraj Srujan Kumar return; 560b304bd79SP Dheeraj Srujan Kumar } 561b304bd79SP Dheeraj Srujan Kumar } 562b304bd79SP Dheeraj Srujan Kumar 563b52664e2SAppaRao Puli subValue->registryMsgIds = *msgIds; 564e5aaf047SAppaRao Puli } 565e5aaf047SAppaRao Puli 566e5aaf047SAppaRao Puli if (retryPolicy) 567e5aaf047SAppaRao Puli { 568*3544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 569*3544d2a7SEd Tanous supportedRetryPolicies.end()) 570e5aaf047SAppaRao Puli { 571002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 572002d39b4SEd Tanous "DeliveryRetryPolicy"); 573e5aaf047SAppaRao Puli return; 574e5aaf047SAppaRao Puli } 575b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 576e5aaf047SAppaRao Puli } 577e5aaf047SAppaRao Puli else 578e5aaf047SAppaRao Puli { 579e5aaf047SAppaRao Puli // Default "TerminateAfterRetries" 580b52664e2SAppaRao Puli subValue->retryPolicy = "TerminateAfterRetries"; 581e5aaf047SAppaRao Puli } 582e5aaf047SAppaRao Puli 583144b6318SAppaRao Puli if (mrdJsonArray) 584156d6b00SAppaRao Puli { 585144b6318SAppaRao Puli for (nlohmann::json& mrdObj : *mrdJsonArray) 586144b6318SAppaRao Puli { 587144b6318SAppaRao Puli std::string mrdUri; 588ea2e6eecSWilly Tu 589002d39b4SEd Tanous if (!json_util::readJson(mrdObj, asyncResp->res, "@odata.id", 590002d39b4SEd Tanous mrdUri)) 591ea2e6eecSWilly Tu 592144b6318SAppaRao Puli { 593144b6318SAppaRao Puli return; 594144b6318SAppaRao Puli } 595ea2e6eecSWilly Tu subValue->metricReportDefinitions.emplace_back(mrdUri); 596144b6318SAppaRao Puli } 597156d6b00SAppaRao Puli } 598156d6b00SAppaRao Puli 599b52664e2SAppaRao Puli std::string id = 600fffb8c1fSEd Tanous EventServiceManager::getInstance().addSubscription(subValue); 601b52664e2SAppaRao Puli if (id.empty()) 602e5aaf047SAppaRao Puli { 603e5aaf047SAppaRao Puli messages::internalError(asyncResp->res); 604e5aaf047SAppaRao Puli return; 605e5aaf047SAppaRao Puli } 606e5aaf047SAppaRao Puli 607e5aaf047SAppaRao Puli messages::created(asyncResp->res); 608e5aaf047SAppaRao Puli asyncResp->res.addHeader( 609e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id); 6107e860f15SJohn Edward Broadbent }); 611e5aaf047SAppaRao Puli } 612e5aaf047SAppaRao Puli 6137e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app) 614e5aaf047SAppaRao Puli { 6159d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 616ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination) 6177e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 61845ca1b86SEd Tanous [&app](const crow::Request& req, 6197e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6207e860f15SJohn Edward Broadbent const std::string& param) { 6213ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 62245ca1b86SEd Tanous { 62345ca1b86SEd Tanous return; 62445ca1b86SEd Tanous } 6253d30708fSChicago Duan 6263d30708fSChicago Duan if (param.starts_with("snmp")) 6273d30708fSChicago Duan { 6283d30708fSChicago Duan getSnmpTrapClient(asyncResp, param); 6293d30708fSChicago Duan return; 6303d30708fSChicago Duan } 6313d30708fSChicago Duan 632b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6337e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 634b52664e2SAppaRao Puli if (subValue == nullptr) 635e5aaf047SAppaRao Puli { 636002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 637e5aaf047SAppaRao Puli return; 638e5aaf047SAppaRao Puli } 6397e860f15SJohn Edward Broadbent const std::string& id = param; 640e5aaf047SAppaRao Puli 6411476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 6423d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination"; 6431476687dSEd Tanous asyncResp->res.jsonValue["Protocol"] = "Redfish"; 6443b32780dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 6453b32780dSEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id); 646e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Id"] = id; 647e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Name"] = "Event Destination " + id; 648002d39b4SEd Tanous asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl; 649b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText; 650e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] = 651b52664e2SAppaRao Puli subValue->subscriptionType; 652002d39b4SEd Tanous asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array(); 653002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType; 654e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] = 655b52664e2SAppaRao Puli subValue->registryPrefixes; 656002d39b4SEd Tanous asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes; 657e56f254cSSunitha Harish 658002d39b4SEd Tanous asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds; 659002d39b4SEd Tanous asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy; 660144b6318SAppaRao Puli 6611476687dSEd Tanous nlohmann::json::array_t mrdJsonArray; 662144b6318SAppaRao Puli for (const auto& mdrUri : subValue->metricReportDefinitions) 663144b6318SAppaRao Puli { 6641476687dSEd Tanous nlohmann::json::object_t mdr; 6651476687dSEd Tanous mdr["@odata.id"] = mdrUri; 6661476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr)); 667144b6318SAppaRao Puli } 668002d39b4SEd Tanous asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray; 6697e860f15SJohn Edward Broadbent }); 6709d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 671ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 672ed398213SEd Tanous // ConfigureSelf 6737eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 674ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination) 675432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 6767e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 67745ca1b86SEd Tanous [&app](const crow::Request& req, 6787e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6797e860f15SJohn Edward Broadbent const std::string& param) { 6803ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 68145ca1b86SEd Tanous { 68245ca1b86SEd Tanous return; 68345ca1b86SEd Tanous } 684b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6857e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 686b52664e2SAppaRao Puli if (subValue == nullptr) 687e5aaf047SAppaRao Puli { 688002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 689e5aaf047SAppaRao Puli return; 690e5aaf047SAppaRao Puli } 691e5aaf047SAppaRao Puli 692e5aaf047SAppaRao Puli std::optional<std::string> context; 693e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 694e5aaf047SAppaRao Puli std::optional<std::vector<nlohmann::json>> headers; 695e5aaf047SAppaRao Puli 696002d39b4SEd Tanous if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context, 697002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, 698002d39b4SEd Tanous "HttpHeaders", headers)) 699e5aaf047SAppaRao Puli { 700e5aaf047SAppaRao Puli return; 701e5aaf047SAppaRao Puli } 702e5aaf047SAppaRao Puli 703e5aaf047SAppaRao Puli if (context) 704e5aaf047SAppaRao Puli { 705b52664e2SAppaRao Puli subValue->customText = *context; 706e5aaf047SAppaRao Puli } 707e5aaf047SAppaRao Puli 708e5aaf047SAppaRao Puli if (headers) 709e5aaf047SAppaRao Puli { 710601c71aeSEd Tanous boost::beast::http::fields fields; 711601c71aeSEd Tanous for (const nlohmann::json& headerChunk : *headers) 712601c71aeSEd Tanous { 71362bafc01SPatrick Williams for (const auto& it : headerChunk.items()) 714601c71aeSEd Tanous { 715601c71aeSEd Tanous const std::string* value = 716601c71aeSEd Tanous it.value().get_ptr<const std::string*>(); 717601c71aeSEd Tanous if (value == nullptr) 718601c71aeSEd Tanous { 719601c71aeSEd Tanous messages::propertyValueFormatError( 720f818b04dSEd Tanous asyncResp->res, it.value(), 721601c71aeSEd Tanous "HttpHeaders/" + it.key()); 722601c71aeSEd Tanous return; 723601c71aeSEd Tanous } 724601c71aeSEd Tanous fields.set(it.key(), *value); 725601c71aeSEd Tanous } 726601c71aeSEd Tanous } 727601c71aeSEd Tanous subValue->httpHeaders = fields; 728e5aaf047SAppaRao Puli } 729e5aaf047SAppaRao Puli 730e5aaf047SAppaRao Puli if (retryPolicy) 731e5aaf047SAppaRao Puli { 732*3544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 733*3544d2a7SEd Tanous supportedRetryPolicies.end()) 734e5aaf047SAppaRao Puli { 735002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 736e5aaf047SAppaRao Puli "DeliveryRetryPolicy"); 737e5aaf047SAppaRao Puli return; 738e5aaf047SAppaRao Puli } 739b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 740e5aaf047SAppaRao Puli } 741e5aaf047SAppaRao Puli 742b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData(); 7437e860f15SJohn Edward Broadbent }); 7449d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 745ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 746ed398213SEd Tanous // ConfigureSelf 7477eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 748ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination) 749432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7507e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 75145ca1b86SEd Tanous [&app](const crow::Request& req, 7527e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7537e860f15SJohn Edward Broadbent const std::string& param) { 7543ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 75545ca1b86SEd Tanous { 75645ca1b86SEd Tanous return; 75745ca1b86SEd Tanous } 7583d30708fSChicago Duan 7593d30708fSChicago Duan if (param.starts_with("snmp")) 7603d30708fSChicago Duan { 7613d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param); 7623d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(param); 7633d30708fSChicago Duan return; 7643d30708fSChicago Duan } 7653d30708fSChicago Duan 766002d39b4SEd Tanous if (!EventServiceManager::getInstance().isSubscriptionExist(param)) 767e5aaf047SAppaRao Puli { 768002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 769e5aaf047SAppaRao Puli return; 770e5aaf047SAppaRao Puli } 7717e860f15SJohn Edward Broadbent EventServiceManager::getInstance().deleteSubscription(param); 7727e860f15SJohn Edward Broadbent }); 773e5aaf047SAppaRao Puli } 774e5aaf047SAppaRao Puli 775e5aaf047SAppaRao Puli } // namespace redfish 776