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; 281*19bb362bSEd 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", 298*19bb362bSEd Tanous mrdJsonArray, "ResourceTypes", resTypes, "VerifyCertificate", 299*19bb362bSEd 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 438*19bb362bSEd Tanous if (verifyCertificate) 439*19bb362bSEd Tanous { 440*19bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 441*19bb362bSEd Tanous } 442*19bb362bSEd 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 = 622fffb8c1fSEd Tanous EventServiceManager::getInstance().addSubscription(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; 682*19bb362bSEd Tanous asyncResp->res.jsonValue["VerifyCertificate"] = 683*19bb362bSEd 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; 718*19bb362bSEd 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, 722*19bb362bSEd 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 768*19bb362bSEd Tanous if (verifyCertificate) 769*19bb362bSEd Tanous { 770*19bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 771*19bb362bSEd Tanous } 772*19bb362bSEd 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