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" 19539d8c6bSEd Tanous #include "generated/enums/event_service.hpp" 203ccb3adbSEd Tanous #include "http/utility.hpp" 213ccb3adbSEd Tanous #include "logging.hpp" 223ccb3adbSEd Tanous #include "query.hpp" 233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 243d30708fSChicago Duan #include "snmp_trap_event_clients.hpp" 25e5aaf047SAppaRao Puli 26601c71aeSEd Tanous #include <boost/beast/http/fields.hpp> 273d30708fSChicago Duan #include <boost/system/error_code.hpp> 28a716aa74SEd Tanous #include <boost/url/parse.hpp> 293d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp> 303d30708fSChicago Duan #include <utils/dbus_utils.hpp> 31ed398213SEd Tanous 323d30708fSChicago Duan #include <charconv> 333d30708fSChicago Duan #include <memory> 343544d2a7SEd Tanous #include <ranges> 351e270c5fSPatrick Williams #include <span> 363d30708fSChicago Duan #include <string> 371e270c5fSPatrick Williams 38e5aaf047SAppaRao Puli namespace redfish 39e5aaf047SAppaRao Puli { 40e5aaf047SAppaRao Puli 41156d6b00SAppaRao Puli static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = { 42156d6b00SAppaRao Puli eventFormatType, metricReportFormatType}; 43e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRegPrefixes = { 44b304bd79SP Dheeraj Srujan Kumar "Base", "OpenBMC", "TaskEvent"}; 45e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRetryPolicies = { 46e5aaf047SAppaRao Puli "TerminateAfterRetries", "SuspendRetries", "RetryForever"}; 47e5aaf047SAppaRao Puli 48e56f254cSSunitha Harish static constexpr const std::array<const char*, 1> supportedResourceTypes = { 49e56f254cSSunitha Harish "Task"}; 50e56f254cSSunitha Harish 517e860f15SJohn Edward Broadbent inline void requestRoutesEventService(App& app) 52e5aaf047SAppaRao Puli { 537e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 54ed398213SEd Tanous .privileges(redfish::privileges::getEventService) 55*bd79bce8SPatrick Williams .methods( 56*bd79bce8SPatrick Williams boost::beast::http::verb:: 57*bd79bce8SPatrick Williams get)([&app]( 58*bd79bce8SPatrick Williams const crow::Request& req, 59002d39b4SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 603ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 6145ca1b86SEd Tanous { 6245ca1b86SEd Tanous return; 6345ca1b86SEd Tanous } 641476687dSEd Tanous 651476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService"; 661476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 671476687dSEd Tanous "#EventService.v1_5_0.EventService"; 681476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "EventService"; 691476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Event Service"; 705e44e3d8SAppaRao Puli asyncResp->res.jsonValue["ServerSentEventUri"] = 715e44e3d8SAppaRao Puli "/redfish/v1/EventService/SSE"; 725e44e3d8SAppaRao Puli 731476687dSEd Tanous asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] = 741476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 75*bd79bce8SPatrick Williams asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"] 76*bd79bce8SPatrick Williams ["target"] = 771476687dSEd Tanous "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"; 78e5aaf047SAppaRao Puli 7928afb49cSJunLin Chen const persistent_data::EventServiceConfig eventServiceConfig = 8028afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 8128afb49cSJunLin Chen .getEventServiceConfig(); 827d1cc387SAppaRao Puli 837d1cc387SAppaRao Puli asyncResp->res.jsonValue["Status"]["State"] = 8428afb49cSJunLin Chen (eventServiceConfig.enabled ? "Enabled" : "Disabled"); 85*bd79bce8SPatrick Williams asyncResp->res.jsonValue["ServiceEnabled"] = 86*bd79bce8SPatrick Williams eventServiceConfig.enabled; 877e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] = 8828afb49cSJunLin Chen eventServiceConfig.retryAttempts; 89e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] = 9028afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval; 91*bd79bce8SPatrick Williams asyncResp->res.jsonValue["EventFormatTypes"] = 92*bd79bce8SPatrick Williams supportedEvtFormatTypes; 930fda0f12SGeorge Liu asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes; 940fda0f12SGeorge Liu asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes; 9507941a88SAyushi Smriti 96613dabeaSEd Tanous nlohmann::json::object_t supportedSSEFilters; 97613dabeaSEd Tanous supportedSSEFilters["EventFormatType"] = true; 98613dabeaSEd Tanous supportedSSEFilters["MessageId"] = true; 99613dabeaSEd Tanous supportedSSEFilters["MetricReportDefinition"] = true; 100613dabeaSEd Tanous supportedSSEFilters["RegistryPrefix"] = true; 101613dabeaSEd Tanous supportedSSEFilters["OriginResource"] = false; 102613dabeaSEd Tanous supportedSSEFilters["ResourceType"] = false; 10307941a88SAyushi Smriti 10407941a88SAyushi Smriti asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] = 105613dabeaSEd Tanous std::move(supportedSSEFilters); 1067e860f15SJohn Edward Broadbent }); 107e5aaf047SAppaRao Puli 1087e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 109ed398213SEd Tanous .privileges(redfish::privileges::patchEventService) 1107e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 11145ca1b86SEd Tanous [&app](const crow::Request& req, 11245ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1133ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 114e5aaf047SAppaRao Puli { 11545ca1b86SEd Tanous return; 11645ca1b86SEd Tanous } 117e5aaf047SAppaRao Puli std::optional<bool> serviceEnabled; 118e5aaf047SAppaRao Puli std::optional<uint32_t> retryAttemps; 119e5aaf047SAppaRao Puli std::optional<uint32_t> retryInterval; 120e5aaf047SAppaRao Puli 12115ed6780SWilly Tu if (!json_util::readJsonPatch( 1227e860f15SJohn Edward Broadbent req, asyncResp->res, "ServiceEnabled", serviceEnabled, 1237e860f15SJohn Edward Broadbent "DeliveryRetryAttempts", retryAttemps, 1247e860f15SJohn Edward Broadbent "DeliveryRetryIntervalSeconds", retryInterval)) 125e5aaf047SAppaRao Puli { 126e5aaf047SAppaRao Puli return; 127e5aaf047SAppaRao Puli } 128e5aaf047SAppaRao Puli 12928afb49cSJunLin Chen persistent_data::EventServiceConfig eventServiceConfig = 13028afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 13128afb49cSJunLin Chen .getEventServiceConfig(); 1327d1cc387SAppaRao Puli 133e5aaf047SAppaRao Puli if (serviceEnabled) 134e5aaf047SAppaRao Puli { 13528afb49cSJunLin Chen eventServiceConfig.enabled = *serviceEnabled; 136e5aaf047SAppaRao Puli } 137e5aaf047SAppaRao Puli 138e5aaf047SAppaRao Puli if (retryAttemps) 139e5aaf047SAppaRao Puli { 140e5aaf047SAppaRao Puli // Supported range [1-3] 141e5aaf047SAppaRao Puli if ((*retryAttemps < 1) || (*retryAttemps > 3)) 142e5aaf047SAppaRao Puli { 143e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 144e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryAttemps), 145e5aaf047SAppaRao Puli "DeliveryRetryAttempts", "[1-3]"); 146e5aaf047SAppaRao Puli } 147e5aaf047SAppaRao Puli else 148e5aaf047SAppaRao Puli { 14928afb49cSJunLin Chen eventServiceConfig.retryAttempts = *retryAttemps; 150e5aaf047SAppaRao Puli } 151e5aaf047SAppaRao Puli } 152e5aaf047SAppaRao Puli 153e5aaf047SAppaRao Puli if (retryInterval) 154e5aaf047SAppaRao Puli { 15533a32b34SGunnar Mills // Supported range [5 - 180] 15633a32b34SGunnar Mills if ((*retryInterval < 5) || (*retryInterval > 180)) 157e5aaf047SAppaRao Puli { 158e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 159e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryInterval), 16033a32b34SGunnar Mills "DeliveryRetryIntervalSeconds", "[5-180]"); 161e5aaf047SAppaRao Puli } 162e5aaf047SAppaRao Puli else 163e5aaf047SAppaRao Puli { 164*bd79bce8SPatrick Williams eventServiceConfig.retryTimeoutInterval = 165*bd79bce8SPatrick Williams *retryInterval; 166e5aaf047SAppaRao Puli } 167e5aaf047SAppaRao Puli } 168e5aaf047SAppaRao Puli 1697d1cc387SAppaRao Puli EventServiceManager::getInstance().setEventServiceConfig( 17028afb49cSJunLin Chen eventServiceConfig); 1717e860f15SJohn Edward Broadbent }); 1720b4bdd93SAppaRao Puli } 1730b4bdd93SAppaRao Puli 1747e860f15SJohn Edward Broadbent inline void requestRoutesSubmitTestEvent(App& app) 1750b4bdd93SAppaRao Puli { 1767e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 1777e860f15SJohn Edward Broadbent app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/") 178ed398213SEd Tanous .privileges(redfish::privileges::postEventService) 1797e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 18045ca1b86SEd Tanous [&app](const crow::Request& req, 1817e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1823ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 18345ca1b86SEd Tanous { 18445ca1b86SEd Tanous return; 18545ca1b86SEd Tanous } 1866ba8c82eSsunharis_in if (!EventServiceManager::getInstance().sendTestEventLog()) 1876ba8c82eSsunharis_in { 1886ba8c82eSsunharis_in messages::serviceDisabled(asyncResp->res, 1896ba8c82eSsunharis_in "/redfish/v1/EventService/"); 1906ba8c82eSsunharis_in return; 1916ba8c82eSsunharis_in } 1928d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 1937e860f15SJohn Edward Broadbent }); 194e5aaf047SAppaRao Puli } 195e5aaf047SAppaRao Puli 1963d30708fSChicago Duan inline void doSubscriptionCollection( 197e81de512SEd Tanous const boost::system::error_code& ec, 1983d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1993d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) 2003d30708fSChicago Duan { 2013d30708fSChicago Duan if (ec) 2023d30708fSChicago Duan { 2031306101eSEd Tanous if (ec.value() == EBADR || ec.value() == EHOSTUNREACH) 2043d30708fSChicago Duan { 2053d30708fSChicago Duan // This is an optional process so just return if it isn't there 2063d30708fSChicago Duan return; 2073d30708fSChicago Duan } 2083d30708fSChicago Duan 20962598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec); 2103d30708fSChicago Duan messages::internalError(asyncResp->res); 2113d30708fSChicago Duan return; 2123d30708fSChicago Duan } 2133d30708fSChicago Duan nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 2143d30708fSChicago Duan for (const auto& objpath : resp) 2153d30708fSChicago Duan { 2163d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first); 2173d30708fSChicago Duan const std::string snmpId = path.filename(); 2183d30708fSChicago Duan if (snmpId.empty()) 2193d30708fSChicago Duan { 22062598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong"); 2213d30708fSChicago Duan messages::internalError(asyncResp->res); 2223d30708fSChicago Duan return; 2233d30708fSChicago Duan } 2243d30708fSChicago Duan 2253d30708fSChicago Duan getSnmpSubscriptionList(asyncResp, snmpId, memberArray); 2263d30708fSChicago Duan } 2273d30708fSChicago Duan } 2283d30708fSChicago Duan 2297e860f15SJohn Edward Broadbent inline void requestRoutesEventDestinationCollection(App& app) 230e5aaf047SAppaRao Puli { 2311ebe3e41SGayathri Leburu BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 232ed398213SEd Tanous .privileges(redfish::privileges::getEventDestinationCollection) 2337e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 23445ca1b86SEd Tanous [&app](const crow::Request& req, 2357e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2363ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 23745ca1b86SEd Tanous { 23845ca1b86SEd Tanous return; 23945ca1b86SEd Tanous } 2401476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2411476687dSEd Tanous "#EventDestinationCollection.EventDestinationCollection"; 2421476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2431476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 244*bd79bce8SPatrick Williams asyncResp->res.jsonValue["Name"] = 245*bd79bce8SPatrick Williams "Event Destination Collections"; 246e5aaf047SAppaRao Puli 247*bd79bce8SPatrick Williams nlohmann::json& memberArray = 248*bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members"]; 249e5aaf047SAppaRao Puli 250b52664e2SAppaRao Puli std::vector<std::string> subscripIds = 251b52664e2SAppaRao Puli EventServiceManager::getInstance().getAllIDs(); 252b52664e2SAppaRao Puli memberArray = nlohmann::json::array(); 253*bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members@odata.count"] = 254*bd79bce8SPatrick Williams subscripIds.size(); 255b52664e2SAppaRao Puli 256b52664e2SAppaRao Puli for (const std::string& id : subscripIds) 257e5aaf047SAppaRao Puli { 2581476687dSEd Tanous nlohmann::json::object_t member; 2593d30708fSChicago Duan member["@odata.id"] = boost::urls::format( 2603d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}" + id); 261b2ba3072SPatrick Williams memberArray.emplace_back(std::move(member)); 262e5aaf047SAppaRao Puli } 2633d30708fSChicago Duan crow::connections::systemBus->async_method_call( 264e81de512SEd Tanous [asyncResp](const boost::system::error_code& ec, 2653d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) { 2663d30708fSChicago Duan doSubscriptionCollection(ec, asyncResp, resp); 2673d30708fSChicago Duan }, 2683d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 2693d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 2703d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 2717e860f15SJohn Edward Broadbent }); 2723d30708fSChicago Duan 2737e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 2747eeafa76SAbhishek Patel .privileges(redfish::privileges::postEventDestinationCollection) 275*bd79bce8SPatrick Williams .methods( 276*bd79bce8SPatrick Williams boost::beast::http::verb:: 277*bd79bce8SPatrick Williams post)([&app]( 278*bd79bce8SPatrick Williams const crow::Request& req, 2797e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2803ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 28145ca1b86SEd Tanous { 28245ca1b86SEd Tanous return; 28345ca1b86SEd Tanous } 284fffb8c1fSEd Tanous if (EventServiceManager::getInstance().getNumberOfSubscriptions() >= 285fffb8c1fSEd Tanous maxNoOfSubscriptions) 286e5aaf047SAppaRao Puli { 287e5aaf047SAppaRao Puli messages::eventSubscriptionLimitExceeded(asyncResp->res); 288e5aaf047SAppaRao Puli return; 289e5aaf047SAppaRao Puli } 290e5aaf047SAppaRao Puli std::string destUrl; 291e5aaf047SAppaRao Puli std::string protocol; 29219bb362bSEd Tanous std::optional<bool> verifyCertificate; 293e5aaf047SAppaRao Puli std::optional<std::string> context; 294e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType; 29523a21a1cSEd Tanous std::optional<std::string> eventFormatType2; 296e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 297e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds; 298e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes; 299e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes; 30078d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 30178d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray; 302e5aaf047SAppaRao Puli 30315ed6780SWilly Tu if (!json_util::readJsonPatch( 304*bd79bce8SPatrick Williams req, asyncResp->res, "Destination", destUrl, "Context", 305*bd79bce8SPatrick Williams context, "Protocol", protocol, "SubscriptionType", 306*bd79bce8SPatrick Williams subscriptionType, "EventFormatType", eventFormatType2, 307*bd79bce8SPatrick Williams "HttpHeaders", headers, "RegistryPrefixes", regPrefixes, 308*bd79bce8SPatrick Williams "MessageIds", msgIds, "DeliveryRetryPolicy", retryPolicy, 309*bd79bce8SPatrick Williams "MetricReportDefinitions", mrdJsonArray, "ResourceTypes", 310*bd79bce8SPatrick Williams resTypes, "VerifyCertificate", verifyCertificate)) 311e5aaf047SAppaRao Puli { 312e5aaf047SAppaRao Puli return; 313e5aaf047SAppaRao Puli } 314e5aaf047SAppaRao Puli 315600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers 316600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000; 317600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize) 318600af5f1SAppaRao Puli { 319600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination", 320600af5f1SAppaRao Puli maxDestinationSize); 321600af5f1SAppaRao Puli return; 322600af5f1SAppaRao Puli } 323600af5f1SAppaRao Puli 324dd28ba82SAppaRao Puli if (regPrefixes && msgIds) 325dd28ba82SAppaRao Puli { 32626f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty()) 327dd28ba82SAppaRao Puli { 328*bd79bce8SPatrick Williams messages::propertyValueConflict( 329*bd79bce8SPatrick Williams asyncResp->res, "MessageIds", "RegistryPrefixes"); 330dd28ba82SAppaRao Puli return; 331dd28ba82SAppaRao Puli } 332dd28ba82SAppaRao Puli } 333dd28ba82SAppaRao Puli 3346fd29553SEd Tanous boost::system::result<boost::urls::url> url = 335a716aa74SEd Tanous boost::urls::parse_absolute_uri(destUrl); 336a716aa74SEd Tanous if (!url) 337e5aaf047SAppaRao Puli { 338*bd79bce8SPatrick Williams BMCWEB_LOG_WARNING( 339*bd79bce8SPatrick Williams "Failed to validate and split destination url"); 340e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl, 341e5aaf047SAppaRao Puli "Destination"); 342e5aaf047SAppaRao Puli return; 343e5aaf047SAppaRao Puli } 344a716aa74SEd Tanous url->normalize(); 345a716aa74SEd Tanous crow::utility::setProtocolDefaults(*url, protocol); 346a716aa74SEd Tanous crow::utility::setPortDefaults(*url); 347a716aa74SEd Tanous 348a716aa74SEd Tanous if (url->path().empty()) 349a716aa74SEd Tanous { 350a716aa74SEd Tanous url->set_path("/"); 351a716aa74SEd Tanous } 352a716aa74SEd Tanous 353a716aa74SEd Tanous if (url->has_userinfo()) 354a716aa74SEd Tanous { 355a716aa74SEd Tanous messages::propertyValueFormatError(asyncResp->res, destUrl, 356a716aa74SEd Tanous "Destination"); 357a716aa74SEd Tanous return; 358a716aa74SEd Tanous } 359b52664e2SAppaRao Puli 3603d30708fSChicago Duan if (protocol == "SNMPv2c") 3613d30708fSChicago Duan { 3623d30708fSChicago Duan if (context) 3633d30708fSChicago Duan { 3643d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context", 3653d30708fSChicago Duan "Protocol"); 3663d30708fSChicago Duan return; 3673d30708fSChicago Duan } 3683d30708fSChicago Duan if (eventFormatType2) 3693d30708fSChicago Duan { 370*bd79bce8SPatrick Williams messages::propertyValueConflict( 371*bd79bce8SPatrick Williams asyncResp->res, "EventFormatType", "Protocol"); 3723d30708fSChicago Duan return; 3733d30708fSChicago Duan } 3743d30708fSChicago Duan if (retryPolicy) 3753d30708fSChicago Duan { 376*bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 377*bd79bce8SPatrick Williams "RetryPolicy", "Protocol"); 3783d30708fSChicago Duan return; 3793d30708fSChicago Duan } 3803d30708fSChicago Duan if (msgIds) 3813d30708fSChicago Duan { 382*bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 383*bd79bce8SPatrick Williams "MessageIds", "Protocol"); 3843d30708fSChicago Duan return; 3853d30708fSChicago Duan } 3863d30708fSChicago Duan if (regPrefixes) 3873d30708fSChicago Duan { 388*bd79bce8SPatrick Williams messages::propertyValueConflict( 389*bd79bce8SPatrick Williams asyncResp->res, "RegistryPrefixes", "Protocol"); 3903d30708fSChicago Duan return; 3913d30708fSChicago Duan } 3923d30708fSChicago Duan if (resTypes) 3933d30708fSChicago Duan { 394*bd79bce8SPatrick Williams messages::propertyValueConflict( 395*bd79bce8SPatrick Williams asyncResp->res, "ResourceTypes", "Protocol"); 3963d30708fSChicago Duan return; 3973d30708fSChicago Duan } 3983d30708fSChicago Duan if (headers) 3993d30708fSChicago Duan { 400*bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 401*bd79bce8SPatrick Williams "HttpHeaders", "Protocol"); 4023d30708fSChicago Duan return; 4033d30708fSChicago Duan } 4043d30708fSChicago Duan if (mrdJsonArray) 4053d30708fSChicago Duan { 4063d30708fSChicago Duan messages::propertyValueConflict( 4073d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol"); 4083d30708fSChicago Duan return; 4093d30708fSChicago Duan } 410a716aa74SEd Tanous if (url->scheme() != "snmp") 411a716aa74SEd Tanous { 412*bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 413*bd79bce8SPatrick Williams "Destination", "Protocol"); 4143d30708fSChicago Duan return; 4153d30708fSChicago Duan } 4163d30708fSChicago Duan 417a716aa74SEd Tanous addSnmpTrapClient(asyncResp, url->host_address(), 418a716aa74SEd Tanous url->port_number()); 419a716aa74SEd Tanous return; 420b52664e2SAppaRao Puli } 4213d30708fSChicago Duan 422a716aa74SEd Tanous std::shared_ptr<Subscription> subValue = 423a716aa74SEd Tanous std::make_shared<Subscription>(*url, app.ioContext()); 424b52664e2SAppaRao Puli 425a716aa74SEd Tanous subValue->destinationUrl = std::move(*url); 426e5aaf047SAppaRao Puli 427e5aaf047SAppaRao Puli if (subscriptionType) 428e5aaf047SAppaRao Puli { 429e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent") 430e5aaf047SAppaRao Puli { 431fffb8c1fSEd Tanous messages::propertyValueNotInList( 432fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType"); 433e5aaf047SAppaRao Puli return; 434e5aaf047SAppaRao Puli } 435b52664e2SAppaRao Puli subValue->subscriptionType = *subscriptionType; 436e5aaf047SAppaRao Puli } 437e5aaf047SAppaRao Puli else 438e5aaf047SAppaRao Puli { 439b52664e2SAppaRao Puli subValue->subscriptionType = "RedfishEvent"; // Default 440e5aaf047SAppaRao Puli } 441e5aaf047SAppaRao Puli 442e5aaf047SAppaRao Puli if (protocol != "Redfish") 443e5aaf047SAppaRao Puli { 444e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol, 445e5aaf047SAppaRao Puli "Protocol"); 446e5aaf047SAppaRao Puli return; 447e5aaf047SAppaRao Puli } 448b52664e2SAppaRao Puli subValue->protocol = protocol; 449e5aaf047SAppaRao Puli 45019bb362bSEd Tanous if (verifyCertificate) 45119bb362bSEd Tanous { 45219bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 45319bb362bSEd Tanous } 45419bb362bSEd Tanous 45523a21a1cSEd Tanous if (eventFormatType2) 456e5aaf047SAppaRao Puli { 457*bd79bce8SPatrick Williams if (std::ranges::find(supportedEvtFormatTypes, 458*bd79bce8SPatrick Williams *eventFormatType2) == 4593544d2a7SEd Tanous supportedEvtFormatTypes.end()) 460e5aaf047SAppaRao Puli { 461fffb8c1fSEd Tanous messages::propertyValueNotInList( 462fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType"); 463e5aaf047SAppaRao Puli return; 464e5aaf047SAppaRao Puli } 46523a21a1cSEd Tanous subValue->eventFormatType = *eventFormatType2; 466e5aaf047SAppaRao Puli } 467e5aaf047SAppaRao Puli else 468e5aaf047SAppaRao Puli { 469e5aaf047SAppaRao Puli // If not specified, use default "Event" 47023a21a1cSEd Tanous subValue->eventFormatType = "Event"; 471e5aaf047SAppaRao Puli } 472e5aaf047SAppaRao Puli 473e5aaf047SAppaRao Puli if (context) 474e5aaf047SAppaRao Puli { 4758ece0e45SEd Tanous // This value is selected arbitrarily. 476600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256; 477600af5f1SAppaRao Puli if (context->size() > maxContextSize) 478600af5f1SAppaRao Puli { 479600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context", 480600af5f1SAppaRao Puli maxContextSize); 481600af5f1SAppaRao Puli return; 482600af5f1SAppaRao Puli } 483b52664e2SAppaRao Puli subValue->customText = *context; 484e5aaf047SAppaRao Puli } 485e5aaf047SAppaRao Puli 486e5aaf047SAppaRao Puli if (headers) 487e5aaf047SAppaRao Puli { 488600af5f1SAppaRao Puli size_t cumulativeLen = 0; 489600af5f1SAppaRao Puli 49078d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 491601c71aeSEd Tanous { 49278d4ec4fSEd Tanous for (const auto& item : headerChunk) 49378d4ec4fSEd Tanous { 49478d4ec4fSEd Tanous const std::string* value = 49578d4ec4fSEd Tanous item.second.get_ptr<const std::string*>(); 49678d4ec4fSEd Tanous if (value == nullptr) 49778d4ec4fSEd Tanous { 49878d4ec4fSEd Tanous messages::propertyValueFormatError( 49978d4ec4fSEd Tanous asyncResp->res, item.second, 50078d4ec4fSEd Tanous "HttpHeaders/" + item.first); 50178d4ec4fSEd Tanous return; 50278d4ec4fSEd Tanous } 50378d4ec4fSEd Tanous // Adding a new json value is the size of the key, + 50478d4ec4fSEd Tanous // the size of the value + 2 * 2 quotes for each, + 50578d4ec4fSEd Tanous // the colon and space between. example: 50678d4ec4fSEd Tanous // "key": "value" 50778d4ec4fSEd Tanous cumulativeLen += item.first.size() + value->size() + 6; 508600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp 509600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096; 510600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED) 511600af5f1SAppaRao Puli { 51278d4ec4fSEd Tanous messages::arraySizeTooLong( 51378d4ec4fSEd Tanous asyncResp->res, "HttpHeaders", maxHeaderSizeED); 514600af5f1SAppaRao Puli return; 515600af5f1SAppaRao Puli } 51678d4ec4fSEd Tanous subValue->httpHeaders.set(item.first, *value); 517601c71aeSEd Tanous } 518601c71aeSEd Tanous } 519e5aaf047SAppaRao Puli } 520e5aaf047SAppaRao Puli 521e5aaf047SAppaRao Puli if (regPrefixes) 522e5aaf047SAppaRao Puli { 523e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes) 524e5aaf047SAppaRao Puli { 5253544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) == 5263544d2a7SEd Tanous supportedRegPrefixes.end()) 527e5aaf047SAppaRao Puli { 528fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it, 529fffb8c1fSEd Tanous "RegistryPrefixes"); 530e5aaf047SAppaRao Puli return; 531e5aaf047SAppaRao Puli } 532e5aaf047SAppaRao Puli } 533b52664e2SAppaRao Puli subValue->registryPrefixes = *regPrefixes; 534e5aaf047SAppaRao Puli } 535e5aaf047SAppaRao Puli 536e56f254cSSunitha Harish if (resTypes) 537e56f254cSSunitha Harish { 538e56f254cSSunitha Harish for (const std::string& it : *resTypes) 539e56f254cSSunitha Harish { 5403544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) == 5413544d2a7SEd Tanous supportedResourceTypes.end()) 542e56f254cSSunitha Harish { 543e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it, 544e56f254cSSunitha Harish "ResourceTypes"); 545e56f254cSSunitha Harish return; 546e56f254cSSunitha Harish } 547e56f254cSSunitha Harish } 548e56f254cSSunitha Harish subValue->resourceTypes = *resTypes; 549e56f254cSSunitha Harish } 550e56f254cSSunitha Harish 551e5aaf047SAppaRao Puli if (msgIds) 552e5aaf047SAppaRao Puli { 553b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix; 554b304bd79SP Dheeraj Srujan Kumar 5557e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all 5567e860f15SJohn Edward Broadbent // supported prefixes 557b304bd79SP Dheeraj Srujan Kumar if (subValue->registryPrefixes.empty()) 558b304bd79SP Dheeraj Srujan Kumar { 559b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(), 560b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end()); 561b304bd79SP Dheeraj Srujan Kumar } 562b304bd79SP Dheeraj Srujan Kumar else 563b304bd79SP Dheeraj Srujan Kumar { 564b304bd79SP Dheeraj Srujan Kumar registryPrefix = subValue->registryPrefixes; 565b304bd79SP Dheeraj Srujan Kumar } 566b304bd79SP Dheeraj Srujan Kumar 567b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds) 568b304bd79SP Dheeraj Srujan Kumar { 569b304bd79SP Dheeraj Srujan Kumar bool validId = false; 570b304bd79SP Dheeraj Srujan Kumar 571b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry 572b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix) 573b304bd79SP Dheeraj Srujan Kumar { 574fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry> 575fffb8c1fSEd Tanous registry = 576fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it); 577b304bd79SP Dheeraj Srujan Kumar 5783544d2a7SEd Tanous if (std::ranges::any_of( 5793544d2a7SEd Tanous registry, 580fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry& 581fffb8c1fSEd Tanous messageEntry) { 58255f79e6fSEd Tanous return id == messageEntry.first; 583b304bd79SP Dheeraj Srujan Kumar })) 584b304bd79SP Dheeraj Srujan Kumar { 585b304bd79SP Dheeraj Srujan Kumar validId = true; 586b304bd79SP Dheeraj Srujan Kumar break; 587b304bd79SP Dheeraj Srujan Kumar } 588b304bd79SP Dheeraj Srujan Kumar } 589b304bd79SP Dheeraj Srujan Kumar 590b304bd79SP Dheeraj Srujan Kumar if (!validId) 591b304bd79SP Dheeraj Srujan Kumar { 592b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id, 593b304bd79SP Dheeraj Srujan Kumar "MessageIds"); 594b304bd79SP Dheeraj Srujan Kumar return; 595b304bd79SP Dheeraj Srujan Kumar } 596b304bd79SP Dheeraj Srujan Kumar } 597b304bd79SP Dheeraj Srujan Kumar 598b52664e2SAppaRao Puli subValue->registryMsgIds = *msgIds; 599e5aaf047SAppaRao Puli } 600e5aaf047SAppaRao Puli 601e5aaf047SAppaRao Puli if (retryPolicy) 602e5aaf047SAppaRao Puli { 6033544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 6043544d2a7SEd Tanous supportedRetryPolicies.end()) 605e5aaf047SAppaRao Puli { 606*bd79bce8SPatrick Williams messages::propertyValueNotInList( 607*bd79bce8SPatrick Williams asyncResp->res, *retryPolicy, "DeliveryRetryPolicy"); 608e5aaf047SAppaRao Puli return; 609e5aaf047SAppaRao Puli } 610b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 611e5aaf047SAppaRao Puli } 612e5aaf047SAppaRao Puli else 613e5aaf047SAppaRao Puli { 614e5aaf047SAppaRao Puli // Default "TerminateAfterRetries" 615b52664e2SAppaRao Puli subValue->retryPolicy = "TerminateAfterRetries"; 616e5aaf047SAppaRao Puli } 617e5aaf047SAppaRao Puli 618144b6318SAppaRao Puli if (mrdJsonArray) 619156d6b00SAppaRao Puli { 62078d4ec4fSEd Tanous for (nlohmann::json::object_t& mrdObj : *mrdJsonArray) 621144b6318SAppaRao Puli { 622144b6318SAppaRao Puli std::string mrdUri; 623ea2e6eecSWilly Tu 62478d4ec4fSEd Tanous if (!json_util::readJsonObject(mrdObj, asyncResp->res, 62578d4ec4fSEd Tanous "@odata.id", mrdUri)) 626ea2e6eecSWilly Tu 627144b6318SAppaRao Puli { 628144b6318SAppaRao Puli return; 629144b6318SAppaRao Puli } 630ea2e6eecSWilly Tu subValue->metricReportDefinitions.emplace_back(mrdUri); 631144b6318SAppaRao Puli } 632156d6b00SAppaRao Puli } 633156d6b00SAppaRao Puli 634b52664e2SAppaRao Puli std::string id = 635*bd79bce8SPatrick Williams EventServiceManager::getInstance().addPushSubscription( 636*bd79bce8SPatrick Williams subValue); 637b52664e2SAppaRao Puli if (id.empty()) 638e5aaf047SAppaRao Puli { 639e5aaf047SAppaRao Puli messages::internalError(asyncResp->res); 640e5aaf047SAppaRao Puli return; 641e5aaf047SAppaRao Puli } 642e5aaf047SAppaRao Puli 643e5aaf047SAppaRao Puli messages::created(asyncResp->res); 644e5aaf047SAppaRao Puli asyncResp->res.addHeader( 645e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id); 6467e860f15SJohn Edward Broadbent }); 647e5aaf047SAppaRao Puli } 648e5aaf047SAppaRao Puli 6497e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app) 650e5aaf047SAppaRao Puli { 6519d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 652ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination) 6537e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 65445ca1b86SEd Tanous [&app](const crow::Request& req, 6557e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6567e860f15SJohn Edward Broadbent const std::string& param) { 6573ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 65845ca1b86SEd Tanous { 65945ca1b86SEd Tanous return; 66045ca1b86SEd Tanous } 6613d30708fSChicago Duan 6623d30708fSChicago Duan if (param.starts_with("snmp")) 6633d30708fSChicago Duan { 6643d30708fSChicago Duan getSnmpTrapClient(asyncResp, param); 6653d30708fSChicago Duan return; 6663d30708fSChicago Duan } 6673d30708fSChicago Duan 668b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6697e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 670b52664e2SAppaRao Puli if (subValue == nullptr) 671e5aaf047SAppaRao Puli { 672*bd79bce8SPatrick Williams asyncResp->res.result( 673*bd79bce8SPatrick Williams boost::beast::http::status::not_found); 674e5aaf047SAppaRao Puli return; 675e5aaf047SAppaRao Puli } 6767e860f15SJohn Edward Broadbent const std::string& id = param; 677e5aaf047SAppaRao Puli 6781476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 6793d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination"; 680539d8c6bSEd Tanous asyncResp->res.jsonValue["Protocol"] = 681539d8c6bSEd Tanous event_destination::EventDestinationProtocol::Redfish; 6823b32780dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 6833b32780dSEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id); 684e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Id"] = id; 685e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Name"] = "Event Destination " + id; 686*bd79bce8SPatrick Williams asyncResp->res.jsonValue["Destination"] = 687*bd79bce8SPatrick Williams subValue->destinationUrl; 688b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText; 689e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] = 690b52664e2SAppaRao Puli subValue->subscriptionType; 691*bd79bce8SPatrick Williams asyncResp->res.jsonValue["HttpHeaders"] = 692*bd79bce8SPatrick Williams nlohmann::json::array(); 693*bd79bce8SPatrick Williams asyncResp->res.jsonValue["EventFormatType"] = 694*bd79bce8SPatrick Williams subValue->eventFormatType; 695e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] = 696b52664e2SAppaRao Puli subValue->registryPrefixes; 697*bd79bce8SPatrick Williams asyncResp->res.jsonValue["ResourceTypes"] = 698*bd79bce8SPatrick Williams subValue->resourceTypes; 699e56f254cSSunitha Harish 700*bd79bce8SPatrick Williams asyncResp->res.jsonValue["MessageIds"] = 701*bd79bce8SPatrick Williams subValue->registryMsgIds; 702*bd79bce8SPatrick Williams asyncResp->res.jsonValue["DeliveryRetryPolicy"] = 703*bd79bce8SPatrick Williams subValue->retryPolicy; 70419bb362bSEd Tanous asyncResp->res.jsonValue["VerifyCertificate"] = 70519bb362bSEd Tanous subValue->verifyCertificate; 706144b6318SAppaRao Puli 7071476687dSEd Tanous nlohmann::json::array_t mrdJsonArray; 708144b6318SAppaRao Puli for (const auto& mdrUri : subValue->metricReportDefinitions) 709144b6318SAppaRao Puli { 7101476687dSEd Tanous nlohmann::json::object_t mdr; 7111476687dSEd Tanous mdr["@odata.id"] = mdrUri; 7121476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr)); 713144b6318SAppaRao Puli } 714*bd79bce8SPatrick Williams asyncResp->res.jsonValue["MetricReportDefinitions"] = 715*bd79bce8SPatrick Williams mrdJsonArray; 7167e860f15SJohn Edward Broadbent }); 7179d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 718ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 719ed398213SEd Tanous // ConfigureSelf 7207eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 721ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination) 722432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7237e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 72445ca1b86SEd Tanous [&app](const crow::Request& req, 7257e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7267e860f15SJohn Edward Broadbent const std::string& param) { 7273ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 72845ca1b86SEd Tanous { 72945ca1b86SEd Tanous return; 73045ca1b86SEd Tanous } 731b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 7327e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 733b52664e2SAppaRao Puli if (subValue == nullptr) 734e5aaf047SAppaRao Puli { 735*bd79bce8SPatrick Williams asyncResp->res.result( 736*bd79bce8SPatrick Williams boost::beast::http::status::not_found); 737e5aaf047SAppaRao Puli return; 738e5aaf047SAppaRao Puli } 739e5aaf047SAppaRao Puli 740e5aaf047SAppaRao Puli std::optional<std::string> context; 741e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 74219bb362bSEd Tanous std::optional<bool> verifyCertificate; 74378d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 744e5aaf047SAppaRao Puli 745*bd79bce8SPatrick Williams if (!json_util::readJsonPatch( 746*bd79bce8SPatrick Williams req, asyncResp->res, "Context", context, 74719bb362bSEd Tanous "VerifyCertificate", verifyCertificate, 748*bd79bce8SPatrick Williams "DeliveryRetryPolicy", retryPolicy, "HttpHeaders", 749*bd79bce8SPatrick Williams headers)) 750e5aaf047SAppaRao Puli { 751e5aaf047SAppaRao Puli return; 752e5aaf047SAppaRao Puli } 753e5aaf047SAppaRao Puli 754e5aaf047SAppaRao Puli if (context) 755e5aaf047SAppaRao Puli { 756b52664e2SAppaRao Puli subValue->customText = *context; 757e5aaf047SAppaRao Puli } 758e5aaf047SAppaRao Puli 759e5aaf047SAppaRao Puli if (headers) 760e5aaf047SAppaRao Puli { 761601c71aeSEd Tanous boost::beast::http::fields fields; 76278d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 763601c71aeSEd Tanous { 76478d4ec4fSEd Tanous for (const auto& it : headerChunk) 765601c71aeSEd Tanous { 766601c71aeSEd Tanous const std::string* value = 76778d4ec4fSEd Tanous it.second.get_ptr<const std::string*>(); 768601c71aeSEd Tanous if (value == nullptr) 769601c71aeSEd Tanous { 770601c71aeSEd Tanous messages::propertyValueFormatError( 77178d4ec4fSEd Tanous asyncResp->res, it.second, 77278d4ec4fSEd Tanous "HttpHeaders/" + it.first); 773601c71aeSEd Tanous return; 774601c71aeSEd Tanous } 77578d4ec4fSEd Tanous fields.set(it.first, *value); 776601c71aeSEd Tanous } 777601c71aeSEd Tanous } 77878d4ec4fSEd Tanous subValue->httpHeaders = std::move(fields); 779e5aaf047SAppaRao Puli } 780e5aaf047SAppaRao Puli 781e5aaf047SAppaRao Puli if (retryPolicy) 782e5aaf047SAppaRao Puli { 783*bd79bce8SPatrick Williams if (std::ranges::find(supportedRetryPolicies, 784*bd79bce8SPatrick Williams *retryPolicy) == 7853544d2a7SEd Tanous supportedRetryPolicies.end()) 786e5aaf047SAppaRao Puli { 787*bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 788*bd79bce8SPatrick Williams *retryPolicy, 789e5aaf047SAppaRao Puli "DeliveryRetryPolicy"); 790e5aaf047SAppaRao Puli return; 791e5aaf047SAppaRao Puli } 792b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 793e5aaf047SAppaRao Puli } 794e5aaf047SAppaRao Puli 79519bb362bSEd Tanous if (verifyCertificate) 79619bb362bSEd Tanous { 79719bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 79819bb362bSEd Tanous } 79919bb362bSEd Tanous 800b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData(); 8017e860f15SJohn Edward Broadbent }); 8029d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 803ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 804ed398213SEd Tanous // ConfigureSelf 8057eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 806ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination) 807432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 8087e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 80945ca1b86SEd Tanous [&app](const crow::Request& req, 8107e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8117e860f15SJohn Edward Broadbent const std::string& param) { 8123ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 81345ca1b86SEd Tanous { 81445ca1b86SEd Tanous return; 81545ca1b86SEd Tanous } 8163d30708fSChicago Duan 8173d30708fSChicago Duan if (param.starts_with("snmp")) 8183d30708fSChicago Duan { 8193d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param); 820*bd79bce8SPatrick Williams EventServiceManager::getInstance().deleteSubscription( 821*bd79bce8SPatrick Williams param); 8223d30708fSChicago Duan return; 8233d30708fSChicago Duan } 8243d30708fSChicago Duan 825*bd79bce8SPatrick Williams if (!EventServiceManager::getInstance().isSubscriptionExist( 826*bd79bce8SPatrick Williams param)) 827e5aaf047SAppaRao Puli { 828*bd79bce8SPatrick Williams asyncResp->res.result( 829*bd79bce8SPatrick Williams boost::beast::http::status::not_found); 830e5aaf047SAppaRao Puli return; 831e5aaf047SAppaRao Puli } 8327e860f15SJohn Edward Broadbent EventServiceManager::getInstance().deleteSubscription(param); 8337e860f15SJohn Edward Broadbent }); 834e5aaf047SAppaRao Puli } 835e5aaf047SAppaRao Puli 836e5aaf047SAppaRao Puli } // namespace redfish 837