1081ebf06SWludzik, Jozef #pragma once 2081ebf06SWludzik, Jozef 34dbb8aeaSWludzik, Jozef #include "sensors.hpp" 4081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp" 5081ebf06SWludzik, Jozef #include "utils/time_utils.hpp" 6081ebf06SWludzik, Jozef 77e860f15SJohn Edward Broadbent #include <app.hpp> 84dbb8aeaSWludzik, Jozef #include <boost/container/flat_map.hpp> 9168e20c1SEd Tanous #include <dbus_utility.hpp> 1045ca1b86SEd Tanous #include <query.hpp> 11ed398213SEd Tanous #include <registries/privilege_registry.hpp> 124dbb8aeaSWludzik, Jozef 13081ebf06SWludzik, Jozef #include <tuple> 14081ebf06SWludzik, Jozef #include <variant> 15081ebf06SWludzik, Jozef 16081ebf06SWludzik, Jozef namespace redfish 17081ebf06SWludzik, Jozef { 18081ebf06SWludzik, Jozef 19081ebf06SWludzik, Jozef namespace telemetry 20081ebf06SWludzik, Jozef { 21081ebf06SWludzik, Jozef 22456cd875SSzymon Dompke constexpr const char* metricReportDefinitionUri = 23456cd875SSzymon Dompke "/redfish/v1/TelemetryService/MetricReportDefinitions"; 24456cd875SSzymon Dompke 25081ebf06SWludzik, Jozef using ReadingParameters = 26081ebf06SWludzik, Jozef std::vector<std::tuple<sdbusplus::message::object_path, std::string, 27081ebf06SWludzik, Jozef std::string, std::string>>; 28081ebf06SWludzik, Jozef 29b9d36b47SEd Tanous inline void 30b9d36b47SEd Tanous fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31b9d36b47SEd Tanous const std::string& id, 32b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& ret) 33081ebf06SWludzik, Jozef { 34081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.type"] = 35081ebf06SWludzik, Jozef "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; 36081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.id"] = 37456cd875SSzymon Dompke crow::utility::urlFromPieces("redfish", "v1", "TelemetryService", 38456cd875SSzymon Dompke "MetricReportDefinitions", id) 39456cd875SSzymon Dompke .string(); 40081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Id"] = id; 41081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Name"] = id; 42081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = 43456cd875SSzymon Dompke crow::utility::urlFromPieces("redfish", "v1", "TelemetryService", 44456cd875SSzymon Dompke "MetricReports", id) 45456cd875SSzymon Dompke .string(); 46081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 47081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; 48081ebf06SWludzik, Jozef 49081ebf06SWludzik, Jozef const bool* emitsReadingsUpdate = nullptr; 50081ebf06SWludzik, Jozef const bool* logToMetricReportsCollection = nullptr; 51081ebf06SWludzik, Jozef const ReadingParameters* readingParams = nullptr; 52081ebf06SWludzik, Jozef const std::string* reportingType = nullptr; 53081ebf06SWludzik, Jozef const uint64_t* interval = nullptr; 54081ebf06SWludzik, Jozef for (const auto& [key, var] : ret) 55081ebf06SWludzik, Jozef { 56081ebf06SWludzik, Jozef if (key == "EmitsReadingsUpdate") 57081ebf06SWludzik, Jozef { 58081ebf06SWludzik, Jozef emitsReadingsUpdate = std::get_if<bool>(&var); 59081ebf06SWludzik, Jozef } 60081ebf06SWludzik, Jozef else if (key == "LogToMetricReportsCollection") 61081ebf06SWludzik, Jozef { 62081ebf06SWludzik, Jozef logToMetricReportsCollection = std::get_if<bool>(&var); 63081ebf06SWludzik, Jozef } 64081ebf06SWludzik, Jozef else if (key == "ReadingParameters") 65081ebf06SWludzik, Jozef { 66081ebf06SWludzik, Jozef readingParams = std::get_if<ReadingParameters>(&var); 67081ebf06SWludzik, Jozef } 68081ebf06SWludzik, Jozef else if (key == "ReportingType") 69081ebf06SWludzik, Jozef { 70081ebf06SWludzik, Jozef reportingType = std::get_if<std::string>(&var); 71081ebf06SWludzik, Jozef } 72081ebf06SWludzik, Jozef else if (key == "Interval") 73081ebf06SWludzik, Jozef { 74081ebf06SWludzik, Jozef interval = std::get_if<uint64_t>(&var); 75081ebf06SWludzik, Jozef } 76081ebf06SWludzik, Jozef } 77e662eae8SEd Tanous if (emitsReadingsUpdate == nullptr || 78e662eae8SEd Tanous logToMetricReportsCollection == nullptr || readingParams == nullptr || 79e662eae8SEd Tanous reportingType == nullptr || interval == nullptr) 80081ebf06SWludzik, Jozef { 81081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; 82081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 83081ebf06SWludzik, Jozef return; 84081ebf06SWludzik, Jozef } 85081ebf06SWludzik, Jozef 86081ebf06SWludzik, Jozef std::vector<std::string> redfishReportActions; 87081ebf06SWludzik, Jozef redfishReportActions.reserve(2); 88081ebf06SWludzik, Jozef if (*emitsReadingsUpdate) 89081ebf06SWludzik, Jozef { 90081ebf06SWludzik, Jozef redfishReportActions.emplace_back("RedfishEvent"); 91081ebf06SWludzik, Jozef } 92081ebf06SWludzik, Jozef if (*logToMetricReportsCollection) 93081ebf06SWludzik, Jozef { 94081ebf06SWludzik, Jozef redfishReportActions.emplace_back("LogToMetricReportsCollection"); 95081ebf06SWludzik, Jozef } 96081ebf06SWludzik, Jozef 97081ebf06SWludzik, Jozef nlohmann::json metrics = nlohmann::json::array(); 989eb808c1SEd Tanous for (const auto& [sensorPath, operationType, id, metadata] : *readingParams) 99081ebf06SWludzik, Jozef { 100081ebf06SWludzik, Jozef metrics.push_back({ 101081ebf06SWludzik, Jozef {"MetricId", id}, 102081ebf06SWludzik, Jozef {"MetricProperties", {metadata}}, 103081ebf06SWludzik, Jozef }); 104081ebf06SWludzik, Jozef } 105081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Metrics"] = metrics; 106081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; 107081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; 108081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = 109081ebf06SWludzik, Jozef time_utils::toDurationString(std::chrono::milliseconds(*interval)); 110081ebf06SWludzik, Jozef } 1114dbb8aeaSWludzik, Jozef 1124dbb8aeaSWludzik, Jozef struct AddReportArgs 1134dbb8aeaSWludzik, Jozef { 1144dbb8aeaSWludzik, Jozef std::string name; 1154dbb8aeaSWludzik, Jozef std::string reportingType; 1164dbb8aeaSWludzik, Jozef bool emitsReadingsUpdate = false; 1174dbb8aeaSWludzik, Jozef bool logToMetricReportsCollection = false; 1184dbb8aeaSWludzik, Jozef uint64_t interval = 0; 1194dbb8aeaSWludzik, Jozef std::vector<std::pair<std::string, std::vector<std::string>>> metrics; 1204dbb8aeaSWludzik, Jozef }; 1214dbb8aeaSWludzik, Jozef 1224dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res, 1234dbb8aeaSWludzik, Jozef std::vector<std::string>& actions, 1244dbb8aeaSWludzik, Jozef AddReportArgs& args) 1254dbb8aeaSWludzik, Jozef { 1264dbb8aeaSWludzik, Jozef size_t index = 0; 1274dbb8aeaSWludzik, Jozef for (auto& action : actions) 1284dbb8aeaSWludzik, Jozef { 1294dbb8aeaSWludzik, Jozef if (action == "RedfishEvent") 1304dbb8aeaSWludzik, Jozef { 1314dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate = true; 1324dbb8aeaSWludzik, Jozef } 1334dbb8aeaSWludzik, Jozef else if (action == "LogToMetricReportsCollection") 1344dbb8aeaSWludzik, Jozef { 1354dbb8aeaSWludzik, Jozef args.logToMetricReportsCollection = true; 1364dbb8aeaSWludzik, Jozef } 1374dbb8aeaSWludzik, Jozef else 1384dbb8aeaSWludzik, Jozef { 1394dbb8aeaSWludzik, Jozef messages::propertyValueNotInList( 1404dbb8aeaSWludzik, Jozef res, action, "ReportActions/" + std::to_string(index)); 1414dbb8aeaSWludzik, Jozef return false; 1424dbb8aeaSWludzik, Jozef } 1434dbb8aeaSWludzik, Jozef index++; 1444dbb8aeaSWludzik, Jozef } 1454dbb8aeaSWludzik, Jozef return true; 1464dbb8aeaSWludzik, Jozef } 1474dbb8aeaSWludzik, Jozef 1484dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req, 1494dbb8aeaSWludzik, Jozef AddReportArgs& args) 1504dbb8aeaSWludzik, Jozef { 1514dbb8aeaSWludzik, Jozef std::vector<nlohmann::json> metrics; 1524dbb8aeaSWludzik, Jozef std::vector<std::string> reportActions; 1534dbb8aeaSWludzik, Jozef std::optional<nlohmann::json> schedule; 15415ed6780SWilly Tu if (!json_util::readJsonPatch(req, res, "Id", args.name, "Metrics", metrics, 15515ed6780SWilly Tu "MetricReportDefinitionType", 15615ed6780SWilly Tu args.reportingType, "ReportActions", 15715ed6780SWilly Tu reportActions, "Schedule", schedule)) 1584dbb8aeaSWludzik, Jozef { 1594dbb8aeaSWludzik, Jozef return false; 1604dbb8aeaSWludzik, Jozef } 1614dbb8aeaSWludzik, Jozef 1624dbb8aeaSWludzik, Jozef constexpr const char* allowedCharactersInName = 1634dbb8aeaSWludzik, Jozef "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 1644dbb8aeaSWludzik, Jozef if (args.name.empty() || args.name.find_first_not_of( 1654dbb8aeaSWludzik, Jozef allowedCharactersInName) != std::string::npos) 1664dbb8aeaSWludzik, Jozef { 1674dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to match " << args.name 1684dbb8aeaSWludzik, Jozef << " with allowed character " 1694dbb8aeaSWludzik, Jozef << allowedCharactersInName; 1704dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "Id", args.name); 1714dbb8aeaSWludzik, Jozef return false; 1724dbb8aeaSWludzik, Jozef } 1734dbb8aeaSWludzik, Jozef 1744dbb8aeaSWludzik, Jozef if (args.reportingType != "Periodic" && args.reportingType != "OnRequest") 1754dbb8aeaSWludzik, Jozef { 1764dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(res, args.reportingType, 1774dbb8aeaSWludzik, Jozef "MetricReportDefinitionType"); 1784dbb8aeaSWludzik, Jozef return false; 1794dbb8aeaSWludzik, Jozef } 1804dbb8aeaSWludzik, Jozef 1814dbb8aeaSWludzik, Jozef if (!toDbusReportActions(res, reportActions, args)) 1824dbb8aeaSWludzik, Jozef { 1834dbb8aeaSWludzik, Jozef return false; 1844dbb8aeaSWludzik, Jozef } 1854dbb8aeaSWludzik, Jozef 1864dbb8aeaSWludzik, Jozef if (args.reportingType == "Periodic") 1874dbb8aeaSWludzik, Jozef { 1884dbb8aeaSWludzik, Jozef if (!schedule) 1894dbb8aeaSWludzik, Jozef { 1904dbb8aeaSWludzik, Jozef messages::createFailedMissingReqProperties(res, "Schedule"); 1914dbb8aeaSWludzik, Jozef return false; 1924dbb8aeaSWludzik, Jozef } 1934dbb8aeaSWludzik, Jozef 1944dbb8aeaSWludzik, Jozef std::string durationStr; 1954dbb8aeaSWludzik, Jozef if (!json_util::readJson(*schedule, res, "RecurrenceInterval", 1964dbb8aeaSWludzik, Jozef durationStr)) 1974dbb8aeaSWludzik, Jozef { 1984dbb8aeaSWludzik, Jozef return false; 1994dbb8aeaSWludzik, Jozef } 2004dbb8aeaSWludzik, Jozef 2014dbb8aeaSWludzik, Jozef std::optional<std::chrono::milliseconds> durationNum = 2024dbb8aeaSWludzik, Jozef time_utils::fromDurationString(durationStr); 2034dbb8aeaSWludzik, Jozef if (!durationNum) 2044dbb8aeaSWludzik, Jozef { 2054dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "RecurrenceInterval", 2064dbb8aeaSWludzik, Jozef durationStr); 2074dbb8aeaSWludzik, Jozef return false; 2084dbb8aeaSWludzik, Jozef } 2094dbb8aeaSWludzik, Jozef args.interval = static_cast<uint64_t>(durationNum->count()); 2104dbb8aeaSWludzik, Jozef } 2114dbb8aeaSWludzik, Jozef 2124dbb8aeaSWludzik, Jozef args.metrics.reserve(metrics.size()); 2134dbb8aeaSWludzik, Jozef for (auto& m : metrics) 2144dbb8aeaSWludzik, Jozef { 2154dbb8aeaSWludzik, Jozef std::string id; 2164dbb8aeaSWludzik, Jozef std::vector<std::string> uris; 2174dbb8aeaSWludzik, Jozef if (!json_util::readJson(m, res, "MetricId", id, "MetricProperties", 2184dbb8aeaSWludzik, Jozef uris)) 2194dbb8aeaSWludzik, Jozef { 2204dbb8aeaSWludzik, Jozef return false; 2214dbb8aeaSWludzik, Jozef } 2224dbb8aeaSWludzik, Jozef 2234dbb8aeaSWludzik, Jozef args.metrics.emplace_back(std::move(id), std::move(uris)); 2244dbb8aeaSWludzik, Jozef } 2254dbb8aeaSWludzik, Jozef 2264dbb8aeaSWludzik, Jozef return true; 2274dbb8aeaSWludzik, Jozef } 2284dbb8aeaSWludzik, Jozef 229*ca1600c1SSzymon Dompke inline bool getChassisSensorNodeFromMetrics( 2308d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2314dbb8aeaSWludzik, Jozef const std::vector<std::pair<std::string, std::vector<std::string>>>& 2324dbb8aeaSWludzik, Jozef metrics, 2334dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>>& matched) 2344dbb8aeaSWludzik, Jozef { 235*ca1600c1SSzymon Dompke for (const auto& metric : metrics) 2364dbb8aeaSWludzik, Jozef { 237*ca1600c1SSzymon Dompke const std::vector<std::string>& uris = metric.second; 2384dbb8aeaSWludzik, Jozef 239*ca1600c1SSzymon Dompke std::optional<IncorrectMetricUri> error = 240*ca1600c1SSzymon Dompke getChassisSensorNode(uris, matched); 241*ca1600c1SSzymon Dompke if (error) 2424dbb8aeaSWludzik, Jozef { 243*ca1600c1SSzymon Dompke messages::propertyValueIncorrect(asyncResp->res, error->uri, 2444dbb8aeaSWludzik, Jozef "MetricProperties/" + 245*ca1600c1SSzymon Dompke std::to_string(error->index)); 2464dbb8aeaSWludzik, Jozef return false; 2474dbb8aeaSWludzik, Jozef } 2484dbb8aeaSWludzik, Jozef } 2494dbb8aeaSWludzik, Jozef return true; 2504dbb8aeaSWludzik, Jozef } 2514dbb8aeaSWludzik, Jozef 2524dbb8aeaSWludzik, Jozef class AddReport 2534dbb8aeaSWludzik, Jozef { 2544dbb8aeaSWludzik, Jozef public: 2558d1b46d7Szhanghch05 AddReport(AddReportArgs argsIn, 2568d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) : 2578d1b46d7Szhanghch05 asyncResp(asyncResp), 2588d1b46d7Szhanghch05 args{std::move(argsIn)} 2594dbb8aeaSWludzik, Jozef {} 2604dbb8aeaSWludzik, Jozef ~AddReport() 2614dbb8aeaSWludzik, Jozef { 2624dbb8aeaSWludzik, Jozef if (asyncResp->res.result() != boost::beast::http::status::ok) 2634dbb8aeaSWludzik, Jozef { 2644dbb8aeaSWludzik, Jozef return; 2654dbb8aeaSWludzik, Jozef } 2664dbb8aeaSWludzik, Jozef 2674dbb8aeaSWludzik, Jozef telemetry::ReadingParameters readingParams; 2684dbb8aeaSWludzik, Jozef readingParams.reserve(args.metrics.size()); 2694dbb8aeaSWludzik, Jozef 2704dbb8aeaSWludzik, Jozef for (const auto& [id, uris] : args.metrics) 2714dbb8aeaSWludzik, Jozef { 2724dbb8aeaSWludzik, Jozef for (size_t i = 0; i < uris.size(); i++) 2734dbb8aeaSWludzik, Jozef { 2744dbb8aeaSWludzik, Jozef const std::string& uri = uris[i]; 2754dbb8aeaSWludzik, Jozef auto el = uriToDbus.find(uri); 2764dbb8aeaSWludzik, Jozef if (el == uriToDbus.end()) 2774dbb8aeaSWludzik, Jozef { 2780fda0f12SGeorge Liu BMCWEB_LOG_ERROR 2790fda0f12SGeorge Liu << "Failed to find DBus sensor corresponding to URI " 2804dbb8aeaSWludzik, Jozef << uri; 2814dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(asyncResp->res, uri, 2824dbb8aeaSWludzik, Jozef "MetricProperties/" + 2834dbb8aeaSWludzik, Jozef std::to_string(i)); 2844dbb8aeaSWludzik, Jozef return; 2854dbb8aeaSWludzik, Jozef } 2864dbb8aeaSWludzik, Jozef 2874dbb8aeaSWludzik, Jozef const std::string& dbusPath = el->second; 2884dbb8aeaSWludzik, Jozef readingParams.emplace_back(dbusPath, "SINGLE", id, uri); 2894dbb8aeaSWludzik, Jozef } 2904dbb8aeaSWludzik, Jozef } 2918d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> aResp = asyncResp; 2924dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 2938d1b46d7Szhanghch05 [aResp, name = args.name, uriToDbus = std::move(uriToDbus)]( 2944dbb8aeaSWludzik, Jozef const boost::system::error_code ec, const std::string&) { 2954dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::file_exists) 2964dbb8aeaSWludzik, Jozef { 2974dbb8aeaSWludzik, Jozef messages::resourceAlreadyExists( 2988d1b46d7Szhanghch05 aResp->res, "MetricReportDefinition", "Id", name); 2994dbb8aeaSWludzik, Jozef return; 3004dbb8aeaSWludzik, Jozef } 3014dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::too_many_files_open) 3024dbb8aeaSWludzik, Jozef { 3038d1b46d7Szhanghch05 messages::createLimitReachedForResource(aResp->res); 3044dbb8aeaSWludzik, Jozef return; 3054dbb8aeaSWludzik, Jozef } 3064dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::argument_list_too_long) 3074dbb8aeaSWludzik, Jozef { 3084dbb8aeaSWludzik, Jozef nlohmann::json metricProperties = nlohmann::json::array(); 3094dbb8aeaSWludzik, Jozef for (const auto& [uri, _] : uriToDbus) 3104dbb8aeaSWludzik, Jozef { 3114dbb8aeaSWludzik, Jozef metricProperties.emplace_back(uri); 3124dbb8aeaSWludzik, Jozef } 3131668ce6dSEd Tanous messages::propertyValueIncorrect(aResp->res, 3141668ce6dSEd Tanous metricProperties.dump(), 3151668ce6dSEd Tanous "MetricProperties"); 3164dbb8aeaSWludzik, Jozef return; 3174dbb8aeaSWludzik, Jozef } 3184dbb8aeaSWludzik, Jozef if (ec) 3194dbb8aeaSWludzik, Jozef { 3208d1b46d7Szhanghch05 messages::internalError(aResp->res); 3214dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 3224dbb8aeaSWludzik, Jozef return; 3234dbb8aeaSWludzik, Jozef } 3244dbb8aeaSWludzik, Jozef 3258d1b46d7Szhanghch05 messages::created(aResp->res); 3264dbb8aeaSWludzik, Jozef }, 3274dbb8aeaSWludzik, Jozef telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", 3284dbb8aeaSWludzik, Jozef "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", 3294dbb8aeaSWludzik, Jozef "TelemetryService/" + args.name, args.reportingType, 3304dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate, args.logToMetricReportsCollection, 3314dbb8aeaSWludzik, Jozef args.interval, readingParams); 3324dbb8aeaSWludzik, Jozef } 3334dbb8aeaSWludzik, Jozef 334ecd6a3a2SEd Tanous AddReport(const AddReport&) = delete; 335ecd6a3a2SEd Tanous AddReport(AddReport&&) = delete; 336ecd6a3a2SEd Tanous AddReport& operator=(const AddReport&) = delete; 337ecd6a3a2SEd Tanous AddReport& operator=(AddReport&&) = delete; 338ecd6a3a2SEd Tanous 3394dbb8aeaSWludzik, Jozef void insert(const boost::container::flat_map<std::string, std::string>& el) 3404dbb8aeaSWludzik, Jozef { 3414dbb8aeaSWludzik, Jozef uriToDbus.insert(el.begin(), el.end()); 3424dbb8aeaSWludzik, Jozef } 3434dbb8aeaSWludzik, Jozef 3444dbb8aeaSWludzik, Jozef private: 3458d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> asyncResp; 3464dbb8aeaSWludzik, Jozef AddReportArgs args; 3474dbb8aeaSWludzik, Jozef boost::container::flat_map<std::string, std::string> uriToDbus{}; 3484dbb8aeaSWludzik, Jozef }; 349081ebf06SWludzik, Jozef } // namespace telemetry 350081ebf06SWludzik, Jozef 3517e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinitionCollection(App& app) 352081ebf06SWludzik, Jozef { 3537e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 354ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinitionCollection) 3557e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 35645ca1b86SEd Tanous [&app](const crow::Request& req, 3577e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 35845ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 35945ca1b86SEd Tanous { 36045ca1b86SEd Tanous return; 36145ca1b86SEd Tanous } 36245ca1b86SEd Tanous 3638d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3648d1b46d7Szhanghch05 "#MetricReportDefinitionCollection." 365081ebf06SWludzik, Jozef "MetricReportDefinitionCollection"; 3668d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 367456cd875SSzymon Dompke telemetry::metricReportDefinitionUri; 3687e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Name"] = 3697e860f15SJohn Edward Broadbent "Metric Definition Collection"; 3704028ff77SEd Tanous const std::vector<const char*> interfaces{ 3714028ff77SEd Tanous telemetry::reportInterface}; 3724028ff77SEd Tanous collection_util::getCollectionMembers( 3734028ff77SEd Tanous asyncResp, telemetry::metricReportDefinitionUri, interfaces, 3744028ff77SEd Tanous "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"); 3757e860f15SJohn Edward Broadbent }); 3764dbb8aeaSWludzik, Jozef 3777e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 378ed398213SEd Tanous .privileges(redfish::privileges::postMetricReportDefinitionCollection) 3790fda0f12SGeorge Liu .methods( 3800fda0f12SGeorge Liu boost::beast::http::verb:: 38145ca1b86SEd Tanous post)([&app]( 38245ca1b86SEd Tanous const crow::Request& req, 3837e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 38445ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 38545ca1b86SEd Tanous { 38645ca1b86SEd Tanous return; 38745ca1b86SEd Tanous } 38845ca1b86SEd Tanous 3894dbb8aeaSWludzik, Jozef telemetry::AddReportArgs args; 3908d1b46d7Szhanghch05 if (!telemetry::getUserParameters(asyncResp->res, req, args)) 3914dbb8aeaSWludzik, Jozef { 3924dbb8aeaSWludzik, Jozef return; 3934dbb8aeaSWludzik, Jozef } 3944dbb8aeaSWludzik, Jozef 3954dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>> 3964dbb8aeaSWludzik, Jozef chassisSensors; 397*ca1600c1SSzymon Dompke if (!telemetry::getChassisSensorNodeFromMetrics( 398*ca1600c1SSzymon Dompke asyncResp, args.metrics, chassisSensors)) 3994dbb8aeaSWludzik, Jozef { 4004dbb8aeaSWludzik, Jozef return; 4014dbb8aeaSWludzik, Jozef } 4024dbb8aeaSWludzik, Jozef 4037e860f15SJohn Edward Broadbent auto addReportReq = std::make_shared<telemetry::AddReport>( 4047e860f15SJohn Edward Broadbent std::move(args), asyncResp); 4054dbb8aeaSWludzik, Jozef for (const auto& [chassis, sensorType] : chassisSensors) 4064dbb8aeaSWludzik, Jozef { 4074dbb8aeaSWludzik, Jozef retrieveUriToDbusMap( 408021d32cfSKrzysztof Grobelny chassis, sensorType, 4090fda0f12SGeorge Liu [asyncResp, 4100fda0f12SGeorge Liu addReportReq](const boost::beast::http::status status, 4117e860f15SJohn Edward Broadbent const boost::container::flat_map< 4127e860f15SJohn Edward Broadbent std::string, std::string>& uriToDbus) { 4134dbb8aeaSWludzik, Jozef if (status != boost::beast::http::status::ok) 4144dbb8aeaSWludzik, Jozef { 4157e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR 4160fda0f12SGeorge Liu << "Failed to retrieve URI to dbus sensors map with err " 4174dbb8aeaSWludzik, Jozef << static_cast<unsigned>(status); 4184dbb8aeaSWludzik, Jozef return; 4194dbb8aeaSWludzik, Jozef } 4204dbb8aeaSWludzik, Jozef addReportReq->insert(uriToDbus); 4214dbb8aeaSWludzik, Jozef }); 4224dbb8aeaSWludzik, Jozef } 4237e860f15SJohn Edward Broadbent }); 424081ebf06SWludzik, Jozef } 425081ebf06SWludzik, Jozef 4267e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinition(App& app) 427081ebf06SWludzik, Jozef { 4287e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 4297e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 430ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinition) 4317e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 43245ca1b86SEd Tanous [&app](const crow::Request& req, 4337e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4347e860f15SJohn Edward Broadbent const std::string& id) { 43545ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 43645ca1b86SEd Tanous { 43745ca1b86SEd Tanous return; 43845ca1b86SEd Tanous } 43945ca1b86SEd Tanous 440081ebf06SWludzik, Jozef crow::connections::systemBus->async_method_call( 441168e20c1SEd Tanous [asyncResp, 442168e20c1SEd Tanous id](const boost::system::error_code ec, 443081ebf06SWludzik, Jozef const std::vector<std::pair< 444168e20c1SEd Tanous std::string, dbus::utility::DbusVariantType>>& 445168e20c1SEd Tanous ret) { 446081ebf06SWludzik, Jozef if (ec.value() == EBADR || 447081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 448081ebf06SWludzik, Jozef { 4497e860f15SJohn Edward Broadbent messages::resourceNotFound( 4507e860f15SJohn Edward Broadbent asyncResp->res, "MetricReportDefinition", id); 451081ebf06SWludzik, Jozef return; 452081ebf06SWludzik, Jozef } 453081ebf06SWludzik, Jozef if (ec) 454081ebf06SWludzik, Jozef { 455081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 456081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 457081ebf06SWludzik, Jozef return; 458081ebf06SWludzik, Jozef } 459081ebf06SWludzik, Jozef 460081ebf06SWludzik, Jozef telemetry::fillReportDefinition(asyncResp, id, ret); 461081ebf06SWludzik, Jozef }, 462081ebf06SWludzik, Jozef telemetry::service, telemetry::getDbusReportPath(id), 463081ebf06SWludzik, Jozef "org.freedesktop.DBus.Properties", "GetAll", 464081ebf06SWludzik, Jozef telemetry::reportInterface); 4657e860f15SJohn Edward Broadbent }); 4667e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 4677e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 468ed398213SEd Tanous .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) 4697e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 47045ca1b86SEd Tanous [&app](const crow::Request& req, 4717e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4727e860f15SJohn Edward Broadbent const std::string& id) 4734dbb8aeaSWludzik, Jozef 4744dbb8aeaSWludzik, Jozef { 47545ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 47645ca1b86SEd Tanous { 47745ca1b86SEd Tanous return; 47845ca1b86SEd Tanous } 47945ca1b86SEd Tanous 4804dbb8aeaSWludzik, Jozef const std::string reportPath = telemetry::getDbusReportPath(id); 4814dbb8aeaSWludzik, Jozef 4824dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 4834dbb8aeaSWludzik, Jozef [asyncResp, id](const boost::system::error_code ec) { 4844dbb8aeaSWludzik, Jozef /* 4857e860f15SJohn Edward Broadbent * boost::system::errc and std::errc are missing value 4867e860f15SJohn Edward Broadbent * for EBADR error that is defined in Linux. 4874dbb8aeaSWludzik, Jozef */ 4884dbb8aeaSWludzik, Jozef if (ec.value() == EBADR) 4894dbb8aeaSWludzik, Jozef { 4907e860f15SJohn Edward Broadbent messages::resourceNotFound( 4917e860f15SJohn Edward Broadbent asyncResp->res, "MetricReportDefinition", id); 4924dbb8aeaSWludzik, Jozef return; 4934dbb8aeaSWludzik, Jozef } 4944dbb8aeaSWludzik, Jozef 4954dbb8aeaSWludzik, Jozef if (ec) 4964dbb8aeaSWludzik, Jozef { 4974dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 4984dbb8aeaSWludzik, Jozef messages::internalError(asyncResp->res); 4994dbb8aeaSWludzik, Jozef return; 5004dbb8aeaSWludzik, Jozef } 5014dbb8aeaSWludzik, Jozef 5027e860f15SJohn Edward Broadbent asyncResp->res.result( 5037e860f15SJohn Edward Broadbent boost::beast::http::status::no_content); 5044dbb8aeaSWludzik, Jozef }, 5057e860f15SJohn Edward Broadbent telemetry::service, reportPath, 5067e860f15SJohn Edward Broadbent "xyz.openbmc_project.Object.Delete", "Delete"); 5077e860f15SJohn Edward Broadbent }); 5084dbb8aeaSWludzik, Jozef } 509081ebf06SWludzik, Jozef } // namespace redfish 510