1e5aaf047SAppaRao Puli /* 26be832e2SEd Tanous Copyright (c) 2020 Intel Corporation 36be832e2SEd Tanous 46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License"); 56be832e2SEd Tanous you may not use this file except in compliance with the License. 66be832e2SEd Tanous You may obtain a copy of the License at 76be832e2SEd Tanous 86be832e2SEd Tanous http://www.apache.org/licenses/LICENSE-2.0 96be832e2SEd Tanous 106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software 116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS, 126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136be832e2SEd Tanous See the License for the specific language governing permissions and 146be832e2SEd 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> 37a14c9113SEd Tanous #include <vector> 381e270c5fSPatrick Williams 39e5aaf047SAppaRao Puli namespace redfish 40e5aaf047SAppaRao Puli { 41e5aaf047SAppaRao Puli 42156d6b00SAppaRao Puli static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = { 43156d6b00SAppaRao Puli eventFormatType, metricReportFormatType}; 44e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRegPrefixes = { 45b304bd79SP Dheeraj Srujan Kumar "Base", "OpenBMC", "TaskEvent"}; 46e5aaf047SAppaRao Puli static constexpr const std::array<const char*, 3> supportedRetryPolicies = { 47e5aaf047SAppaRao Puli "TerminateAfterRetries", "SuspendRetries", "RetryForever"}; 48e5aaf047SAppaRao Puli 49e56f254cSSunitha Harish static constexpr const std::array<const char*, 1> supportedResourceTypes = { 50e56f254cSSunitha Harish "Task"}; 51e56f254cSSunitha Harish 527e860f15SJohn Edward Broadbent inline void requestRoutesEventService(App& app) 53e5aaf047SAppaRao Puli { 547e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 55ed398213SEd Tanous .privileges(redfish::privileges::getEventService) 56bd79bce8SPatrick Williams .methods( 57bd79bce8SPatrick Williams boost::beast::http::verb:: 58bd79bce8SPatrick Williams get)([&app]( 59bd79bce8SPatrick Williams const crow::Request& req, 60002d39b4SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 613ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 6245ca1b86SEd Tanous { 6345ca1b86SEd Tanous return; 6445ca1b86SEd Tanous } 651476687dSEd Tanous 661476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService"; 671476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 681476687dSEd Tanous "#EventService.v1_5_0.EventService"; 691476687dSEd Tanous asyncResp->res.jsonValue["Id"] = "EventService"; 701476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "Event Service"; 715e44e3d8SAppaRao Puli asyncResp->res.jsonValue["ServerSentEventUri"] = 725e44e3d8SAppaRao Puli "/redfish/v1/EventService/SSE"; 735e44e3d8SAppaRao Puli 741476687dSEd Tanous asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] = 751476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 76bd79bce8SPatrick Williams asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"] 77bd79bce8SPatrick Williams ["target"] = 781476687dSEd Tanous "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"; 79e5aaf047SAppaRao Puli 8028afb49cSJunLin Chen const persistent_data::EventServiceConfig eventServiceConfig = 8128afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 8228afb49cSJunLin Chen .getEventServiceConfig(); 837d1cc387SAppaRao Puli 847d1cc387SAppaRao Puli asyncResp->res.jsonValue["Status"]["State"] = 8528afb49cSJunLin Chen (eventServiceConfig.enabled ? "Enabled" : "Disabled"); 86bd79bce8SPatrick Williams asyncResp->res.jsonValue["ServiceEnabled"] = 87bd79bce8SPatrick Williams eventServiceConfig.enabled; 887e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["DeliveryRetryAttempts"] = 8928afb49cSJunLin Chen eventServiceConfig.retryAttempts; 90e5aaf047SAppaRao Puli asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] = 9128afb49cSJunLin Chen eventServiceConfig.retryTimeoutInterval; 92bd79bce8SPatrick Williams asyncResp->res.jsonValue["EventFormatTypes"] = 93bd79bce8SPatrick Williams supportedEvtFormatTypes; 940fda0f12SGeorge Liu asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes; 950fda0f12SGeorge Liu asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes; 9607941a88SAyushi Smriti 97613dabeaSEd Tanous nlohmann::json::object_t supportedSSEFilters; 98613dabeaSEd Tanous supportedSSEFilters["EventFormatType"] = true; 99613dabeaSEd Tanous supportedSSEFilters["MessageId"] = true; 100613dabeaSEd Tanous supportedSSEFilters["MetricReportDefinition"] = true; 101613dabeaSEd Tanous supportedSSEFilters["RegistryPrefix"] = true; 102613dabeaSEd Tanous supportedSSEFilters["OriginResource"] = false; 103613dabeaSEd Tanous supportedSSEFilters["ResourceType"] = false; 10407941a88SAyushi Smriti 10507941a88SAyushi Smriti asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] = 106613dabeaSEd Tanous std::move(supportedSSEFilters); 1077e860f15SJohn Edward Broadbent }); 108e5aaf047SAppaRao Puli 1097e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/") 110ed398213SEd Tanous .privileges(redfish::privileges::patchEventService) 1117e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 11245ca1b86SEd Tanous [&app](const crow::Request& req, 11345ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1143ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 115e5aaf047SAppaRao Puli { 11645ca1b86SEd Tanous return; 11745ca1b86SEd Tanous } 118e5aaf047SAppaRao Puli std::optional<bool> serviceEnabled; 119e5aaf047SAppaRao Puli std::optional<uint32_t> retryAttemps; 120e5aaf047SAppaRao Puli std::optional<uint32_t> retryInterval; 121*afc474aeSMyung Bae if (!json_util::readJsonPatch( // 122*afc474aeSMyung Bae req, asyncResp->res, // 123*afc474aeSMyung Bae "DeliveryRetryAttempts", retryAttemps, // 124*afc474aeSMyung Bae "DeliveryRetryIntervalSeconds", retryInterval, // 125*afc474aeSMyung Bae "ServiceEnabled", serviceEnabled // 126*afc474aeSMyung Bae )) 127e5aaf047SAppaRao Puli { 128e5aaf047SAppaRao Puli return; 129e5aaf047SAppaRao Puli } 130e5aaf047SAppaRao Puli 13128afb49cSJunLin Chen persistent_data::EventServiceConfig eventServiceConfig = 13228afb49cSJunLin Chen persistent_data::EventServiceStore::getInstance() 13328afb49cSJunLin Chen .getEventServiceConfig(); 1347d1cc387SAppaRao Puli 135e5aaf047SAppaRao Puli if (serviceEnabled) 136e5aaf047SAppaRao Puli { 13728afb49cSJunLin Chen eventServiceConfig.enabled = *serviceEnabled; 138e5aaf047SAppaRao Puli } 139e5aaf047SAppaRao Puli 140e5aaf047SAppaRao Puli if (retryAttemps) 141e5aaf047SAppaRao Puli { 142e5aaf047SAppaRao Puli // Supported range [1-3] 143e5aaf047SAppaRao Puli if ((*retryAttemps < 1) || (*retryAttemps > 3)) 144e5aaf047SAppaRao Puli { 145e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 146e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryAttemps), 147e5aaf047SAppaRao Puli "DeliveryRetryAttempts", "[1-3]"); 148e5aaf047SAppaRao Puli } 149e5aaf047SAppaRao Puli else 150e5aaf047SAppaRao Puli { 15128afb49cSJunLin Chen eventServiceConfig.retryAttempts = *retryAttemps; 152e5aaf047SAppaRao Puli } 153e5aaf047SAppaRao Puli } 154e5aaf047SAppaRao Puli 155e5aaf047SAppaRao Puli if (retryInterval) 156e5aaf047SAppaRao Puli { 15733a32b34SGunnar Mills // Supported range [5 - 180] 15833a32b34SGunnar Mills if ((*retryInterval < 5) || (*retryInterval > 180)) 159e5aaf047SAppaRao Puli { 160e5aaf047SAppaRao Puli messages::queryParameterOutOfRange( 161e5aaf047SAppaRao Puli asyncResp->res, std::to_string(*retryInterval), 16233a32b34SGunnar Mills "DeliveryRetryIntervalSeconds", "[5-180]"); 163e5aaf047SAppaRao Puli } 164e5aaf047SAppaRao Puli else 165e5aaf047SAppaRao Puli { 166bd79bce8SPatrick Williams eventServiceConfig.retryTimeoutInterval = 167bd79bce8SPatrick Williams *retryInterval; 168e5aaf047SAppaRao Puli } 169e5aaf047SAppaRao Puli } 170e5aaf047SAppaRao Puli 1717d1cc387SAppaRao Puli EventServiceManager::getInstance().setEventServiceConfig( 17228afb49cSJunLin Chen eventServiceConfig); 1737e860f15SJohn Edward Broadbent }); 1740b4bdd93SAppaRao Puli } 1750b4bdd93SAppaRao Puli 1767e860f15SJohn Edward Broadbent inline void requestRoutesSubmitTestEvent(App& app) 1770b4bdd93SAppaRao Puli { 1787e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 1797e860f15SJohn Edward Broadbent app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/") 180ed398213SEd Tanous .privileges(redfish::privileges::postEventService) 1817e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 18245ca1b86SEd Tanous [&app](const crow::Request& req, 1837e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1843ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 18545ca1b86SEd Tanous { 18645ca1b86SEd Tanous return; 18745ca1b86SEd Tanous } 1886ba8c82eSsunharis_in if (!EventServiceManager::getInstance().sendTestEventLog()) 1896ba8c82eSsunharis_in { 1906ba8c82eSsunharis_in messages::serviceDisabled(asyncResp->res, 1916ba8c82eSsunharis_in "/redfish/v1/EventService/"); 1926ba8c82eSsunharis_in return; 1936ba8c82eSsunharis_in } 1948d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 1957e860f15SJohn Edward Broadbent }); 196e5aaf047SAppaRao Puli } 197e5aaf047SAppaRao Puli 1983d30708fSChicago Duan inline void doSubscriptionCollection( 199e81de512SEd Tanous const boost::system::error_code& ec, 2003d30708fSChicago Duan const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2013d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) 2023d30708fSChicago Duan { 2033d30708fSChicago Duan if (ec) 2043d30708fSChicago Duan { 2051306101eSEd Tanous if (ec.value() == EBADR || ec.value() == EHOSTUNREACH) 2063d30708fSChicago Duan { 2073d30708fSChicago Duan // This is an optional process so just return if it isn't there 2083d30708fSChicago Duan return; 2093d30708fSChicago Duan } 2103d30708fSChicago Duan 21162598e31SEd Tanous BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec); 2123d30708fSChicago Duan messages::internalError(asyncResp->res); 2133d30708fSChicago Duan return; 2143d30708fSChicago Duan } 2153d30708fSChicago Duan nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"]; 2163d30708fSChicago Duan for (const auto& objpath : resp) 2173d30708fSChicago Duan { 2183d30708fSChicago Duan sdbusplus::message::object_path path(objpath.first); 2193d30708fSChicago Duan const std::string snmpId = path.filename(); 2203d30708fSChicago Duan if (snmpId.empty()) 2213d30708fSChicago Duan { 22262598e31SEd Tanous BMCWEB_LOG_ERROR("The SNMP client ID is wrong"); 2233d30708fSChicago Duan messages::internalError(asyncResp->res); 2243d30708fSChicago Duan return; 2253d30708fSChicago Duan } 2263d30708fSChicago Duan 2273d30708fSChicago Duan getSnmpSubscriptionList(asyncResp, snmpId, memberArray); 2283d30708fSChicago Duan } 2293d30708fSChicago Duan } 2303d30708fSChicago Duan 2317e860f15SJohn Edward Broadbent inline void requestRoutesEventDestinationCollection(App& app) 232e5aaf047SAppaRao Puli { 2331ebe3e41SGayathri Leburu BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 234ed398213SEd Tanous .privileges(redfish::privileges::getEventDestinationCollection) 2357e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 23645ca1b86SEd Tanous [&app](const crow::Request& req, 2377e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2383ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 23945ca1b86SEd Tanous { 24045ca1b86SEd Tanous return; 24145ca1b86SEd Tanous } 2421476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2431476687dSEd Tanous "#EventDestinationCollection.EventDestinationCollection"; 2441476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2451476687dSEd Tanous "/redfish/v1/EventService/Subscriptions"; 246bd79bce8SPatrick Williams asyncResp->res.jsonValue["Name"] = 247bd79bce8SPatrick Williams "Event Destination Collections"; 248e5aaf047SAppaRao Puli 249bd79bce8SPatrick Williams nlohmann::json& memberArray = 250bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members"]; 251e5aaf047SAppaRao Puli 252b52664e2SAppaRao Puli std::vector<std::string> subscripIds = 253b52664e2SAppaRao Puli EventServiceManager::getInstance().getAllIDs(); 254b52664e2SAppaRao Puli memberArray = nlohmann::json::array(); 255bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members@odata.count"] = 256bd79bce8SPatrick Williams subscripIds.size(); 257b52664e2SAppaRao Puli 258b52664e2SAppaRao Puli for (const std::string& id : subscripIds) 259e5aaf047SAppaRao Puli { 2601476687dSEd Tanous nlohmann::json::object_t member; 2613d30708fSChicago Duan member["@odata.id"] = boost::urls::format( 2623d30708fSChicago Duan "/redfish/v1/EventService/Subscriptions/{}" + id); 263b2ba3072SPatrick Williams memberArray.emplace_back(std::move(member)); 264e5aaf047SAppaRao Puli } 2653d30708fSChicago Duan crow::connections::systemBus->async_method_call( 266e81de512SEd Tanous [asyncResp](const boost::system::error_code& ec, 2673d30708fSChicago Duan const dbus::utility::ManagedObjectType& resp) { 2683d30708fSChicago Duan doSubscriptionCollection(ec, asyncResp, resp); 2693d30708fSChicago Duan }, 2703d30708fSChicago Duan "xyz.openbmc_project.Network.SNMP", 2713d30708fSChicago Duan "/xyz/openbmc_project/network/snmp/manager", 2723d30708fSChicago Duan "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 2737e860f15SJohn Edward Broadbent }); 2743d30708fSChicago Duan 2757e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/") 2767eeafa76SAbhishek Patel .privileges(redfish::privileges::postEventDestinationCollection) 277bd79bce8SPatrick Williams .methods( 278bd79bce8SPatrick Williams boost::beast::http::verb:: 279bd79bce8SPatrick Williams post)([&app]( 280bd79bce8SPatrick Williams const crow::Request& req, 2817e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2823ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 28345ca1b86SEd Tanous { 28445ca1b86SEd Tanous return; 28545ca1b86SEd Tanous } 286fffb8c1fSEd Tanous if (EventServiceManager::getInstance().getNumberOfSubscriptions() >= 287fffb8c1fSEd Tanous maxNoOfSubscriptions) 288e5aaf047SAppaRao Puli { 289e5aaf047SAppaRao Puli messages::eventSubscriptionLimitExceeded(asyncResp->res); 290e5aaf047SAppaRao Puli return; 291e5aaf047SAppaRao Puli } 292e5aaf047SAppaRao Puli std::string destUrl; 293e5aaf047SAppaRao Puli std::string protocol; 29419bb362bSEd Tanous std::optional<bool> verifyCertificate; 295e5aaf047SAppaRao Puli std::optional<std::string> context; 296e5aaf047SAppaRao Puli std::optional<std::string> subscriptionType; 29723a21a1cSEd Tanous std::optional<std::string> eventFormatType2; 298e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 299e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> msgIds; 300e5aaf047SAppaRao Puli std::optional<std::vector<std::string>> regPrefixes; 301a14c9113SEd Tanous std::optional<std::vector<std::string>> originResources; 302e56f254cSSunitha Harish std::optional<std::vector<std::string>> resTypes; 30378d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 30478d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray; 305e5aaf047SAppaRao Puli 306*afc474aeSMyung Bae if (!json_util::readJsonPatch( // 307*afc474aeSMyung Bae req, asyncResp->res, // 308*afc474aeSMyung Bae "Context", context, // 309*afc474aeSMyung Bae "DeliveryRetryPolicy", retryPolicy, // 310*afc474aeSMyung Bae "Destination", destUrl, // 311*afc474aeSMyung Bae "EventFormatType", eventFormatType2, // 312*afc474aeSMyung Bae "HttpHeaders", headers, // 313*afc474aeSMyung Bae "MessageIds", msgIds, // 314*afc474aeSMyung Bae "MetricReportDefinitions", mrdJsonArray, // 315*afc474aeSMyung Bae "OriginResources", originResources, // 316*afc474aeSMyung Bae "Protocol", protocol, // 317*afc474aeSMyung Bae "RegistryPrefixes", regPrefixes, // 318*afc474aeSMyung Bae "ResourceTypes", resTypes, // 319*afc474aeSMyung Bae "SubscriptionType", subscriptionType, // 320*afc474aeSMyung Bae "VerifyCertificate", verifyCertificate // 3214b712a29SEd Tanous )) 322e5aaf047SAppaRao Puli { 323e5aaf047SAppaRao Puli return; 324e5aaf047SAppaRao Puli } 3254b712a29SEd Tanous // clang-format on 326e5aaf047SAppaRao Puli 327600af5f1SAppaRao Puli // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers 328600af5f1SAppaRao Puli static constexpr const uint16_t maxDestinationSize = 2000; 329600af5f1SAppaRao Puli if (destUrl.size() > maxDestinationSize) 330600af5f1SAppaRao Puli { 331600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Destination", 332600af5f1SAppaRao Puli maxDestinationSize); 333600af5f1SAppaRao Puli return; 334600af5f1SAppaRao Puli } 335600af5f1SAppaRao Puli 336dd28ba82SAppaRao Puli if (regPrefixes && msgIds) 337dd28ba82SAppaRao Puli { 33826f6976fSEd Tanous if (!regPrefixes->empty() && !msgIds->empty()) 339dd28ba82SAppaRao Puli { 340bd79bce8SPatrick Williams messages::propertyValueConflict( 341bd79bce8SPatrick Williams asyncResp->res, "MessageIds", "RegistryPrefixes"); 342dd28ba82SAppaRao Puli return; 343dd28ba82SAppaRao Puli } 344dd28ba82SAppaRao Puli } 345dd28ba82SAppaRao Puli 3466fd29553SEd Tanous boost::system::result<boost::urls::url> url = 347a716aa74SEd Tanous boost::urls::parse_absolute_uri(destUrl); 348a716aa74SEd Tanous if (!url) 349e5aaf047SAppaRao Puli { 350bd79bce8SPatrick Williams BMCWEB_LOG_WARNING( 351bd79bce8SPatrick Williams "Failed to validate and split destination url"); 352e5aaf047SAppaRao Puli messages::propertyValueFormatError(asyncResp->res, destUrl, 353e5aaf047SAppaRao Puli "Destination"); 354e5aaf047SAppaRao Puli return; 355e5aaf047SAppaRao Puli } 356a716aa74SEd Tanous url->normalize(); 357a716aa74SEd Tanous crow::utility::setProtocolDefaults(*url, protocol); 358a716aa74SEd Tanous crow::utility::setPortDefaults(*url); 359a716aa74SEd Tanous 360a716aa74SEd Tanous if (url->path().empty()) 361a716aa74SEd Tanous { 362a716aa74SEd Tanous url->set_path("/"); 363a716aa74SEd Tanous } 364a716aa74SEd Tanous 365a716aa74SEd Tanous if (url->has_userinfo()) 366a716aa74SEd Tanous { 367a716aa74SEd Tanous messages::propertyValueFormatError(asyncResp->res, destUrl, 368a716aa74SEd Tanous "Destination"); 369a716aa74SEd Tanous return; 370a716aa74SEd Tanous } 371b52664e2SAppaRao Puli 3723d30708fSChicago Duan if (protocol == "SNMPv2c") 3733d30708fSChicago Duan { 3743d30708fSChicago Duan if (context) 3753d30708fSChicago Duan { 3763d30708fSChicago Duan messages::propertyValueConflict(asyncResp->res, "Context", 3773d30708fSChicago Duan "Protocol"); 3783d30708fSChicago Duan return; 3793d30708fSChicago Duan } 3803d30708fSChicago Duan if (eventFormatType2) 3813d30708fSChicago Duan { 382bd79bce8SPatrick Williams messages::propertyValueConflict( 383bd79bce8SPatrick Williams asyncResp->res, "EventFormatType", "Protocol"); 3843d30708fSChicago Duan return; 3853d30708fSChicago Duan } 3863d30708fSChicago Duan if (retryPolicy) 3873d30708fSChicago Duan { 388bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 389bd79bce8SPatrick Williams "RetryPolicy", "Protocol"); 3903d30708fSChicago Duan return; 3913d30708fSChicago Duan } 3923d30708fSChicago Duan if (msgIds) 3933d30708fSChicago Duan { 394bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 395bd79bce8SPatrick Williams "MessageIds", "Protocol"); 3963d30708fSChicago Duan return; 3973d30708fSChicago Duan } 3983d30708fSChicago Duan if (regPrefixes) 3993d30708fSChicago Duan { 400bd79bce8SPatrick Williams messages::propertyValueConflict( 401bd79bce8SPatrick Williams asyncResp->res, "RegistryPrefixes", "Protocol"); 4023d30708fSChicago Duan return; 4033d30708fSChicago Duan } 4043d30708fSChicago Duan if (resTypes) 4053d30708fSChicago Duan { 406bd79bce8SPatrick Williams messages::propertyValueConflict( 407bd79bce8SPatrick Williams asyncResp->res, "ResourceTypes", "Protocol"); 4083d30708fSChicago Duan return; 4093d30708fSChicago Duan } 4103d30708fSChicago Duan if (headers) 4113d30708fSChicago Duan { 412bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 413bd79bce8SPatrick Williams "HttpHeaders", "Protocol"); 4143d30708fSChicago Duan return; 4153d30708fSChicago Duan } 4163d30708fSChicago Duan if (mrdJsonArray) 4173d30708fSChicago Duan { 4183d30708fSChicago Duan messages::propertyValueConflict( 4193d30708fSChicago Duan asyncResp->res, "MetricReportDefinitions", "Protocol"); 4203d30708fSChicago Duan return; 4213d30708fSChicago Duan } 422a716aa74SEd Tanous if (url->scheme() != "snmp") 423a716aa74SEd Tanous { 424bd79bce8SPatrick Williams messages::propertyValueConflict(asyncResp->res, 425bd79bce8SPatrick Williams "Destination", "Protocol"); 4263d30708fSChicago Duan return; 4273d30708fSChicago Duan } 4283d30708fSChicago Duan 429a716aa74SEd Tanous addSnmpTrapClient(asyncResp, url->host_address(), 430a716aa74SEd Tanous url->port_number()); 431a716aa74SEd Tanous return; 432b52664e2SAppaRao Puli } 4333d30708fSChicago Duan 434a716aa74SEd Tanous std::shared_ptr<Subscription> subValue = 435a716aa74SEd Tanous std::make_shared<Subscription>(*url, app.ioContext()); 436b52664e2SAppaRao Puli 4374b712a29SEd Tanous subValue->userSub.destinationUrl = std::move(*url); 438e5aaf047SAppaRao Puli 439e5aaf047SAppaRao Puli if (subscriptionType) 440e5aaf047SAppaRao Puli { 441e5aaf047SAppaRao Puli if (*subscriptionType != "RedfishEvent") 442e5aaf047SAppaRao Puli { 443fffb8c1fSEd Tanous messages::propertyValueNotInList( 444fffb8c1fSEd Tanous asyncResp->res, *subscriptionType, "SubscriptionType"); 445e5aaf047SAppaRao Puli return; 446e5aaf047SAppaRao Puli } 4474b712a29SEd Tanous subValue->userSub.subscriptionType = *subscriptionType; 448e5aaf047SAppaRao Puli } 449e5aaf047SAppaRao Puli else 450e5aaf047SAppaRao Puli { 4514b712a29SEd Tanous // Default 4524b712a29SEd Tanous subValue->userSub.subscriptionType = "RedfishEvent"; 453e5aaf047SAppaRao Puli } 454e5aaf047SAppaRao Puli 455e5aaf047SAppaRao Puli if (protocol != "Redfish") 456e5aaf047SAppaRao Puli { 457e5aaf047SAppaRao Puli messages::propertyValueNotInList(asyncResp->res, protocol, 458e5aaf047SAppaRao Puli "Protocol"); 459e5aaf047SAppaRao Puli return; 460e5aaf047SAppaRao Puli } 4614b712a29SEd Tanous subValue->userSub.protocol = protocol; 462e5aaf047SAppaRao Puli 46319bb362bSEd Tanous if (verifyCertificate) 46419bb362bSEd Tanous { 4654b712a29SEd Tanous subValue->userSub.verifyCertificate = *verifyCertificate; 46619bb362bSEd Tanous } 46719bb362bSEd Tanous 46823a21a1cSEd Tanous if (eventFormatType2) 469e5aaf047SAppaRao Puli { 470bd79bce8SPatrick Williams if (std::ranges::find(supportedEvtFormatTypes, 471bd79bce8SPatrick Williams *eventFormatType2) == 4723544d2a7SEd Tanous supportedEvtFormatTypes.end()) 473e5aaf047SAppaRao Puli { 474fffb8c1fSEd Tanous messages::propertyValueNotInList( 475fffb8c1fSEd Tanous asyncResp->res, *eventFormatType2, "EventFormatType"); 476e5aaf047SAppaRao Puli return; 477e5aaf047SAppaRao Puli } 4784b712a29SEd Tanous subValue->userSub.eventFormatType = *eventFormatType2; 479e5aaf047SAppaRao Puli } 480e5aaf047SAppaRao Puli else 481e5aaf047SAppaRao Puli { 482e5aaf047SAppaRao Puli // If not specified, use default "Event" 4834b712a29SEd Tanous subValue->userSub.eventFormatType = "Event"; 484e5aaf047SAppaRao Puli } 485e5aaf047SAppaRao Puli 486e5aaf047SAppaRao Puli if (context) 487e5aaf047SAppaRao Puli { 4888ece0e45SEd Tanous // This value is selected arbitrarily. 489600af5f1SAppaRao Puli constexpr const size_t maxContextSize = 256; 490600af5f1SAppaRao Puli if (context->size() > maxContextSize) 491600af5f1SAppaRao Puli { 492600af5f1SAppaRao Puli messages::stringValueTooLong(asyncResp->res, "Context", 493600af5f1SAppaRao Puli maxContextSize); 494600af5f1SAppaRao Puli return; 495600af5f1SAppaRao Puli } 4964b712a29SEd Tanous subValue->userSub.customText = *context; 497e5aaf047SAppaRao Puli } 498e5aaf047SAppaRao Puli 499e5aaf047SAppaRao Puli if (headers) 500e5aaf047SAppaRao Puli { 501600af5f1SAppaRao Puli size_t cumulativeLen = 0; 502600af5f1SAppaRao Puli 50378d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 504601c71aeSEd Tanous { 50578d4ec4fSEd Tanous for (const auto& item : headerChunk) 50678d4ec4fSEd Tanous { 50778d4ec4fSEd Tanous const std::string* value = 50878d4ec4fSEd Tanous item.second.get_ptr<const std::string*>(); 50978d4ec4fSEd Tanous if (value == nullptr) 51078d4ec4fSEd Tanous { 51178d4ec4fSEd Tanous messages::propertyValueFormatError( 51278d4ec4fSEd Tanous asyncResp->res, item.second, 51378d4ec4fSEd Tanous "HttpHeaders/" + item.first); 51478d4ec4fSEd Tanous return; 51578d4ec4fSEd Tanous } 51678d4ec4fSEd Tanous // Adding a new json value is the size of the key, + 51778d4ec4fSEd Tanous // the size of the value + 2 * 2 quotes for each, + 51878d4ec4fSEd Tanous // the colon and space between. example: 51978d4ec4fSEd Tanous // "key": "value" 52078d4ec4fSEd Tanous cumulativeLen += item.first.size() + value->size() + 6; 521600af5f1SAppaRao Puli // This value is selected to mirror http_connection.hpp 522600af5f1SAppaRao Puli constexpr const uint16_t maxHeaderSizeED = 8096; 523600af5f1SAppaRao Puli if (cumulativeLen > maxHeaderSizeED) 524600af5f1SAppaRao Puli { 52578d4ec4fSEd Tanous messages::arraySizeTooLong( 52678d4ec4fSEd Tanous asyncResp->res, "HttpHeaders", maxHeaderSizeED); 527600af5f1SAppaRao Puli return; 528600af5f1SAppaRao Puli } 5294b712a29SEd Tanous subValue->userSub.httpHeaders.set(item.first, *value); 530601c71aeSEd Tanous } 531601c71aeSEd Tanous } 532e5aaf047SAppaRao Puli } 533e5aaf047SAppaRao Puli 534e5aaf047SAppaRao Puli if (regPrefixes) 535e5aaf047SAppaRao Puli { 536e5aaf047SAppaRao Puli for (const std::string& it : *regPrefixes) 537e5aaf047SAppaRao Puli { 5383544d2a7SEd Tanous if (std::ranges::find(supportedRegPrefixes, it) == 5393544d2a7SEd Tanous supportedRegPrefixes.end()) 540e5aaf047SAppaRao Puli { 541fffb8c1fSEd Tanous messages::propertyValueNotInList(asyncResp->res, it, 542fffb8c1fSEd Tanous "RegistryPrefixes"); 543e5aaf047SAppaRao Puli return; 544e5aaf047SAppaRao Puli } 545e5aaf047SAppaRao Puli } 5464b712a29SEd Tanous subValue->userSub.registryPrefixes = *regPrefixes; 547e5aaf047SAppaRao Puli } 548e5aaf047SAppaRao Puli 549a14c9113SEd Tanous if (originResources) 550a14c9113SEd Tanous { 5514b712a29SEd Tanous subValue->userSub.originResources = *originResources; 552a14c9113SEd Tanous } 553a14c9113SEd Tanous 554e56f254cSSunitha Harish if (resTypes) 555e56f254cSSunitha Harish { 556e56f254cSSunitha Harish for (const std::string& it : *resTypes) 557e56f254cSSunitha Harish { 5583544d2a7SEd Tanous if (std::ranges::find(supportedResourceTypes, it) == 5593544d2a7SEd Tanous supportedResourceTypes.end()) 560e56f254cSSunitha Harish { 561e56f254cSSunitha Harish messages::propertyValueNotInList(asyncResp->res, it, 562e56f254cSSunitha Harish "ResourceTypes"); 563e56f254cSSunitha Harish return; 564e56f254cSSunitha Harish } 565e56f254cSSunitha Harish } 5664b712a29SEd Tanous subValue->userSub.resourceTypes = *resTypes; 567e56f254cSSunitha Harish } 568e56f254cSSunitha Harish 569e5aaf047SAppaRao Puli if (msgIds) 570e5aaf047SAppaRao Puli { 571b304bd79SP Dheeraj Srujan Kumar std::vector<std::string> registryPrefix; 572b304bd79SP Dheeraj Srujan Kumar 5737e860f15SJohn Edward Broadbent // If no registry prefixes are mentioned, consider all 5747e860f15SJohn Edward Broadbent // supported prefixes 5754b712a29SEd Tanous if (subValue->userSub.registryPrefixes.empty()) 576b304bd79SP Dheeraj Srujan Kumar { 577b304bd79SP Dheeraj Srujan Kumar registryPrefix.assign(supportedRegPrefixes.begin(), 578b304bd79SP Dheeraj Srujan Kumar supportedRegPrefixes.end()); 579b304bd79SP Dheeraj Srujan Kumar } 580b304bd79SP Dheeraj Srujan Kumar else 581b304bd79SP Dheeraj Srujan Kumar { 5824b712a29SEd Tanous registryPrefix = subValue->userSub.registryPrefixes; 583b304bd79SP Dheeraj Srujan Kumar } 584b304bd79SP Dheeraj Srujan Kumar 585b304bd79SP Dheeraj Srujan Kumar for (const std::string& id : *msgIds) 586b304bd79SP Dheeraj Srujan Kumar { 587b304bd79SP Dheeraj Srujan Kumar bool validId = false; 588b304bd79SP Dheeraj Srujan Kumar 589b304bd79SP Dheeraj Srujan Kumar // Check for Message ID in each of the selected Registry 590b304bd79SP Dheeraj Srujan Kumar for (const std::string& it : registryPrefix) 591b304bd79SP Dheeraj Srujan Kumar { 592fffb8c1fSEd Tanous const std::span<const redfish::registries::MessageEntry> 593fffb8c1fSEd Tanous registry = 594fffb8c1fSEd Tanous redfish::registries::getRegistryFromPrefix(it); 595b304bd79SP Dheeraj Srujan Kumar 5963544d2a7SEd Tanous if (std::ranges::any_of( 5973544d2a7SEd Tanous registry, 598fffb8c1fSEd Tanous [&id](const redfish::registries::MessageEntry& 599fffb8c1fSEd Tanous messageEntry) { 60055f79e6fSEd Tanous return id == messageEntry.first; 601b304bd79SP Dheeraj Srujan Kumar })) 602b304bd79SP Dheeraj Srujan Kumar { 603b304bd79SP Dheeraj Srujan Kumar validId = true; 604b304bd79SP Dheeraj Srujan Kumar break; 605b304bd79SP Dheeraj Srujan Kumar } 606b304bd79SP Dheeraj Srujan Kumar } 607b304bd79SP Dheeraj Srujan Kumar 608b304bd79SP Dheeraj Srujan Kumar if (!validId) 609b304bd79SP Dheeraj Srujan Kumar { 610b304bd79SP Dheeraj Srujan Kumar messages::propertyValueNotInList(asyncResp->res, id, 611b304bd79SP Dheeraj Srujan Kumar "MessageIds"); 612b304bd79SP Dheeraj Srujan Kumar return; 613b304bd79SP Dheeraj Srujan Kumar } 614b304bd79SP Dheeraj Srujan Kumar } 615b304bd79SP Dheeraj Srujan Kumar 6164b712a29SEd Tanous subValue->userSub.registryMsgIds = *msgIds; 617e5aaf047SAppaRao Puli } 618e5aaf047SAppaRao Puli 619e5aaf047SAppaRao Puli if (retryPolicy) 620e5aaf047SAppaRao Puli { 6213544d2a7SEd Tanous if (std::ranges::find(supportedRetryPolicies, *retryPolicy) == 6223544d2a7SEd Tanous supportedRetryPolicies.end()) 623e5aaf047SAppaRao Puli { 624bd79bce8SPatrick Williams messages::propertyValueNotInList( 625bd79bce8SPatrick Williams asyncResp->res, *retryPolicy, "DeliveryRetryPolicy"); 626e5aaf047SAppaRao Puli return; 627e5aaf047SAppaRao Puli } 6284b712a29SEd Tanous subValue->userSub.retryPolicy = *retryPolicy; 629e5aaf047SAppaRao Puli } 630e5aaf047SAppaRao Puli else 631e5aaf047SAppaRao Puli { 632e5aaf047SAppaRao Puli // Default "TerminateAfterRetries" 6334b712a29SEd Tanous subValue->userSub.retryPolicy = "TerminateAfterRetries"; 634e5aaf047SAppaRao Puli } 635e5aaf047SAppaRao Puli 636144b6318SAppaRao Puli if (mrdJsonArray) 637156d6b00SAppaRao Puli { 63878d4ec4fSEd Tanous for (nlohmann::json::object_t& mrdObj : *mrdJsonArray) 639144b6318SAppaRao Puli { 640144b6318SAppaRao Puli std::string mrdUri; 641ea2e6eecSWilly Tu 64278d4ec4fSEd Tanous if (!json_util::readJsonObject(mrdObj, asyncResp->res, 64378d4ec4fSEd Tanous "@odata.id", mrdUri)) 644ea2e6eecSWilly Tu 645144b6318SAppaRao Puli { 646144b6318SAppaRao Puli return; 647144b6318SAppaRao Puli } 6484b712a29SEd Tanous subValue->userSub.metricReportDefinitions.emplace_back( 6494b712a29SEd Tanous mrdUri); 650144b6318SAppaRao Puli } 651156d6b00SAppaRao Puli } 652156d6b00SAppaRao Puli 653b52664e2SAppaRao Puli std::string id = 654bd79bce8SPatrick Williams EventServiceManager::getInstance().addPushSubscription( 655bd79bce8SPatrick Williams subValue); 656b52664e2SAppaRao Puli if (id.empty()) 657e5aaf047SAppaRao Puli { 658e5aaf047SAppaRao Puli messages::internalError(asyncResp->res); 659e5aaf047SAppaRao Puli return; 660e5aaf047SAppaRao Puli } 661e5aaf047SAppaRao Puli 662e5aaf047SAppaRao Puli messages::created(asyncResp->res); 663e5aaf047SAppaRao Puli asyncResp->res.addHeader( 664e5aaf047SAppaRao Puli "Location", "/redfish/v1/EventService/Subscriptions/" + id); 6657e860f15SJohn Edward Broadbent }); 666e5aaf047SAppaRao Puli } 667e5aaf047SAppaRao Puli 6687e860f15SJohn Edward Broadbent inline void requestRoutesEventDestination(App& app) 669e5aaf047SAppaRao Puli { 6709d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 671ed398213SEd Tanous .privileges(redfish::privileges::getEventDestination) 6727e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 67345ca1b86SEd Tanous [&app](const crow::Request& req, 6747e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 6757e860f15SJohn Edward Broadbent const std::string& param) { 6763ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 67745ca1b86SEd Tanous { 67845ca1b86SEd Tanous return; 67945ca1b86SEd Tanous } 6803d30708fSChicago Duan 6813d30708fSChicago Duan if (param.starts_with("snmp")) 6823d30708fSChicago Duan { 6833d30708fSChicago Duan getSnmpTrapClient(asyncResp, param); 6843d30708fSChicago Duan return; 6853d30708fSChicago Duan } 6863d30708fSChicago Duan 687b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 6887e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 689b52664e2SAppaRao Puli if (subValue == nullptr) 690e5aaf047SAppaRao Puli { 691bd79bce8SPatrick Williams asyncResp->res.result( 692bd79bce8SPatrick Williams boost::beast::http::status::not_found); 693e5aaf047SAppaRao Puli return; 694e5aaf047SAppaRao Puli } 6957e860f15SJohn Edward Broadbent const std::string& id = param; 696e5aaf047SAppaRao Puli 6974b712a29SEd Tanous const persistent_data::UserSubscription& userSub = 6984b712a29SEd Tanous subValue->userSub; 699e56f254cSSunitha Harish 7004b712a29SEd Tanous nlohmann::json& jVal = asyncResp->res.jsonValue; 7014b712a29SEd Tanous jVal["@odata.type"] = 7024b712a29SEd Tanous "#EventDestination.v1_14_1.EventDestination"; 7034b712a29SEd Tanous jVal["Protocol"] = 7044b712a29SEd Tanous event_destination::EventDestinationProtocol::Redfish; 7054b712a29SEd Tanous jVal["@odata.id"] = boost::urls::format( 7064b712a29SEd Tanous "/redfish/v1/EventService/Subscriptions/{}", id); 7074b712a29SEd Tanous jVal["Id"] = id; 7084b712a29SEd Tanous jVal["Name"] = "Event Destination " + id; 7094b712a29SEd Tanous jVal["Destination"] = userSub.destinationUrl; 7104b712a29SEd Tanous jVal["Context"] = userSub.customText; 7114b712a29SEd Tanous jVal["SubscriptionType"] = userSub.subscriptionType; 7124b712a29SEd Tanous jVal["HttpHeaders"] = nlohmann::json::array(); 7134b712a29SEd Tanous jVal["EventFormatType"] = userSub.eventFormatType; 7144b712a29SEd Tanous jVal["RegistryPrefixes"] = userSub.registryPrefixes; 7154b712a29SEd Tanous jVal["ResourceTypes"] = userSub.resourceTypes; 7164b712a29SEd Tanous 7174b712a29SEd Tanous jVal["MessageIds"] = userSub.registryMsgIds; 7184b712a29SEd Tanous jVal["DeliveryRetryPolicy"] = userSub.retryPolicy; 7194b712a29SEd Tanous jVal["VerifyCertificate"] = userSub.verifyCertificate; 720144b6318SAppaRao Puli 7211476687dSEd Tanous nlohmann::json::array_t mrdJsonArray; 7224b712a29SEd Tanous for (const auto& mdrUri : userSub.metricReportDefinitions) 723144b6318SAppaRao Puli { 7241476687dSEd Tanous nlohmann::json::object_t mdr; 7251476687dSEd Tanous mdr["@odata.id"] = mdrUri; 7261476687dSEd Tanous mrdJsonArray.emplace_back(std::move(mdr)); 727144b6318SAppaRao Puli } 7284b712a29SEd Tanous jVal["MetricReportDefinitions"] = mrdJsonArray; 7297e860f15SJohn Edward Broadbent }); 7309d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 731ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 732ed398213SEd Tanous // ConfigureSelf 7337eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 734ed398213SEd Tanous //.privileges(redfish::privileges::patchEventDestination) 735432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 7367e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::patch)( 73745ca1b86SEd Tanous [&app](const crow::Request& req, 7387e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7397e860f15SJohn Edward Broadbent const std::string& param) { 7403ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 74145ca1b86SEd Tanous { 74245ca1b86SEd Tanous return; 74345ca1b86SEd Tanous } 744b52664e2SAppaRao Puli std::shared_ptr<Subscription> subValue = 7457e860f15SJohn Edward Broadbent EventServiceManager::getInstance().getSubscription(param); 746b52664e2SAppaRao Puli if (subValue == nullptr) 747e5aaf047SAppaRao Puli { 748bd79bce8SPatrick Williams asyncResp->res.result( 749bd79bce8SPatrick Williams boost::beast::http::status::not_found); 750e5aaf047SAppaRao Puli return; 751e5aaf047SAppaRao Puli } 752e5aaf047SAppaRao Puli 753e5aaf047SAppaRao Puli std::optional<std::string> context; 754e5aaf047SAppaRao Puli std::optional<std::string> retryPolicy; 75519bb362bSEd Tanous std::optional<bool> verifyCertificate; 75678d4ec4fSEd Tanous std::optional<std::vector<nlohmann::json::object_t>> headers; 757e5aaf047SAppaRao Puli 758*afc474aeSMyung Bae if (!json_util::readJsonPatch( // 759*afc474aeSMyung Bae req, asyncResp->res, // 760*afc474aeSMyung Bae "Context", context, // 761*afc474aeSMyung Bae "DeliveryRetryPolicy", retryPolicy, // 762*afc474aeSMyung Bae "HttpHeaders", headers, // 763*afc474aeSMyung Bae "VerifyCertificate", verifyCertificate // 764*afc474aeSMyung Bae )) 765e5aaf047SAppaRao Puli { 766e5aaf047SAppaRao Puli return; 767e5aaf047SAppaRao Puli } 768e5aaf047SAppaRao Puli 769e5aaf047SAppaRao Puli if (context) 770e5aaf047SAppaRao Puli { 7714b712a29SEd Tanous subValue->userSub.customText = *context; 772e5aaf047SAppaRao Puli } 773e5aaf047SAppaRao Puli 774e5aaf047SAppaRao Puli if (headers) 775e5aaf047SAppaRao Puli { 776601c71aeSEd Tanous boost::beast::http::fields fields; 77778d4ec4fSEd Tanous for (const nlohmann::json::object_t& headerChunk : *headers) 778601c71aeSEd Tanous { 77978d4ec4fSEd Tanous for (const auto& it : headerChunk) 780601c71aeSEd Tanous { 781601c71aeSEd Tanous const std::string* value = 78278d4ec4fSEd Tanous it.second.get_ptr<const std::string*>(); 783601c71aeSEd Tanous if (value == nullptr) 784601c71aeSEd Tanous { 785601c71aeSEd Tanous messages::propertyValueFormatError( 78678d4ec4fSEd Tanous asyncResp->res, it.second, 78778d4ec4fSEd Tanous "HttpHeaders/" + it.first); 788601c71aeSEd Tanous return; 789601c71aeSEd Tanous } 79078d4ec4fSEd Tanous fields.set(it.first, *value); 791601c71aeSEd Tanous } 792601c71aeSEd Tanous } 7934b712a29SEd Tanous subValue->userSub.httpHeaders = std::move(fields); 794e5aaf047SAppaRao Puli } 795e5aaf047SAppaRao Puli 796e5aaf047SAppaRao Puli if (retryPolicy) 797e5aaf047SAppaRao Puli { 798bd79bce8SPatrick Williams if (std::ranges::find(supportedRetryPolicies, 799bd79bce8SPatrick Williams *retryPolicy) == 8003544d2a7SEd Tanous supportedRetryPolicies.end()) 801e5aaf047SAppaRao Puli { 802bd79bce8SPatrick Williams messages::propertyValueNotInList(asyncResp->res, 803bd79bce8SPatrick Williams *retryPolicy, 804e5aaf047SAppaRao Puli "DeliveryRetryPolicy"); 805e5aaf047SAppaRao Puli return; 806e5aaf047SAppaRao Puli } 8074b712a29SEd Tanous subValue->userSub.retryPolicy = *retryPolicy; 808e5aaf047SAppaRao Puli } 809e5aaf047SAppaRao Puli 81019bb362bSEd Tanous if (verifyCertificate) 81119bb362bSEd Tanous { 8124b712a29SEd Tanous subValue->userSub.verifyCertificate = *verifyCertificate; 81319bb362bSEd Tanous } 81419bb362bSEd Tanous 815b52664e2SAppaRao Puli EventServiceManager::getInstance().updateSubscriptionData(); 8167e860f15SJohn Edward Broadbent }); 8179d41aec6SRavi Teja BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/") 818ed398213SEd Tanous // The below privilege is wrong, it should be ConfigureManager OR 819ed398213SEd Tanous // ConfigureSelf 8207eeafa76SAbhishek Patel // https://github.com/openbmc/bmcweb/issues/220 821ed398213SEd Tanous //.privileges(redfish::privileges::deleteEventDestination) 822432a890cSEd Tanous .privileges({{"ConfigureManager"}}) 8237e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 82445ca1b86SEd Tanous [&app](const crow::Request& req, 8257e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8267e860f15SJohn Edward Broadbent const std::string& param) { 8273ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 82845ca1b86SEd Tanous { 82945ca1b86SEd Tanous return; 83045ca1b86SEd Tanous } 8314b712a29SEd Tanous EventServiceManager& event = EventServiceManager::getInstance(); 8323d30708fSChicago Duan if (param.starts_with("snmp")) 8333d30708fSChicago Duan { 8343d30708fSChicago Duan deleteSnmpTrapClient(asyncResp, param); 8354b712a29SEd Tanous event.deleteSubscription(param); 8363d30708fSChicago Duan return; 8373d30708fSChicago Duan } 8383d30708fSChicago Duan 8394b712a29SEd Tanous if (!event.deleteSubscription(param)) 840e5aaf047SAppaRao Puli { 8414b712a29SEd Tanous messages::resourceNotFound(asyncResp->res, 8424b712a29SEd Tanous "EventDestination", param); 843e5aaf047SAppaRao Puli return; 844e5aaf047SAppaRao Puli } 8454b712a29SEd Tanous messages::success(asyncResp->res); 8467e860f15SJohn Edward Broadbent }); 847e5aaf047SAppaRao Puli } 848e5aaf047SAppaRao Puli 849e5aaf047SAppaRao Puli } // namespace redfish 850