1e5aaf047SAppaRao Puli /* 2*6be832e2SEd Tanous Copyright (c) 2020 Intel Corporation 3*6be832e2SEd Tanous 4*6be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License"); 5*6be832e2SEd Tanous you may not use this file except in compliance with the License. 6*6be832e2SEd Tanous You may obtain a copy of the License at 7*6be832e2SEd Tanous 8*6be832e2SEd Tanous http://www.apache.org/licenses/LICENSE-2.0 9*6be832e2SEd Tanous 10*6be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software 11*6be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS, 12*6be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*6be832e2SEd Tanous See the License for the specific language governing permissions and 14*6be832e2SEd Tanous 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) 55bd79bce8SPatrick Williams .methods( 56bd79bce8SPatrick Williams boost::beast::http::verb:: 57bd79bce8SPatrick Williams get)([&app]( 58bd79bce8SPatrick 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"; 75bd79bce8SPatrick Williams asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"] 76bd79bce8SPatrick 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"); 85bd79bce8SPatrick Williams asyncResp->res.jsonValue["ServiceEnabled"] = 86bd79bce8SPatrick Williams eventServiceConfig.enabled; 877e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] = 8828afb49cSJunLin Chen eventServiceConfig.retryAttempts; 89e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] = 9028afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval; 91bd79bce8SPatrick Williams asyncResp->res.jsonValue["EventFormatTypes"] = 92bd79bce8SPatrick 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 { 164bd79bce8SPatrick Williams eventServiceConfig.retryTimeoutInterval = 165bd79bce8SPatrick 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"; 244bd79bce8SPatrick Williams asyncResp->res.jsonValue["Name"] = 245bd79bce8SPatrick Williams "Event Destination Collections"; 246e5aaf047SAppaRao Puli 247bd79bce8SPatrick Williams nlohmann::json& memberArray = 248bd79bce8SPatrick 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(); 253bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members@odata.count"] = 254bd79bce8SPatrick 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) 275bd79bce8SPatrick Williams .methods( 276bd79bce8SPatrick Williams boost::beast::http::verb:: 277bd79bce8SPatrick Williams post)([&app]( 278bd79bce8SPatrick 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( 304bd79bce8SPatrick Williams req, asyncResp->res, "Destination", destUrl, "Context", 305bd79bce8SPatrick Williams context, "Protocol", protocol, "SubscriptionType", 306bd79bce8SPatrick Williams subscriptionType, "EventFormatType", eventFormatType2, 307bd79bce8SPatrick Williams "HttpHeaders", headers, "RegistryPrefixes", regPrefixes, 308bd79bce8SPatrick Williams "MessageIds", msgIds, "DeliveryRetryPolicy", retryPolicy, 309bd79bce8SPatrick Williams "MetricReportDefinitions", mrdJsonArray, "ResourceTypes", 310bd79bce8SPatrick 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 { 328bd79bce8SPatrick Williams messages::propertyValueConflict( 329bd79bce8SPatrick 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 { 338bd79bce8SPatrick Williams BMCWEB_LOG_WARNING( 339bd79bce8SPatrick 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 { 370bd79bce8SPatrick Williams messages::propertyValueConflict( 371bd79bce8SPatrick Williams asyncResp->res, "EventFormatType", "Protocol"); 3723d30708fSChicago Duan return; 3733d30708fSChicago Duan } 3743d30708fSChicago Duan if (retryPolicy) 3753d30708fSChicago Duan { 376bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 377bd79bce8SPatrick Williams "RetryPolicy", "Protocol"); 3783d30708fSChicago Duan return; 3793d30708fSChicago Duan } 3803d30708fSChicago Duan if (msgIds) 3813d30708fSChicago Duan { 382bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 383bd79bce8SPatrick Williams "MessageIds", "Protocol"); 3843d30708fSChicago Duan return; 3853d30708fSChicago Duan } 3863d30708fSChicago Duan if (regPrefixes) 3873d30708fSChicago Duan { 388bd79bce8SPatrick Williams messages::propertyValueConflict( 389bd79bce8SPatrick Williams asyncResp->res, "RegistryPrefixes", "Protocol"); 3903d30708fSChicago Duan return; 3913d30708fSChicago Duan } 3923d30708fSChicago Duan if (resTypes) 3933d30708fSChicago Duan { 394bd79bce8SPatrick Williams messages::propertyValueConflict( 395bd79bce8SPatrick Williams asyncResp->res, "ResourceTypes", "Protocol"); 3963d30708fSChicago Duan return; 3973d30708fSChicago Duan } 3983d30708fSChicago Duan if (headers) 3993d30708fSChicago Duan { 400bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 401bd79bce8SPatrick 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 { 412bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 413bd79bce8SPatrick 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 { 457bd79bce8SPatrick Williams if (std::ranges::find(supportedEvtFormatTypes, 458bd79bce8SPatrick 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 { 606bd79bce8SPatrick Williams messages::propertyValueNotInList( 607bd79bce8SPatrick 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 = 635bd79bce8SPatrick Williams EventServiceManager::getInstance().addPushSubscription( 636bd79bce8SPatrick 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 { 672bd79bce8SPatrick Williams asyncResp->res.result( 673bd79bce8SPatrick 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"] = 6798759961cSMyung Bae "#EventDestination.v1_14_1.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; 686bd79bce8SPatrick Williams asyncResp->res.jsonValue["Destination"] = 687bd79bce8SPatrick Williams subValue->destinationUrl; 688b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText; 689e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] = 690b52664e2SAppaRao Puli subValue->subscriptionType; 691bd79bce8SPatrick Williams asyncResp->res.jsonValue["HttpHeaders"] = 692bd79bce8SPatrick Williams nlohmann::json::array(); 693bd79bce8SPatrick Williams asyncResp->res.jsonValue["EventFormatType"] = 694bd79bce8SPatrick Williams subValue->eventFormatType; 695e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] = 696b52664e2SAppaRao Puli subValue->registryPrefixes; 697bd79bce8SPatrick Williams asyncResp->res.jsonValue["ResourceTypes"] = 698bd79bce8SPatrick Williams subValue->resourceTypes; 699e56f254cSSunitha Harish 700bd79bce8SPatrick Williams asyncResp->res.jsonValue["MessageIds"] = 701bd79bce8SPatrick Williams subValue->registryMsgIds; 702bd79bce8SPatrick Williams asyncResp->res.jsonValue["DeliveryRetryPolicy"] = 703bd79bce8SPatrick 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 } 714bd79bce8SPatrick Williams asyncResp->res.jsonValue["MetricReportDefinitions"] = 715bd79bce8SPatrick 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 { 735bd79bce8SPatrick Williams asyncResp->res.result( 736bd79bce8SPatrick 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 745bd79bce8SPatrick Williams if (!json_util::readJsonPatch( 746bd79bce8SPatrick Williams req, asyncResp->res, "Context", context, 74719bb362bSEd Tanous "VerifyCertificate", verifyCertificate, 748bd79bce8SPatrick Williams "DeliveryRetryPolicy", retryPolicy, "HttpHeaders", 749bd79bce8SPatrick 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 { 783bd79bce8SPatrick Williams if (std::ranges::find(supportedRetryPolicies, 784bd79bce8SPatrick Williams *retryPolicy) == 7853544d2a7SEd Tanous supportedRetryPolicies.end()) 786e5aaf047SAppaRao Puli { 787bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 788bd79bce8SPatrick 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); 820bd79bce8SPatrick Williams EventServiceManager::getInstance().deleteSubscription( 821bd79bce8SPatrick Williams param); 8223d30708fSChicago Duan return; 8233d30708fSChicago Duan } 8243d30708fSChicago Duan 825bd79bce8SPatrick Williams if (!EventServiceManager::getInstance().isSubscriptionExist( 826bd79bce8SPatrick Williams param)) 827e5aaf047SAppaRao Puli { 828bd79bce8SPatrick Williams asyncResp->res.result( 829bd79bce8SPatrick 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