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" 19*539d8c6bSEd 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) 55002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 56002d39b4SEd Tanous [&app](const crow::Request& req, 57002d39b4SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 583ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 5945ca1b86SEd Tanous { 6045ca1b86SEd Tanous return; 6145ca1b86SEd Tanous } 621476687dSEd Tanous 631476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService"; 641476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 651476687dSEd Tanous "#EventService.v1_5_0.EventService"; 661476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "EventService"; 671476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Event Service"; 685e44e3d8SAppaRao Puli asyncResp->res.jsonValue["ServerSentEventUri"] = 695e44e3d8SAppaRao Puli "/redfish/v1/EventService/SSE"; 705e44e3d8SAppaRao Puli 711476687dSEd Tanous asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] = 721476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 73002d39b4SEd Tanous asyncResp->res 74002d39b4SEd Tanous .jsonValue["Actions"]["#EventService.SubmitTestEvent"]["target"] = 751476687dSEd Tanous "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"; 76e5aaf047SAppaRao Puli 7728afb49cSJunLin Chen const persistent_data::EventServiceConfig eventServiceConfig = 7828afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 7928afb49cSJunLin Chen .getEventServiceConfig(); 807d1cc387SAppaRao Puli 817d1cc387SAppaRao Puli asyncResp->res.jsonValue["Status"]["State"] = 8228afb49cSJunLin Chen (eventServiceConfig.enabled ? "Enabled" : "Disabled"); 83002d39b4SEd Tanous asyncResp->res.jsonValue["ServiceEnabled"] = eventServiceConfig.enabled; 847e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] = 8528afb49cSJunLin Chen eventServiceConfig.retryAttempts; 86e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] = 8728afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval; 88002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes; 890fda0f12SGeorge Liu asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes; 900fda0f12SGeorge Liu asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes; 9107941a88SAyushi Smriti 92613dabeaSEd Tanous nlohmann::json::object_t supportedSSEFilters; 93613dabeaSEd Tanous supportedSSEFilters["EventFormatType"] = true; 94613dabeaSEd Tanous supportedSSEFilters["MessageId"] = true; 95613dabeaSEd Tanous supportedSSEFilters["MetricReportDefinition"] = true; 96613dabeaSEd Tanous supportedSSEFilters["RegistryPrefix"] = true; 97613dabeaSEd Tanous supportedSSEFilters["OriginResource"] = false; 98613dabeaSEd Tanous supportedSSEFilters["ResourceType"] = false; 9907941a88SAyushi Smriti 10007941a88SAyushi Smriti asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] = 101613dabeaSEd Tanous std::move(supportedSSEFilters); 1027e860f15SJohn Edward Broadbent }); 103e5aaf047SAppaRao Puli 1047e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 105ed398213SEd Tanous .privileges(redfish::privileges::patchEventService) 1067e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 10745ca1b86SEd Tanous [&app](const crow::Request& req, 10845ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1093ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 110e5aaf047SAppaRao Puli { 11145ca1b86SEd Tanous return; 11245ca1b86SEd Tanous } 113e5aaf047SAppaRao Puli std::optional<bool> serviceEnabled; 114e5aaf047SAppaRao Puli std::optional<uint32_t> retryAttemps; 115e5aaf047SAppaRao Puli std::optional<uint32_t> retryInterval; 116e5aaf047SAppaRao Puli 11715ed6780SWilly Tu if (!json_util::readJsonPatch( 1187e860f15SJohn Edward Broadbent req, asyncResp->res, "ServiceEnabled", serviceEnabled, 1197e860f15SJohn Edward Broadbent "DeliveryRetryAttempts", retryAttemps, 1207e860f15SJohn Edward Broadbent "DeliveryRetryIntervalSeconds", retryInterval)) 121e5aaf047SAppaRao Puli { 122e5aaf047SAppaRao Puli return; 123e5aaf047SAppaRao Puli } 124e5aaf047SAppaRao Puli 12528afb49cSJunLin Chen persistent_data::EventServiceConfig eventServiceConfig = 12628afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 12728afb49cSJunLin Chen .getEventServiceConfig(); 1287d1cc387SAppaRao Puli 129e5aaf047SAppaRao Puli if (serviceEnabled) 130e5aaf047SAppaRao Puli { 13128afb49cSJunLin Chen eventServiceConfig.enabled = *serviceEnabled; 132e5aaf047SAppaRao Puli } 133e5aaf047SAppaRao Puli 134e5aaf047SAppaRao Puli if (retryAttemps) 135e5aaf047SAppaRao Puli { 136e5aaf047SAppaRao Puli // Supported range [1-3] 137e5aaf047SAppaRao Puli if ((*retryAttemps < 1) || (*retryAttemps > 3)) 138e5aaf047SAppaRao Puli { 139e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 140e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryAttemps), 141e5aaf047SAppaRao Puli "DeliveryRetryAttempts", "[1-3]"); 142e5aaf047SAppaRao Puli } 143e5aaf047SAppaRao Puli else 144e5aaf047SAppaRao Puli { 14528afb49cSJunLin Chen eventServiceConfig.retryAttempts = *retryAttemps; 146e5aaf047SAppaRao Puli } 147e5aaf047SAppaRao Puli } 148e5aaf047SAppaRao Puli 149e5aaf047SAppaRao Puli if (retryInterval) 150e5aaf047SAppaRao Puli { 15133a32b34SGunnar Mills // Supported range [5 - 180] 15233a32b34SGunnar Mills if ((*retryInterval < 5) || (*retryInterval > 180)) 153e5aaf047SAppaRao Puli { 154e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 155e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryInterval), 15633a32b34SGunnar Mills "DeliveryRetryIntervalSeconds", "[5-180]"); 157e5aaf047SAppaRao Puli } 158e5aaf047SAppaRao Puli else 159e5aaf047SAppaRao Puli { 160002d39b4SEd Tanous eventServiceConfig.retryTimeoutInterval = *retryInterval; 161e5aaf047SAppaRao Puli } 162e5aaf047SAppaRao Puli } 163e5aaf047SAppaRao Puli 1647d1cc387SAppaRao Puli EventServiceManager::getInstance().setEventServiceConfig( 16528afb49cSJunLin Chen eventServiceConfig); 1667e860f15SJohn Edward Broadbent }); 1670b4bdd93SAppaRao Puli } 1680b4bdd93SAppaRao Puli 1697e860f15SJohn Edward Broadbent inline void requestRoutesSubmitTestEvent(App& app) 1700b4bdd93SAppaRao Puli { 1717e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 1727e860f15SJohn Edward Broadbent app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/") 173ed398213SEd Tanous .privileges(redfish::privileges::postEventService) 1747e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 17545ca1b86SEd Tanous [&app](const crow::Request& req, 1767e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1773ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 17845ca1b86SEd Tanous { 17945ca1b86SEd Tanous return; 18045ca1b86SEd Tanous } 1816ba8c82eSsunharis_in if (!EventServiceManager::getInstance().sendTestEventLog()) 1826ba8c82eSsunharis_in { 1836ba8c82eSsunharis_in messages::serviceDisabled(asyncResp->res, 1846ba8c82eSsunharis_in "/redfish/v1/EventService/"); 1856ba8c82eSsunharis_in return; 1866ba8c82eSsunharis_in } 1878d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 1887e860f15SJohn Edward Broadbent }); 189e5aaf047SAppaRao Puli } 190e5aaf047SAppaRao Puli 1913d30708fSChicago Duan inline void doSubscriptionCollection( 192e81de512SEd Tanous const boost::system::error_code& ec, 1933d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1943d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) 1953d30708fSChicago Duan { 1963d30708fSChicago Duan if (ec) 1973d30708fSChicago Duan { 1981306101eSEd Tanous if (ec.value() == EBADR || ec.value() == EHOSTUNREACH) 1993d30708fSChicago Duan { 2003d30708fSChicago Duan // This is an optional process so just return if it isn't there 2013d30708fSChicago Duan return; 2023d30708fSChicago Duan } 2033d30708fSChicago Duan 20462598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec); 2053d30708fSChicago Duan messages::internalError(asyncResp->res); 2063d30708fSChicago Duan return; 2073d30708fSChicago Duan } 2083d30708fSChicago Duan nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 2093d30708fSChicago Duan for (const auto& objpath : resp) 2103d30708fSChicago Duan { 2113d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first); 2123d30708fSChicago Duan const std::string snmpId = path.filename(); 2133d30708fSChicago Duan if (snmpId.empty()) 2143d30708fSChicago Duan { 21562598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong"); 2163d30708fSChicago Duan messages::internalError(asyncResp->res); 2173d30708fSChicago Duan return; 2183d30708fSChicago Duan } 2193d30708fSChicago Duan 2203d30708fSChicago Duan getSnmpSubscriptionList(asyncResp, snmpId, memberArray); 2213d30708fSChicago Duan } 2223d30708fSChicago Duan } 2233d30708fSChicago Duan 2247e860f15SJohn Edward Broadbent inline void requestRoutesEventDestinationCollection(App& app) 225e5aaf047SAppaRao Puli { 2261ebe3e41SGayathri Leburu BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 227ed398213SEd Tanous .privileges(redfish::privileges::getEventDestinationCollection) 2287e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 22945ca1b86SEd Tanous [&app](const crow::Request& req, 2307e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2313ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 23245ca1b86SEd Tanous { 23345ca1b86SEd Tanous return; 23445ca1b86SEd Tanous } 2351476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2361476687dSEd Tanous "#EventDestinationCollection.EventDestinationCollection"; 2371476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2381476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 239002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Event Destination Collections"; 240e5aaf047SAppaRao Puli 241002d39b4SEd Tanous nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 242e5aaf047SAppaRao Puli 243b52664e2SAppaRao Puli std::vector<std::string> subscripIds = 244b52664e2SAppaRao Puli EventServiceManager::getInstance().getAllIDs(); 245b52664e2SAppaRao Puli memberArray = nlohmann::json::array(); 246002d39b4SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size(); 247b52664e2SAppaRao Puli 248b52664e2SAppaRao Puli for (const std::string& id : subscripIds) 249e5aaf047SAppaRao Puli { 2501476687dSEd Tanous nlohmann::json::object_t member; 2513d30708fSChicago Duan member["@odata.id"] = boost::urls::format( 2523d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}" + id); 253b2ba3072SPatrick Williams memberArray.emplace_back(std::move(member)); 254e5aaf047SAppaRao Puli } 2553d30708fSChicago Duan crow::connections::systemBus->async_method_call( 256e81de512SEd Tanous [asyncResp](const boost::system::error_code& ec, 2573d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) { 2583d30708fSChicago Duan doSubscriptionCollection(ec, asyncResp, resp); 2593d30708fSChicago Duan }, 2603d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 2613d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 2623d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 2637e860f15SJohn Edward Broadbent }); 2643d30708fSChicago Duan 2657e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 2667eeafa76SAbhishek Patel .privileges(redfish::privileges::postEventDestinationCollection) 267002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 268002d39b4SEd Tanous [&app](const crow::Request& req, 2697e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2703ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 27145ca1b86SEd Tanous { 27245ca1b86SEd Tanous return; 27345ca1b86SEd Tanous } 274fffb8c1fSEd Tanous if (EventServiceManager::getInstance().getNumberOfSubscriptions() >= 275fffb8c1fSEd Tanous maxNoOfSubscriptions) 276e5aaf047SAppaRao Puli { 277e5aaf047SAppaRao Puli messages::eventSubscriptionLimitExceeded(asyncResp->res); 278e5aaf047SAppaRao Puli return; 279e5aaf047SAppaRao Puli } 280e5aaf047SAppaRao Puli std::string destUrl; 281e5aaf047SAppaRao Puli std::string protocol; 28219bb362bSEd Tanous std::optional<bool> verifyCertificate; 283e5aaf047SAppaRao Puli std::optional<std::string> context; 284e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType; 28523a21a1cSEd Tanous std::optional<std::string> eventFormatType2; 286e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 287e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds; 288e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes; 289e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes; 29078d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 29178d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray; 292e5aaf047SAppaRao Puli 29315ed6780SWilly Tu if (!json_util::readJsonPatch( 294002d39b4SEd Tanous req, asyncResp->res, "Destination", destUrl, "Context", context, 295002d39b4SEd Tanous "Protocol", protocol, "SubscriptionType", subscriptionType, 296002d39b4SEd Tanous "EventFormatType", eventFormatType2, "HttpHeaders", headers, 297002d39b4SEd Tanous "RegistryPrefixes", regPrefixes, "MessageIds", msgIds, 298002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions", 29919bb362bSEd Tanous mrdJsonArray, "ResourceTypes", resTypes, "VerifyCertificate", 30019bb362bSEd Tanous verifyCertificate)) 301e5aaf047SAppaRao Puli { 302e5aaf047SAppaRao Puli return; 303e5aaf047SAppaRao Puli } 304e5aaf047SAppaRao Puli 305600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers 306600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000; 307600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize) 308600af5f1SAppaRao Puli { 309600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination", 310600af5f1SAppaRao Puli maxDestinationSize); 311600af5f1SAppaRao Puli return; 312600af5f1SAppaRao Puli } 313600af5f1SAppaRao Puli 314dd28ba82SAppaRao Puli if (regPrefixes && msgIds) 315dd28ba82SAppaRao Puli { 31626f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty()) 317dd28ba82SAppaRao Puli { 318002d39b4SEd Tanous messages::propertyValueConflict(asyncResp->res, "MessageIds", 319002d39b4SEd Tanous "RegistryPrefixes"); 320dd28ba82SAppaRao Puli return; 321dd28ba82SAppaRao Puli } 322dd28ba82SAppaRao Puli } 323dd28ba82SAppaRao Puli 3246fd29553SEd Tanous boost::system::result<boost::urls::url> url = 325a716aa74SEd Tanous boost::urls::parse_absolute_uri(destUrl); 326a716aa74SEd Tanous if (!url) 327e5aaf047SAppaRao Puli { 32862598e31SEd Tanous BMCWEB_LOG_WARNING("Failed to validate and split destination url"); 329e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl, 330e5aaf047SAppaRao Puli "Destination"); 331e5aaf047SAppaRao Puli return; 332e5aaf047SAppaRao Puli } 333a716aa74SEd Tanous url->normalize(); 334a716aa74SEd Tanous crow::utility::setProtocolDefaults(*url, protocol); 335a716aa74SEd Tanous crow::utility::setPortDefaults(*url); 336a716aa74SEd Tanous 337a716aa74SEd Tanous if (url->path().empty()) 338a716aa74SEd Tanous { 339a716aa74SEd Tanous url->set_path("/"); 340a716aa74SEd Tanous } 341a716aa74SEd Tanous 342a716aa74SEd Tanous if (url->has_userinfo()) 343a716aa74SEd Tanous { 344a716aa74SEd Tanous messages::propertyValueFormatError(asyncResp->res, destUrl, 345a716aa74SEd Tanous "Destination"); 346a716aa74SEd Tanous return; 347a716aa74SEd Tanous } 348b52664e2SAppaRao Puli 3493d30708fSChicago Duan if (protocol == "SNMPv2c") 3503d30708fSChicago Duan { 3513d30708fSChicago Duan if (context) 3523d30708fSChicago Duan { 3533d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context", 3543d30708fSChicago Duan "Protocol"); 3553d30708fSChicago Duan return; 3563d30708fSChicago Duan } 3573d30708fSChicago Duan if (eventFormatType2) 3583d30708fSChicago Duan { 3593d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3603d30708fSChicago Duan "EventFormatType", "Protocol"); 3613d30708fSChicago Duan return; 3623d30708fSChicago Duan } 3633d30708fSChicago Duan if (retryPolicy) 3643d30708fSChicago Duan { 3653d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "RetryPolicy", 3663d30708fSChicago Duan "Protocol"); 3673d30708fSChicago Duan return; 3683d30708fSChicago Duan } 3693d30708fSChicago Duan if (msgIds) 3703d30708fSChicago Duan { 3713d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "MessageIds", 3723d30708fSChicago Duan "Protocol"); 3733d30708fSChicago Duan return; 3743d30708fSChicago Duan } 3753d30708fSChicago Duan if (regPrefixes) 3763d30708fSChicago Duan { 3773d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, 3783d30708fSChicago Duan "RegistryPrefixes", "Protocol"); 3793d30708fSChicago Duan return; 3803d30708fSChicago Duan } 3813d30708fSChicago Duan if (resTypes) 3823d30708fSChicago Duan { 3833d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "ResourceTypes", 3843d30708fSChicago Duan "Protocol"); 3853d30708fSChicago Duan return; 3863d30708fSChicago Duan } 3873d30708fSChicago Duan if (headers) 3883d30708fSChicago Duan { 3893d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "HttpHeaders", 3903d30708fSChicago Duan "Protocol"); 3913d30708fSChicago Duan return; 3923d30708fSChicago Duan } 3933d30708fSChicago Duan if (mrdJsonArray) 3943d30708fSChicago Duan { 3953d30708fSChicago Duan messages::propertyValueConflict( 3963d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol"); 3973d30708fSChicago Duan return; 3983d30708fSChicago Duan } 399a716aa74SEd Tanous if (url->scheme() != "snmp") 400a716aa74SEd Tanous { 401a716aa74SEd Tanous messages::propertyValueConflict(asyncResp->res, "Destination", 402a716aa74SEd Tanous "Protocol"); 4033d30708fSChicago Duan return; 4043d30708fSChicago Duan } 4053d30708fSChicago Duan 406a716aa74SEd Tanous addSnmpTrapClient(asyncResp, url->host_address(), 407a716aa74SEd Tanous url->port_number()); 408a716aa74SEd Tanous return; 409b52664e2SAppaRao Puli } 4103d30708fSChicago Duan 411a716aa74SEd Tanous std::shared_ptr<Subscription> subValue = 412a716aa74SEd Tanous std::make_shared<Subscription>(*url, app.ioContext()); 413b52664e2SAppaRao Puli 414a716aa74SEd Tanous subValue->destinationUrl = std::move(*url); 415e5aaf047SAppaRao Puli 416e5aaf047SAppaRao Puli if (subscriptionType) 417e5aaf047SAppaRao Puli { 418e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent") 419e5aaf047SAppaRao Puli { 420fffb8c1fSEd Tanous messages::propertyValueNotInList( 421fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType"); 422e5aaf047SAppaRao Puli return; 423e5aaf047SAppaRao Puli } 424b52664e2SAppaRao Puli subValue->subscriptionType = *subscriptionType; 425e5aaf047SAppaRao Puli } 426e5aaf047SAppaRao Puli else 427e5aaf047SAppaRao Puli { 428b52664e2SAppaRao Puli subValue->subscriptionType = "RedfishEvent"; // Default 429e5aaf047SAppaRao Puli } 430e5aaf047SAppaRao Puli 431e5aaf047SAppaRao Puli if (protocol != "Redfish") 432e5aaf047SAppaRao Puli { 433e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol, 434e5aaf047SAppaRao Puli "Protocol"); 435e5aaf047SAppaRao Puli return; 436e5aaf047SAppaRao Puli } 437b52664e2SAppaRao Puli subValue->protocol = protocol; 438e5aaf047SAppaRao Puli 43919bb362bSEd Tanous if (verifyCertificate) 44019bb362bSEd Tanous { 44119bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 44219bb362bSEd Tanous } 44319bb362bSEd Tanous 44423a21a1cSEd Tanous if (eventFormatType2) 445e5aaf047SAppaRao Puli { 4463544d2a7SEd Tanous if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) == 4473544d2a7SEd Tanous supportedEvtFormatTypes.end()) 448e5aaf047SAppaRao Puli { 449fffb8c1fSEd Tanous messages::propertyValueNotInList( 450fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType"); 451e5aaf047SAppaRao Puli return; 452e5aaf047SAppaRao Puli } 45323a21a1cSEd Tanous subValue->eventFormatType = *eventFormatType2; 454e5aaf047SAppaRao Puli } 455e5aaf047SAppaRao Puli else 456e5aaf047SAppaRao Puli { 457e5aaf047SAppaRao Puli // If not specified, use default "Event" 45823a21a1cSEd Tanous subValue->eventFormatType = "Event"; 459e5aaf047SAppaRao Puli } 460e5aaf047SAppaRao Puli 461e5aaf047SAppaRao Puli if (context) 462e5aaf047SAppaRao Puli { 4638ece0e45SEd Tanous // This value is selected arbitrarily. 464600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256; 465600af5f1SAppaRao Puli if (context->size() > maxContextSize) 466600af5f1SAppaRao Puli { 467600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context", 468600af5f1SAppaRao Puli maxContextSize); 469600af5f1SAppaRao Puli return; 470600af5f1SAppaRao Puli } 471b52664e2SAppaRao Puli subValue->customText = *context; 472e5aaf047SAppaRao Puli } 473e5aaf047SAppaRao Puli 474e5aaf047SAppaRao Puli if (headers) 475e5aaf047SAppaRao Puli { 476600af5f1SAppaRao Puli size_t cumulativeLen = 0; 477600af5f1SAppaRao Puli 47878d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 479601c71aeSEd Tanous { 48078d4ec4fSEd Tanous for (const auto& item : headerChunk) 48178d4ec4fSEd Tanous { 48278d4ec4fSEd Tanous const std::string* value = 48378d4ec4fSEd Tanous item.second.get_ptr<const std::string*>(); 48478d4ec4fSEd Tanous if (value == nullptr) 48578d4ec4fSEd Tanous { 48678d4ec4fSEd Tanous messages::propertyValueFormatError( 48778d4ec4fSEd Tanous asyncResp->res, item.second, 48878d4ec4fSEd Tanous "HttpHeaders/" + item.first); 48978d4ec4fSEd Tanous return; 49078d4ec4fSEd Tanous } 49178d4ec4fSEd Tanous // Adding a new json value is the size of the key, + 49278d4ec4fSEd Tanous // the size of the value + 2 * 2 quotes for each, + 49378d4ec4fSEd Tanous // the colon and space between. example: 49478d4ec4fSEd Tanous // "key": "value" 49578d4ec4fSEd Tanous cumulativeLen += item.first.size() + value->size() + 6; 496600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp 497600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096; 498600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED) 499600af5f1SAppaRao Puli { 50078d4ec4fSEd Tanous messages::arraySizeTooLong( 50178d4ec4fSEd Tanous asyncResp->res, "HttpHeaders", maxHeaderSizeED); 502600af5f1SAppaRao Puli return; 503600af5f1SAppaRao Puli } 50478d4ec4fSEd Tanous subValue->httpHeaders.set(item.first, *value); 505601c71aeSEd Tanous } 506601c71aeSEd Tanous } 507e5aaf047SAppaRao Puli } 508e5aaf047SAppaRao Puli 509e5aaf047SAppaRao Puli if (regPrefixes) 510e5aaf047SAppaRao Puli { 511e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes) 512e5aaf047SAppaRao Puli { 5133544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) == 5143544d2a7SEd Tanous supportedRegPrefixes.end()) 515e5aaf047SAppaRao Puli { 516fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it, 517fffb8c1fSEd Tanous "RegistryPrefixes"); 518e5aaf047SAppaRao Puli return; 519e5aaf047SAppaRao Puli } 520e5aaf047SAppaRao Puli } 521b52664e2SAppaRao Puli subValue->registryPrefixes = *regPrefixes; 522e5aaf047SAppaRao Puli } 523e5aaf047SAppaRao Puli 524e56f254cSSunitha Harish if (resTypes) 525e56f254cSSunitha Harish { 526e56f254cSSunitha Harish for (const std::string& it : *resTypes) 527e56f254cSSunitha Harish { 5283544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) == 5293544d2a7SEd Tanous supportedResourceTypes.end()) 530e56f254cSSunitha Harish { 531e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it, 532e56f254cSSunitha Harish "ResourceTypes"); 533e56f254cSSunitha Harish return; 534e56f254cSSunitha Harish } 535e56f254cSSunitha Harish } 536e56f254cSSunitha Harish subValue->resourceTypes = *resTypes; 537e56f254cSSunitha Harish } 538e56f254cSSunitha Harish 539e5aaf047SAppaRao Puli if (msgIds) 540e5aaf047SAppaRao Puli { 541b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix; 542b304bd79SP Dheeraj Srujan Kumar 5437e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all 5447e860f15SJohn Edward Broadbent // supported prefixes 545b304bd79SP Dheeraj Srujan Kumar if (subValue->registryPrefixes.empty()) 546b304bd79SP Dheeraj Srujan Kumar { 547b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(), 548b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end()); 549b304bd79SP Dheeraj Srujan Kumar } 550b304bd79SP Dheeraj Srujan Kumar else 551b304bd79SP Dheeraj Srujan Kumar { 552b304bd79SP Dheeraj Srujan Kumar registryPrefix = subValue->registryPrefixes; 553b304bd79SP Dheeraj Srujan Kumar } 554b304bd79SP Dheeraj Srujan Kumar 555b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds) 556b304bd79SP Dheeraj Srujan Kumar { 557b304bd79SP Dheeraj Srujan Kumar bool validId = false; 558b304bd79SP Dheeraj Srujan Kumar 559b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry 560b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix) 561b304bd79SP Dheeraj Srujan Kumar { 562fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry> 563fffb8c1fSEd Tanous registry = 564fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it); 565b304bd79SP Dheeraj Srujan Kumar 5663544d2a7SEd Tanous if (std::ranges::any_of( 5673544d2a7SEd Tanous registry, 568fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry& 569fffb8c1fSEd Tanous messageEntry) { 57055f79e6fSEd Tanous return id == messageEntry.first; 571b304bd79SP Dheeraj Srujan Kumar })) 572b304bd79SP Dheeraj Srujan Kumar { 573b304bd79SP Dheeraj Srujan Kumar validId = true; 574b304bd79SP Dheeraj Srujan Kumar break; 575b304bd79SP Dheeraj Srujan Kumar } 576b304bd79SP Dheeraj Srujan Kumar } 577b304bd79SP Dheeraj Srujan Kumar 578b304bd79SP Dheeraj Srujan Kumar if (!validId) 579b304bd79SP Dheeraj Srujan Kumar { 580b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id, 581b304bd79SP Dheeraj Srujan Kumar "MessageIds"); 582b304bd79SP Dheeraj Srujan Kumar return; 583b304bd79SP Dheeraj Srujan Kumar } 584b304bd79SP Dheeraj Srujan Kumar } 585b304bd79SP Dheeraj Srujan Kumar 586b52664e2SAppaRao Puli subValue->registryMsgIds = *msgIds; 587e5aaf047SAppaRao Puli } 588e5aaf047SAppaRao Puli 589e5aaf047SAppaRao Puli if (retryPolicy) 590e5aaf047SAppaRao Puli { 5913544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 5923544d2a7SEd Tanous supportedRetryPolicies.end()) 593e5aaf047SAppaRao Puli { 594002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 595002d39b4SEd Tanous "DeliveryRetryPolicy"); 596e5aaf047SAppaRao Puli return; 597e5aaf047SAppaRao Puli } 598b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 599e5aaf047SAppaRao Puli } 600e5aaf047SAppaRao Puli else 601e5aaf047SAppaRao Puli { 602e5aaf047SAppaRao Puli // Default "TerminateAfterRetries" 603b52664e2SAppaRao Puli subValue->retryPolicy = "TerminateAfterRetries"; 604e5aaf047SAppaRao Puli } 605e5aaf047SAppaRao Puli 606144b6318SAppaRao Puli if (mrdJsonArray) 607156d6b00SAppaRao Puli { 60878d4ec4fSEd Tanous for (nlohmann::json::object_t& mrdObj : *mrdJsonArray) 609144b6318SAppaRao Puli { 610144b6318SAppaRao Puli std::string mrdUri; 611ea2e6eecSWilly Tu 61278d4ec4fSEd Tanous if (!json_util::readJsonObject(mrdObj, asyncResp->res, 61378d4ec4fSEd Tanous "@odata.id", mrdUri)) 614ea2e6eecSWilly Tu 615144b6318SAppaRao Puli { 616144b6318SAppaRao Puli return; 617144b6318SAppaRao Puli } 618ea2e6eecSWilly Tu subValue->metricReportDefinitions.emplace_back(mrdUri); 619144b6318SAppaRao Puli } 620156d6b00SAppaRao Puli } 621156d6b00SAppaRao Puli 622b52664e2SAppaRao Puli std::string id = 623f80a87f2SEd Tanous EventServiceManager::getInstance().addPushSubscription(subValue); 624b52664e2SAppaRao Puli if (id.empty()) 625e5aaf047SAppaRao Puli { 626e5aaf047SAppaRao Puli messages::internalError(asyncResp->res); 627e5aaf047SAppaRao Puli return; 628e5aaf047SAppaRao Puli } 629e5aaf047SAppaRao Puli 630e5aaf047SAppaRao Puli messages::created(asyncResp->res); 631e5aaf047SAppaRao Puli asyncResp->res.addHeader( 632e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id); 6337e860f15SJohn Edward Broadbent }); 634e5aaf047SAppaRao Puli } 635e5aaf047SAppaRao Puli 6367e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app) 637e5aaf047SAppaRao Puli { 6389d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 639ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination) 6407e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 64145ca1b86SEd Tanous [&app](const crow::Request& req, 6427e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6437e860f15SJohn Edward Broadbent const std::string& param) { 6443ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 64545ca1b86SEd Tanous { 64645ca1b86SEd Tanous return; 64745ca1b86SEd Tanous } 6483d30708fSChicago Duan 6493d30708fSChicago Duan if (param.starts_with("snmp")) 6503d30708fSChicago Duan { 6513d30708fSChicago Duan getSnmpTrapClient(asyncResp, param); 6523d30708fSChicago Duan return; 6533d30708fSChicago Duan } 6543d30708fSChicago Duan 655b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6567e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 657b52664e2SAppaRao Puli if (subValue == nullptr) 658e5aaf047SAppaRao Puli { 659002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 660e5aaf047SAppaRao Puli return; 661e5aaf047SAppaRao Puli } 6627e860f15SJohn Edward Broadbent const std::string& id = param; 663e5aaf047SAppaRao Puli 6641476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 6653d30708fSChicago Duan "#EventDestination.v1_8_0.EventDestination"; 666*539d8c6bSEd Tanous asyncResp->res.jsonValue["Protocol"] = 667*539d8c6bSEd Tanous event_destination::EventDestinationProtocol::Redfish; 6683b32780dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 6693b32780dSEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id); 670e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Id"] = id; 671e5aaf047SAppaRao Puli asyncResp->res.jsonValue["Name"] = "Event Destination " + id; 672002d39b4SEd Tanous asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl; 673b52664e2SAppaRao Puli asyncResp->res.jsonValue["Context"] = subValue->customText; 674e5aaf047SAppaRao Puli asyncResp->res.jsonValue["SubscriptionType"] = 675b52664e2SAppaRao Puli subValue->subscriptionType; 676002d39b4SEd Tanous asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array(); 677002d39b4SEd Tanous asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType; 678e5aaf047SAppaRao Puli asyncResp->res.jsonValue["RegistryPrefixes"] = 679b52664e2SAppaRao Puli subValue->registryPrefixes; 680002d39b4SEd Tanous asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes; 681e56f254cSSunitha Harish 682002d39b4SEd Tanous asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds; 683002d39b4SEd Tanous asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy; 68419bb362bSEd Tanous asyncResp->res.jsonValue["VerifyCertificate"] = 68519bb362bSEd Tanous subValue->verifyCertificate; 686144b6318SAppaRao Puli 6871476687dSEd Tanous nlohmann::json::array_t mrdJsonArray; 688144b6318SAppaRao Puli for (const auto& mdrUri : subValue->metricReportDefinitions) 689144b6318SAppaRao Puli { 6901476687dSEd Tanous nlohmann::json::object_t mdr; 6911476687dSEd Tanous mdr["@odata.id"] = mdrUri; 6921476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr)); 693144b6318SAppaRao Puli } 694002d39b4SEd Tanous asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray; 6957e860f15SJohn Edward Broadbent }); 6969d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 697ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 698ed398213SEd Tanous // ConfigureSelf 6997eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 700ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination) 701432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7027e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 70345ca1b86SEd Tanous [&app](const crow::Request& req, 7047e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7057e860f15SJohn Edward Broadbent const std::string& param) { 7063ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 70745ca1b86SEd Tanous { 70845ca1b86SEd Tanous return; 70945ca1b86SEd Tanous } 710b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 7117e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 712b52664e2SAppaRao Puli if (subValue == nullptr) 713e5aaf047SAppaRao Puli { 714002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 715e5aaf047SAppaRao Puli return; 716e5aaf047SAppaRao Puli } 717e5aaf047SAppaRao Puli 718e5aaf047SAppaRao Puli std::optional<std::string> context; 719e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 72019bb362bSEd Tanous std::optional<bool> verifyCertificate; 72178d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 722e5aaf047SAppaRao Puli 723002d39b4SEd Tanous if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context, 72419bb362bSEd Tanous "VerifyCertificate", verifyCertificate, 725002d39b4SEd Tanous "DeliveryRetryPolicy", retryPolicy, 726002d39b4SEd Tanous "HttpHeaders", headers)) 727e5aaf047SAppaRao Puli { 728e5aaf047SAppaRao Puli return; 729e5aaf047SAppaRao Puli } 730e5aaf047SAppaRao Puli 731e5aaf047SAppaRao Puli if (context) 732e5aaf047SAppaRao Puli { 733b52664e2SAppaRao Puli subValue->customText = *context; 734e5aaf047SAppaRao Puli } 735e5aaf047SAppaRao Puli 736e5aaf047SAppaRao Puli if (headers) 737e5aaf047SAppaRao Puli { 738601c71aeSEd Tanous boost::beast::http::fields fields; 73978d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 740601c71aeSEd Tanous { 74178d4ec4fSEd Tanous for (const auto& it : headerChunk) 742601c71aeSEd Tanous { 743601c71aeSEd Tanous const std::string* value = 74478d4ec4fSEd Tanous it.second.get_ptr<const std::string*>(); 745601c71aeSEd Tanous if (value == nullptr) 746601c71aeSEd Tanous { 747601c71aeSEd Tanous messages::propertyValueFormatError( 74878d4ec4fSEd Tanous asyncResp->res, it.second, 74978d4ec4fSEd Tanous "HttpHeaders/" + it.first); 750601c71aeSEd Tanous return; 751601c71aeSEd Tanous } 75278d4ec4fSEd Tanous fields.set(it.first, *value); 753601c71aeSEd Tanous } 754601c71aeSEd Tanous } 75578d4ec4fSEd Tanous subValue->httpHeaders = std::move(fields); 756e5aaf047SAppaRao Puli } 757e5aaf047SAppaRao Puli 758e5aaf047SAppaRao Puli if (retryPolicy) 759e5aaf047SAppaRao Puli { 7603544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 7613544d2a7SEd Tanous supportedRetryPolicies.end()) 762e5aaf047SAppaRao Puli { 763002d39b4SEd Tanous messages::propertyValueNotInList(asyncResp->res, *retryPolicy, 764e5aaf047SAppaRao Puli "DeliveryRetryPolicy"); 765e5aaf047SAppaRao Puli return; 766e5aaf047SAppaRao Puli } 767b52664e2SAppaRao Puli subValue->retryPolicy = *retryPolicy; 768e5aaf047SAppaRao Puli } 769e5aaf047SAppaRao Puli 77019bb362bSEd Tanous if (verifyCertificate) 77119bb362bSEd Tanous { 77219bb362bSEd Tanous subValue->verifyCertificate = *verifyCertificate; 77319bb362bSEd Tanous } 77419bb362bSEd Tanous 775b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData(); 7767e860f15SJohn Edward Broadbent }); 7779d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 778ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 779ed398213SEd Tanous // ConfigureSelf 7807eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 781ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination) 782432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7837e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 78445ca1b86SEd Tanous [&app](const crow::Request& req, 7857e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7867e860f15SJohn Edward Broadbent const std::string& param) { 7873ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 78845ca1b86SEd Tanous { 78945ca1b86SEd Tanous return; 79045ca1b86SEd Tanous } 7913d30708fSChicago Duan 7923d30708fSChicago Duan if (param.starts_with("snmp")) 7933d30708fSChicago Duan { 7943d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param); 7953d30708fSChicago Duan EventServiceManager::getInstance().deleteSubscription(param); 7963d30708fSChicago Duan return; 7973d30708fSChicago Duan } 7983d30708fSChicago Duan 799002d39b4SEd Tanous if (!EventServiceManager::getInstance().isSubscriptionExist(param)) 800e5aaf047SAppaRao Puli { 801002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::not_found); 802e5aaf047SAppaRao Puli return; 803e5aaf047SAppaRao Puli } 8047e860f15SJohn Edward Broadbent EventServiceManager::getInstance().deleteSubscription(param); 8057e860f15SJohn Edward Broadbent }); 806e5aaf047SAppaRao Puli } 807e5aaf047SAppaRao Puli 808e5aaf047SAppaRao Puli } // namespace redfish 809