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 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 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 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 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; 28119bb362bSEd Tanous std::optional<bool> verifyCertificate; 282e5aaf047SAppaRao Puli std::optional<std::string> context; 283e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType; 28423a21a1cSEd Tanous std::optional<std::string> eventFormatType2; 285e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 286e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds; 287e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes; 288e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes; 28978d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 29078d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray; 291e5aaf047SAppaRao Puli 29215ed6780SWilly Tu if (!json_util::readJsonPatch( 293002d39b4SEd Tanous req, asyncResp->res, "Destination", destUrl, "Context", context, 294002d39b4SEd Tanous "Protocol", protocol, "SubscriptionType", subscriptionType, 295002d39b4SEd Tanous "EventFormatType", eventFormatType2, "HttpHeaders", headers, 296002d39b4SEd Tanous "RegistryPrefixes", regPrefixes, "MessageIds", msgIds, 297002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions", 29819bb362bSEd Tanous mrdJsonArray, "ResourceTypes", resTypes, "VerifyCertificate", 29919bb362bSEd Tanous verifyCertificate)) 300e5aaf047SAppaRao Puli { 301e5aaf047SAppaRao Puli return; 302e5aaf047SAppaRao Puli } 303e5aaf047SAppaRao Puli 304600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers 305600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000; 306600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize) 307600af5f1SAppaRao Puli { 308600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination", 309600af5f1SAppaRao Puli maxDestinationSize); 310600af5f1SAppaRao Puli return; 311600af5f1SAppaRao Puli } 312600af5f1SAppaRao Puli 313dd28ba82SAppaRao Puli if (regPrefixes && msgIds) 314dd28ba82SAppaRao Puli { 31526f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty()) 316dd28ba82SAppaRao Puli { 317002d39b4SEd Tanous messages::propertyValueConflict(asyncResp->res, "MessageIds", 318002d39b4SEd Tanous "RegistryPrefixes"); 319dd28ba82SAppaRao Puli return; 320dd28ba82SAppaRao Puli } 321dd28ba82SAppaRao Puli } 322dd28ba82SAppaRao Puli 3236fd29553SEd Tanous boost::system::result<boost::urls::url> url = 324a716aa74SEd Tanous boost::urls::parse_absolute_uri(destUrl); 325a716aa74SEd Tanous if (!url) 326e5aaf047SAppaRao Puli { 32762598e31SEd Tanous BMCWEB_LOG_WARNING("Failed to validate and split destination url"); 328e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl, 329e5aaf047SAppaRao Puli "Destination"); 330e5aaf047SAppaRao Puli return; 331e5aaf047SAppaRao Puli } 332a716aa74SEd Tanous url->normalize(); 333a716aa74SEd Tanous crow::utility::setProtocolDefaults(*url, protocol); 334a716aa74SEd Tanous crow::utility::setPortDefaults(*url); 335a716aa74SEd Tanous 336a716aa74SEd Tanous if (url->path().empty()) 337a716aa74SEd Tanous { 338a716aa74SEd Tanous url->set_path("/"); 339a716aa74SEd Tanous } 340a716aa74SEd Tanous 341a716aa74SEd Tanous if (url->has_userinfo()) 342a716aa74SEd Tanous { 343a716aa74SEd Tanous messages::propertyValueFormatError(asyncResp->res, destUrl, 344a716aa74SEd Tanous "Destination"); 345a716aa74SEd Tanous return; 346a716aa74SEd Tanous } 347b52664e2SAppaRao Puli 3483d30708fSChicago Duan if (protocol == "SNMPv2c") 3493d30708fSChicago Duan { 3503d30708fSChicago Duan if (context) 3513d30708fSChicago Duan { 3523d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context", 3533d30708fSChicago Duan "Protocol"); 3543d30708fSChicago Duan return; 3553d30708fSChicago Duan } 3563d30708fSChicago Duan if (eventFormatType2) 3573d30708fSChicago Duan { 3583d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3593d30708fSChicago Duan "EventFormatType", "Protocol"); 3603d30708fSChicago Duan return; 3613d30708fSChicago Duan } 3623d30708fSChicago Duan if (retryPolicy) 3633d30708fSChicago Duan { 3643d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "RetryPolicy", 3653d30708fSChicago Duan "Protocol"); 3663d30708fSChicago Duan return; 3673d30708fSChicago Duan } 3683d30708fSChicago Duan if (msgIds) 3693d30708fSChicago Duan { 3703d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "MessageIds", 3713d30708fSChicago Duan "Protocol"); 3723d30708fSChicago Duan return; 3733d30708fSChicago Duan } 3743d30708fSChicago Duan if (regPrefixes) 3753d30708fSChicago Duan { 3763d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3773d30708fSChicago Duan "RegistryPrefixes", "Protocol"); 3783d30708fSChicago Duan return; 3793d30708fSChicago Duan } 3803d30708fSChicago Duan if (resTypes) 3813d30708fSChicago Duan { 3823d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "ResourceTypes", 3833d30708fSChicago Duan "Protocol"); 3843d30708fSChicago Duan return; 3853d30708fSChicago Duan } 3863d30708fSChicago Duan if (headers) 3873d30708fSChicago Duan { 3883d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "HttpHeaders", 3893d30708fSChicago Duan "Protocol"); 3903d30708fSChicago Duan return; 3913d30708fSChicago Duan } 3923d30708fSChicago Duan if (mrdJsonArray) 3933d30708fSChicago Duan { 3943d30708fSChicago Duan messages::propertyValueConflict( 3953d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol"); 3963d30708fSChicago Duan return; 3973d30708fSChicago Duan } 398a716aa74SEd Tanous if (url->scheme() != "snmp") 399a716aa74SEd Tanous { 400a716aa74SEd Tanous messages::propertyValueConflict(asyncResp->res, "Destination", 401a716aa74SEd Tanous "Protocol"); 4023d30708fSChicago Duan return; 4033d30708fSChicago Duan } 4043d30708fSChicago Duan 405a716aa74SEd Tanous addSnmpTrapClient(asyncResp, url->host_address(), 406a716aa74SEd Tanous url->port_number()); 407a716aa74SEd Tanous return; 408b52664e2SAppaRao Puli } 4093d30708fSChicago Duan 410a716aa74SEd Tanous std::shared_ptr<Subscription> subValue = 411a716aa74SEd Tanous std::make_shared<Subscription>(*url, app.ioContext()); 412b52664e2SAppaRao Puli 413a716aa74SEd Tanous subValue->destinationUrl = std::move(*url); 414e5aaf047SAppaRao Puli 415e5aaf047SAppaRao Puli if (subscriptionType) 416e5aaf047SAppaRao Puli { 417e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent") 418e5aaf047SAppaRao Puli { 419fffb8c1fSEd Tanous messages::propertyValueNotInList( 420fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType"); 421e5aaf047SAppaRao Puli return; 422e5aaf047SAppaRao Puli } 423b52664e2SAppaRao Puli subValue->subscriptionType = *subscriptionType; 424e5aaf047SAppaRao Puli } 425e5aaf047SAppaRao Puli else 426e5aaf047SAppaRao Puli { 427b52664e2SAppaRao Puli subValue->subscriptionType = "RedfishEvent"; // Default 428e5aaf047SAppaRao Puli } 429e5aaf047SAppaRao Puli 430e5aaf047SAppaRao Puli if (protocol != "Redfish") 431e5aaf047SAppaRao Puli { 432e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol, 433e5aaf047SAppaRao Puli "Protocol"); 434e5aaf047SAppaRao Puli return; 435e5aaf047SAppaRao Puli } 436b52664e2SAppaRao Puli subValue->protocol = protocol; 437e5aaf047SAppaRao Puli 43819bb362bSEd Tanous if (verifyCertificate) 43919bb362bSEd Tanous { 44019bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 44119bb362bSEd Tanous } 44219bb362bSEd Tanous 44323a21a1cSEd Tanous if (eventFormatType2) 444e5aaf047SAppaRao Puli { 4453544d2a7SEd Tanous if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) == 4463544d2a7SEd Tanous supportedEvtFormatTypes.end()) 447e5aaf047SAppaRao Puli { 448fffb8c1fSEd Tanous messages::propertyValueNotInList( 449fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType"); 450e5aaf047SAppaRao Puli return; 451e5aaf047SAppaRao Puli } 45223a21a1cSEd Tanous subValue->eventFormatType = *eventFormatType2; 453e5aaf047SAppaRao Puli } 454e5aaf047SAppaRao Puli else 455e5aaf047SAppaRao Puli { 456e5aaf047SAppaRao Puli // If not specified, use default "Event" 45723a21a1cSEd Tanous subValue->eventFormatType = "Event"; 458e5aaf047SAppaRao Puli } 459e5aaf047SAppaRao Puli 460e5aaf047SAppaRao Puli if (context) 461e5aaf047SAppaRao Puli { 4628ece0e45SEd Tanous // This value is selected arbitrarily. 463600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256; 464600af5f1SAppaRao Puli if (context->size() > maxContextSize) 465600af5f1SAppaRao Puli { 466600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context", 467600af5f1SAppaRao Puli maxContextSize); 468600af5f1SAppaRao Puli return; 469600af5f1SAppaRao Puli } 470b52664e2SAppaRao Puli subValue->customText = *context; 471e5aaf047SAppaRao Puli } 472e5aaf047SAppaRao Puli 473e5aaf047SAppaRao Puli if (headers) 474e5aaf047SAppaRao Puli { 475600af5f1SAppaRao Puli size_t cumulativeLen = 0; 476600af5f1SAppaRao Puli 47778d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 478601c71aeSEd Tanous { 47978d4ec4fSEd Tanous for (const auto& item : headerChunk) 48078d4ec4fSEd Tanous { 48178d4ec4fSEd Tanous const std::string* value = 48278d4ec4fSEd Tanous item.second.get_ptr<const std::string*>(); 48378d4ec4fSEd Tanous if (value == nullptr) 48478d4ec4fSEd Tanous { 48578d4ec4fSEd Tanous messages::propertyValueFormatError( 48678d4ec4fSEd Tanous asyncResp->res, item.second, 48778d4ec4fSEd Tanous "HttpHeaders/" + item.first); 48878d4ec4fSEd Tanous return; 48978d4ec4fSEd Tanous } 49078d4ec4fSEd Tanous // Adding a new json value is the size of the key, + 49178d4ec4fSEd Tanous // the size of the value + 2 * 2 quotes for each, + 49278d4ec4fSEd Tanous // the colon and space between. example: 49378d4ec4fSEd Tanous // "key": "value" 49478d4ec4fSEd Tanous cumulativeLen += item.first.size() + value->size() + 6; 495600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp 496600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096; 497600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED) 498600af5f1SAppaRao Puli { 49978d4ec4fSEd Tanous messages::arraySizeTooLong( 50078d4ec4fSEd Tanous asyncResp->res, "HttpHeaders", maxHeaderSizeED); 501600af5f1SAppaRao Puli return; 502600af5f1SAppaRao Puli } 50378d4ec4fSEd Tanous subValue->httpHeaders.set(item.first, *value); 504601c71aeSEd Tanous } 505601c71aeSEd Tanous } 506e5aaf047SAppaRao Puli } 507e5aaf047SAppaRao Puli 508e5aaf047SAppaRao Puli if (regPrefixes) 509e5aaf047SAppaRao Puli { 510e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes) 511e5aaf047SAppaRao Puli { 5123544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) == 5133544d2a7SEd Tanous supportedRegPrefixes.end()) 514e5aaf047SAppaRao Puli { 515fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it, 516fffb8c1fSEd Tanous "RegistryPrefixes"); 517e5aaf047SAppaRao Puli return; 518e5aaf047SAppaRao Puli } 519e5aaf047SAppaRao Puli } 520b52664e2SAppaRao Puli subValue->registryPrefixes = *regPrefixes; 521e5aaf047SAppaRao Puli } 522e5aaf047SAppaRao Puli 523e56f254cSSunitha Harish if (resTypes) 524e56f254cSSunitha Harish { 525e56f254cSSunitha Harish for (const std::string& it : *resTypes) 526e56f254cSSunitha Harish { 5273544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) == 5283544d2a7SEd Tanous supportedResourceTypes.end()) 529e56f254cSSunitha Harish { 530e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it, 531e56f254cSSunitha Harish "ResourceTypes"); 532e56f254cSSunitha Harish return; 533e56f254cSSunitha Harish } 534e56f254cSSunitha Harish } 535e56f254cSSunitha Harish subValue->resourceTypes = *resTypes; 536e56f254cSSunitha Harish } 537e56f254cSSunitha Harish 538e5aaf047SAppaRao Puli if (msgIds) 539e5aaf047SAppaRao Puli { 540b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix; 541b304bd79SP Dheeraj Srujan Kumar 5427e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all 5437e860f15SJohn Edward Broadbent // supported prefixes 544b304bd79SP Dheeraj Srujan Kumar if (subValue->registryPrefixes.empty()) 545b304bd79SP Dheeraj Srujan Kumar { 546b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(), 547b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end()); 548b304bd79SP Dheeraj Srujan Kumar } 549b304bd79SP Dheeraj Srujan Kumar else 550b304bd79SP Dheeraj Srujan Kumar { 551b304bd79SP Dheeraj Srujan Kumar registryPrefix = subValue->registryPrefixes; 552b304bd79SP Dheeraj Srujan Kumar } 553b304bd79SP Dheeraj Srujan Kumar 554b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds) 555b304bd79SP Dheeraj Srujan Kumar { 556b304bd79SP Dheeraj Srujan Kumar bool validId = false; 557b304bd79SP Dheeraj Srujan Kumar 558b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry 559b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix) 560b304bd79SP Dheeraj Srujan Kumar { 561fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry> 562fffb8c1fSEd Tanous registry = 563fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it); 564b304bd79SP Dheeraj Srujan Kumar 5653544d2a7SEd Tanous if (std::ranges::any_of( 5663544d2a7SEd Tanous registry, 567fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry& 568fffb8c1fSEd Tanous messageEntry) { 56955f79e6fSEd Tanous return id == messageEntry.first; 570b304bd79SP Dheeraj Srujan Kumar })) 571b304bd79SP Dheeraj Srujan Kumar { 572b304bd79SP Dheeraj Srujan Kumar validId = true; 573b304bd79SP Dheeraj Srujan Kumar break; 574b304bd79SP Dheeraj Srujan Kumar } 575b304bd79SP Dheeraj Srujan Kumar } 576b304bd79SP Dheeraj Srujan Kumar 577b304bd79SP Dheeraj Srujan Kumar if (!validId) 578b304bd79SP Dheeraj Srujan Kumar { 579b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id, 580b304bd79SP Dheeraj Srujan Kumar "MessageIds"); 581b304bd79SP Dheeraj Srujan Kumar return; 582b304bd79SP Dheeraj Srujan Kumar } 583b304bd79SP Dheeraj Srujan Kumar } 584b304bd79SP Dheeraj Srujan Kumar 585b52664e2SAppaRao Puli subValue->registryMsgIds = *msgIds; 586e5aaf047SAppaRao Puli } 587e5aaf047SAppaRao Puli 588e5aaf047SAppaRao Puli if (retryPolicy) 589e5aaf047SAppaRao Puli { 5903544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 5913544d2a7SEd Tanous supportedRetryPolicies.end()) 592e5aaf047SAppaRao Puli { 593002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 594002d39b4SEd Tanous "DeliveryRetryPolicy"); 595e5aaf047SAppaRao Puli return; 596e5aaf047SAppaRao Puli } 597b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 598e5aaf047SAppaRao Puli } 599e5aaf047SAppaRao Puli else 600e5aaf047SAppaRao Puli { 601e5aaf047SAppaRao Puli // Default "TerminateAfterRetries" 602b52664e2SAppaRao Puli subValue->retryPolicy = "TerminateAfterRetries"; 603e5aaf047SAppaRao Puli } 604e5aaf047SAppaRao Puli 605144b6318SAppaRao Puli if (mrdJsonArray) 606156d6b00SAppaRao Puli { 60778d4ec4fSEd Tanous for (nlohmann::json::object_t& mrdObj : *mrdJsonArray) 608144b6318SAppaRao Puli { 609144b6318SAppaRao Puli std::string mrdUri; 610ea2e6eecSWilly Tu 61178d4ec4fSEd Tanous if (!json_util::readJsonObject(mrdObj, asyncResp->res, 61278d4ec4fSEd Tanous "@odata.id", mrdUri)) 613ea2e6eecSWilly Tu 614144b6318SAppaRao Puli { 615144b6318SAppaRao Puli return; 616144b6318SAppaRao Puli } 617ea2e6eecSWilly Tu subValue->metricReportDefinitions.emplace_back(mrdUri); 618144b6318SAppaRao Puli } 619156d6b00SAppaRao Puli } 620156d6b00SAppaRao Puli 621b52664e2SAppaRao Puli std::string id = 622*f80a87f2SEd Tanous EventServiceManager::getInstance().addPushSubscription(subValue); 623b52664e2SAppaRao Puli if (id.empty()) 624e5aaf047SAppaRao Puli { 625e5aaf047SAppaRao Puli messages::internalError(asyncResp->res); 626e5aaf047SAppaRao Puli return; 627e5aaf047SAppaRao Puli } 628e5aaf047SAppaRao Puli 629e5aaf047SAppaRao Puli messages::created(asyncResp->res); 630e5aaf047SAppaRao Puli asyncResp->res.addHeader( 631e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id); 6327e860f15SJohn Edward Broadbent }); 633e5aaf047SAppaRao Puli } 634e5aaf047SAppaRao Puli 6357e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app) 636e5aaf047SAppaRao Puli { 6379d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 638ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination) 6397e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 64045ca1b86SEd Tanous [&app](const crow::Request& req, 6417e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6427e860f15SJohn Edward Broadbent const std::string& param) { 6433ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 64445ca1b86SEd Tanous { 64545ca1b86SEd Tanous return; 64645ca1b86SEd Tanous } 6473d30708fSChicago Duan 6483d30708fSChicago Duan if (param.starts_with("snmp")) 6493d30708fSChicago Duan { 6503d30708fSChicago Duan getSnmpTrapClient(asyncResp, param); 6513d30708fSChicago Duan return; 6523d30708fSChicago Duan } 6533d30708fSChicago Duan 654b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6557e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 656b52664e2SAppaRao Puli if (subValue == nullptr) 657e5aaf047SAppaRao Puli { 658002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 659e5aaf047SAppaRao Puli return; 660e5aaf047SAppaRao Puli } 6617e860f15SJohn Edward Broadbent const std::string& id = param; 662e5aaf047SAppaRao Puli 6631476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 6643d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination"; 6651476687dSEd Tanous asyncResp->res.jsonValue["Protocol"] = "Redfish"; 6663b32780dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 6673b32780dSEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id); 668e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Id"] = id; 669e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Name"] = "Event Destination " + id; 670002d39b4SEd Tanous asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl; 671b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText; 672e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] = 673b52664e2SAppaRao Puli subValue->subscriptionType; 674002d39b4SEd Tanous asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array(); 675002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType; 676e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] = 677b52664e2SAppaRao Puli subValue->registryPrefixes; 678002d39b4SEd Tanous asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes; 679e56f254cSSunitha Harish 680002d39b4SEd Tanous asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds; 681002d39b4SEd Tanous asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy; 68219bb362bSEd Tanous asyncResp->res.jsonValue["VerifyCertificate"] = 68319bb362bSEd Tanous subValue->verifyCertificate; 684144b6318SAppaRao Puli 6851476687dSEd Tanous nlohmann::json::array_t mrdJsonArray; 686144b6318SAppaRao Puli for (const auto& mdrUri : subValue->metricReportDefinitions) 687144b6318SAppaRao Puli { 6881476687dSEd Tanous nlohmann::json::object_t mdr; 6891476687dSEd Tanous mdr["@odata.id"] = mdrUri; 6901476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr)); 691144b6318SAppaRao Puli } 692002d39b4SEd Tanous asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray; 6937e860f15SJohn Edward Broadbent }); 6949d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 695ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 696ed398213SEd Tanous // ConfigureSelf 6977eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 698ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination) 699432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7007e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 70145ca1b86SEd Tanous [&app](const crow::Request& req, 7027e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7037e860f15SJohn Edward Broadbent const std::string& param) { 7043ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 70545ca1b86SEd Tanous { 70645ca1b86SEd Tanous return; 70745ca1b86SEd Tanous } 708b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 7097e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 710b52664e2SAppaRao Puli if (subValue == nullptr) 711e5aaf047SAppaRao Puli { 712002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 713e5aaf047SAppaRao Puli return; 714e5aaf047SAppaRao Puli } 715e5aaf047SAppaRao Puli 716e5aaf047SAppaRao Puli std::optional<std::string> context; 717e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 71819bb362bSEd Tanous std::optional<bool> verifyCertificate; 71978d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 720e5aaf047SAppaRao Puli 721002d39b4SEd Tanous if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context, 72219bb362bSEd Tanous "VerifyCertificate", verifyCertificate, 723002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, 724002d39b4SEd Tanous "HttpHeaders", headers)) 725e5aaf047SAppaRao Puli { 726e5aaf047SAppaRao Puli return; 727e5aaf047SAppaRao Puli } 728e5aaf047SAppaRao Puli 729e5aaf047SAppaRao Puli if (context) 730e5aaf047SAppaRao Puli { 731b52664e2SAppaRao Puli subValue->customText = *context; 732e5aaf047SAppaRao Puli } 733e5aaf047SAppaRao Puli 734e5aaf047SAppaRao Puli if (headers) 735e5aaf047SAppaRao Puli { 736601c71aeSEd Tanous boost::beast::http::fields fields; 73778d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 738601c71aeSEd Tanous { 73978d4ec4fSEd Tanous for (const auto& it : headerChunk) 740601c71aeSEd Tanous { 741601c71aeSEd Tanous const std::string* value = 74278d4ec4fSEd Tanous it.second.get_ptr<const std::string*>(); 743601c71aeSEd Tanous if (value == nullptr) 744601c71aeSEd Tanous { 745601c71aeSEd Tanous messages::propertyValueFormatError( 74678d4ec4fSEd Tanous asyncResp->res, it.second, 74778d4ec4fSEd Tanous "HttpHeaders/" + it.first); 748601c71aeSEd Tanous return; 749601c71aeSEd Tanous } 75078d4ec4fSEd Tanous fields.set(it.first, *value); 751601c71aeSEd Tanous } 752601c71aeSEd Tanous } 75378d4ec4fSEd Tanous subValue->httpHeaders = std::move(fields); 754e5aaf047SAppaRao Puli } 755e5aaf047SAppaRao Puli 756e5aaf047SAppaRao Puli if (retryPolicy) 757e5aaf047SAppaRao Puli { 7583544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 7593544d2a7SEd Tanous supportedRetryPolicies.end()) 760e5aaf047SAppaRao Puli { 761002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 762e5aaf047SAppaRao Puli "DeliveryRetryPolicy"); 763e5aaf047SAppaRao Puli return; 764e5aaf047SAppaRao Puli } 765b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 766e5aaf047SAppaRao Puli } 767e5aaf047SAppaRao Puli 76819bb362bSEd Tanous if (verifyCertificate) 76919bb362bSEd Tanous { 77019bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 77119bb362bSEd Tanous } 77219bb362bSEd Tanous 773b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData(); 7747e860f15SJohn Edward Broadbent }); 7759d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 776ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 777ed398213SEd Tanous // ConfigureSelf 7787eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 779ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination) 780432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7817e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 78245ca1b86SEd Tanous [&app](const crow::Request& req, 7837e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7847e860f15SJohn Edward Broadbent const std::string& param) { 7853ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 78645ca1b86SEd Tanous { 78745ca1b86SEd Tanous return; 78845ca1b86SEd Tanous } 7893d30708fSChicago Duan 7903d30708fSChicago Duan if (param.starts_with("snmp")) 7913d30708fSChicago Duan { 7923d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param); 7933d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(param); 7943d30708fSChicago Duan return; 7953d30708fSChicago Duan } 7963d30708fSChicago Duan 797002d39b4SEd Tanous if (!EventServiceManager::getInstance().isSubscriptionExist(param)) 798e5aaf047SAppaRao Puli { 799002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 800e5aaf047SAppaRao Puli return; 801e5aaf047SAppaRao Puli } 8027e860f15SJohn Edward Broadbent EventServiceManager::getInstance().deleteSubscription(param); 8037e860f15SJohn Edward Broadbent }); 804e5aaf047SAppaRao Puli } 805e5aaf047SAppaRao Puli 806e5aaf047SAppaRao Puli } // namespace redfish 807