1081ebf06SWludzik, Jozef #pragma once 2081ebf06SWludzik, Jozef 3081ebf06SWludzik, Jozef #include "node.hpp" 44dbb8aeaSWludzik, Jozef #include "sensors.hpp" 5081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp" 6081ebf06SWludzik, Jozef #include "utils/time_utils.hpp" 7081ebf06SWludzik, Jozef 84dbb8aeaSWludzik, Jozef #include <boost/container/flat_map.hpp> 94dbb8aeaSWludzik, Jozef 10081ebf06SWludzik, Jozef #include <tuple> 11081ebf06SWludzik, Jozef #include <variant> 12081ebf06SWludzik, Jozef 13081ebf06SWludzik, Jozef namespace redfish 14081ebf06SWludzik, Jozef { 15081ebf06SWludzik, Jozef 16081ebf06SWludzik, Jozef namespace telemetry 17081ebf06SWludzik, Jozef { 18081ebf06SWludzik, Jozef 19081ebf06SWludzik, Jozef using ReadingParameters = 20081ebf06SWludzik, Jozef std::vector<std::tuple<sdbusplus::message::object_path, std::string, 21081ebf06SWludzik, Jozef std::string, std::string>>; 22081ebf06SWludzik, Jozef 23081ebf06SWludzik, Jozef inline void fillReportDefinition( 24*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id, 25081ebf06SWludzik, Jozef const std::vector< 26081ebf06SWludzik, Jozef std::pair<std::string, std::variant<std::string, bool, uint64_t, 27081ebf06SWludzik, Jozef ReadingParameters>>>& ret) 28081ebf06SWludzik, Jozef { 29081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.type"] = 30081ebf06SWludzik, Jozef "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; 31081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.id"] = 32081ebf06SWludzik, Jozef telemetry::metricReportDefinitionUri + id; 33081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Id"] = id; 34081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Name"] = id; 35081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = 36081ebf06SWludzik, Jozef telemetry::metricReportUri + id; 37081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 38081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; 39081ebf06SWludzik, Jozef 40081ebf06SWludzik, Jozef const bool* emitsReadingsUpdate = nullptr; 41081ebf06SWludzik, Jozef const bool* logToMetricReportsCollection = nullptr; 42081ebf06SWludzik, Jozef const ReadingParameters* readingParams = nullptr; 43081ebf06SWludzik, Jozef const std::string* reportingType = nullptr; 44081ebf06SWludzik, Jozef const uint64_t* interval = nullptr; 45081ebf06SWludzik, Jozef for (const auto& [key, var] : ret) 46081ebf06SWludzik, Jozef { 47081ebf06SWludzik, Jozef if (key == "EmitsReadingsUpdate") 48081ebf06SWludzik, Jozef { 49081ebf06SWludzik, Jozef emitsReadingsUpdate = std::get_if<bool>(&var); 50081ebf06SWludzik, Jozef } 51081ebf06SWludzik, Jozef else if (key == "LogToMetricReportsCollection") 52081ebf06SWludzik, Jozef { 53081ebf06SWludzik, Jozef logToMetricReportsCollection = std::get_if<bool>(&var); 54081ebf06SWludzik, Jozef } 55081ebf06SWludzik, Jozef else if (key == "ReadingParameters") 56081ebf06SWludzik, Jozef { 57081ebf06SWludzik, Jozef readingParams = std::get_if<ReadingParameters>(&var); 58081ebf06SWludzik, Jozef } 59081ebf06SWludzik, Jozef else if (key == "ReportingType") 60081ebf06SWludzik, Jozef { 61081ebf06SWludzik, Jozef reportingType = std::get_if<std::string>(&var); 62081ebf06SWludzik, Jozef } 63081ebf06SWludzik, Jozef else if (key == "Interval") 64081ebf06SWludzik, Jozef { 65081ebf06SWludzik, Jozef interval = std::get_if<uint64_t>(&var); 66081ebf06SWludzik, Jozef } 67081ebf06SWludzik, Jozef } 68081ebf06SWludzik, Jozef if (!emitsReadingsUpdate || !logToMetricReportsCollection || 69081ebf06SWludzik, Jozef !readingParams || !reportingType || !interval) 70081ebf06SWludzik, Jozef { 71081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; 72081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 73081ebf06SWludzik, Jozef return; 74081ebf06SWludzik, Jozef } 75081ebf06SWludzik, Jozef 76081ebf06SWludzik, Jozef std::vector<std::string> redfishReportActions; 77081ebf06SWludzik, Jozef redfishReportActions.reserve(2); 78081ebf06SWludzik, Jozef if (*emitsReadingsUpdate) 79081ebf06SWludzik, Jozef { 80081ebf06SWludzik, Jozef redfishReportActions.emplace_back("RedfishEvent"); 81081ebf06SWludzik, Jozef } 82081ebf06SWludzik, Jozef if (*logToMetricReportsCollection) 83081ebf06SWludzik, Jozef { 84081ebf06SWludzik, Jozef redfishReportActions.emplace_back("LogToMetricReportsCollection"); 85081ebf06SWludzik, Jozef } 86081ebf06SWludzik, Jozef 87081ebf06SWludzik, Jozef nlohmann::json metrics = nlohmann::json::array(); 88081ebf06SWludzik, Jozef for (auto& [sensorPath, operationType, id, metadata] : *readingParams) 89081ebf06SWludzik, Jozef { 90081ebf06SWludzik, Jozef metrics.push_back({ 91081ebf06SWludzik, Jozef {"MetricId", id}, 92081ebf06SWludzik, Jozef {"MetricProperties", {metadata}}, 93081ebf06SWludzik, Jozef }); 94081ebf06SWludzik, Jozef } 95081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Metrics"] = metrics; 96081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; 97081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; 98081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = 99081ebf06SWludzik, Jozef time_utils::toDurationString(std::chrono::milliseconds(*interval)); 100081ebf06SWludzik, Jozef } 1014dbb8aeaSWludzik, Jozef 1024dbb8aeaSWludzik, Jozef struct AddReportArgs 1034dbb8aeaSWludzik, Jozef { 1044dbb8aeaSWludzik, Jozef std::string name; 1054dbb8aeaSWludzik, Jozef std::string reportingType; 1064dbb8aeaSWludzik, Jozef bool emitsReadingsUpdate = false; 1074dbb8aeaSWludzik, Jozef bool logToMetricReportsCollection = false; 1084dbb8aeaSWludzik, Jozef uint64_t interval = 0; 1094dbb8aeaSWludzik, Jozef std::vector<std::pair<std::string, std::vector<std::string>>> metrics; 1104dbb8aeaSWludzik, Jozef }; 1114dbb8aeaSWludzik, Jozef 1124dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res, 1134dbb8aeaSWludzik, Jozef std::vector<std::string>& actions, 1144dbb8aeaSWludzik, Jozef AddReportArgs& args) 1154dbb8aeaSWludzik, Jozef { 1164dbb8aeaSWludzik, Jozef size_t index = 0; 1174dbb8aeaSWludzik, Jozef for (auto& action : actions) 1184dbb8aeaSWludzik, Jozef { 1194dbb8aeaSWludzik, Jozef if (action == "RedfishEvent") 1204dbb8aeaSWludzik, Jozef { 1214dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate = true; 1224dbb8aeaSWludzik, Jozef } 1234dbb8aeaSWludzik, Jozef else if (action == "LogToMetricReportsCollection") 1244dbb8aeaSWludzik, Jozef { 1254dbb8aeaSWludzik, Jozef args.logToMetricReportsCollection = true; 1264dbb8aeaSWludzik, Jozef } 1274dbb8aeaSWludzik, Jozef else 1284dbb8aeaSWludzik, Jozef { 1294dbb8aeaSWludzik, Jozef messages::propertyValueNotInList( 1304dbb8aeaSWludzik, Jozef res, action, "ReportActions/" + std::to_string(index)); 1314dbb8aeaSWludzik, Jozef return false; 1324dbb8aeaSWludzik, Jozef } 1334dbb8aeaSWludzik, Jozef index++; 1344dbb8aeaSWludzik, Jozef } 1354dbb8aeaSWludzik, Jozef return true; 1364dbb8aeaSWludzik, Jozef } 1374dbb8aeaSWludzik, Jozef 1384dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req, 1394dbb8aeaSWludzik, Jozef AddReportArgs& args) 1404dbb8aeaSWludzik, Jozef { 1414dbb8aeaSWludzik, Jozef std::vector<nlohmann::json> metrics; 1424dbb8aeaSWludzik, Jozef std::vector<std::string> reportActions; 1434dbb8aeaSWludzik, Jozef std::optional<nlohmann::json> schedule; 1444dbb8aeaSWludzik, Jozef if (!json_util::readJson(req, res, "Id", args.name, "Metrics", metrics, 1454dbb8aeaSWludzik, Jozef "MetricReportDefinitionType", args.reportingType, 1464dbb8aeaSWludzik, Jozef "ReportActions", reportActions, "Schedule", 1474dbb8aeaSWludzik, Jozef schedule)) 1484dbb8aeaSWludzik, Jozef { 1494dbb8aeaSWludzik, Jozef return false; 1504dbb8aeaSWludzik, Jozef } 1514dbb8aeaSWludzik, Jozef 1524dbb8aeaSWludzik, Jozef constexpr const char* allowedCharactersInName = 1534dbb8aeaSWludzik, Jozef "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 1544dbb8aeaSWludzik, Jozef if (args.name.empty() || args.name.find_first_not_of( 1554dbb8aeaSWludzik, Jozef allowedCharactersInName) != std::string::npos) 1564dbb8aeaSWludzik, Jozef { 1574dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to match " << args.name 1584dbb8aeaSWludzik, Jozef << " with allowed character " 1594dbb8aeaSWludzik, Jozef << allowedCharactersInName; 1604dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "Id", args.name); 1614dbb8aeaSWludzik, Jozef return false; 1624dbb8aeaSWludzik, Jozef } 1634dbb8aeaSWludzik, Jozef 1644dbb8aeaSWludzik, Jozef if (args.reportingType != "Periodic" && args.reportingType != "OnRequest") 1654dbb8aeaSWludzik, Jozef { 1664dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(res, args.reportingType, 1674dbb8aeaSWludzik, Jozef "MetricReportDefinitionType"); 1684dbb8aeaSWludzik, Jozef return false; 1694dbb8aeaSWludzik, Jozef } 1704dbb8aeaSWludzik, Jozef 1714dbb8aeaSWludzik, Jozef if (!toDbusReportActions(res, reportActions, args)) 1724dbb8aeaSWludzik, Jozef { 1734dbb8aeaSWludzik, Jozef return false; 1744dbb8aeaSWludzik, Jozef } 1754dbb8aeaSWludzik, Jozef 1764dbb8aeaSWludzik, Jozef if (args.reportingType == "Periodic") 1774dbb8aeaSWludzik, Jozef { 1784dbb8aeaSWludzik, Jozef if (!schedule) 1794dbb8aeaSWludzik, Jozef { 1804dbb8aeaSWludzik, Jozef messages::createFailedMissingReqProperties(res, "Schedule"); 1814dbb8aeaSWludzik, Jozef return false; 1824dbb8aeaSWludzik, Jozef } 1834dbb8aeaSWludzik, Jozef 1844dbb8aeaSWludzik, Jozef std::string durationStr; 1854dbb8aeaSWludzik, Jozef if (!json_util::readJson(*schedule, res, "RecurrenceInterval", 1864dbb8aeaSWludzik, Jozef durationStr)) 1874dbb8aeaSWludzik, Jozef { 1884dbb8aeaSWludzik, Jozef return false; 1894dbb8aeaSWludzik, Jozef } 1904dbb8aeaSWludzik, Jozef 1914dbb8aeaSWludzik, Jozef std::optional<std::chrono::milliseconds> durationNum = 1924dbb8aeaSWludzik, Jozef time_utils::fromDurationString(durationStr); 1934dbb8aeaSWludzik, Jozef if (!durationNum) 1944dbb8aeaSWludzik, Jozef { 1954dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "RecurrenceInterval", 1964dbb8aeaSWludzik, Jozef durationStr); 1974dbb8aeaSWludzik, Jozef return false; 1984dbb8aeaSWludzik, Jozef } 1994dbb8aeaSWludzik, Jozef args.interval = static_cast<uint64_t>(durationNum->count()); 2004dbb8aeaSWludzik, Jozef } 2014dbb8aeaSWludzik, Jozef 2024dbb8aeaSWludzik, Jozef args.metrics.reserve(metrics.size()); 2034dbb8aeaSWludzik, Jozef for (auto& m : metrics) 2044dbb8aeaSWludzik, Jozef { 2054dbb8aeaSWludzik, Jozef std::string id; 2064dbb8aeaSWludzik, Jozef std::vector<std::string> uris; 2074dbb8aeaSWludzik, Jozef if (!json_util::readJson(m, res, "MetricId", id, "MetricProperties", 2084dbb8aeaSWludzik, Jozef uris)) 2094dbb8aeaSWludzik, Jozef { 2104dbb8aeaSWludzik, Jozef return false; 2114dbb8aeaSWludzik, Jozef } 2124dbb8aeaSWludzik, Jozef 2134dbb8aeaSWludzik, Jozef args.metrics.emplace_back(std::move(id), std::move(uris)); 2144dbb8aeaSWludzik, Jozef } 2154dbb8aeaSWludzik, Jozef 2164dbb8aeaSWludzik, Jozef return true; 2174dbb8aeaSWludzik, Jozef } 2184dbb8aeaSWludzik, Jozef 2194dbb8aeaSWludzik, Jozef inline bool getChassisSensorNode( 220*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2214dbb8aeaSWludzik, Jozef const std::vector<std::pair<std::string, std::vector<std::string>>>& 2224dbb8aeaSWludzik, Jozef metrics, 2234dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>>& matched) 2244dbb8aeaSWludzik, Jozef { 2254dbb8aeaSWludzik, Jozef for (const auto& [id, uris] : metrics) 2264dbb8aeaSWludzik, Jozef { 2274dbb8aeaSWludzik, Jozef for (size_t i = 0; i < uris.size(); i++) 2284dbb8aeaSWludzik, Jozef { 2294dbb8aeaSWludzik, Jozef const std::string& uri = uris[i]; 2304dbb8aeaSWludzik, Jozef std::string chassis; 2314dbb8aeaSWludzik, Jozef std::string node; 2324dbb8aeaSWludzik, Jozef 2334dbb8aeaSWludzik, Jozef if (!boost::starts_with(uri, "/redfish/v1/Chassis/") || 2344dbb8aeaSWludzik, Jozef !dbus::utility::getNthStringFromPath(uri, 3, chassis) || 2354dbb8aeaSWludzik, Jozef !dbus::utility::getNthStringFromPath(uri, 4, node)) 2364dbb8aeaSWludzik, Jozef { 2374dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to get chassis and sensor Node " 2384dbb8aeaSWludzik, Jozef "from " 2394dbb8aeaSWludzik, Jozef << uri; 2404dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(asyncResp->res, uri, 2414dbb8aeaSWludzik, Jozef "MetricProperties/" + 2424dbb8aeaSWludzik, Jozef std::to_string(i)); 2434dbb8aeaSWludzik, Jozef return false; 2444dbb8aeaSWludzik, Jozef } 2454dbb8aeaSWludzik, Jozef 2464dbb8aeaSWludzik, Jozef if (boost::ends_with(node, "#")) 2474dbb8aeaSWludzik, Jozef { 2484dbb8aeaSWludzik, Jozef node.pop_back(); 2494dbb8aeaSWludzik, Jozef } 2504dbb8aeaSWludzik, Jozef 2514dbb8aeaSWludzik, Jozef matched.emplace(std::move(chassis), std::move(node)); 2524dbb8aeaSWludzik, Jozef } 2534dbb8aeaSWludzik, Jozef } 2544dbb8aeaSWludzik, Jozef return true; 2554dbb8aeaSWludzik, Jozef } 2564dbb8aeaSWludzik, Jozef 2574dbb8aeaSWludzik, Jozef class AddReport 2584dbb8aeaSWludzik, Jozef { 2594dbb8aeaSWludzik, Jozef public: 260*8d1b46d7Szhanghch05 AddReport(AddReportArgs argsIn, 261*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) : 262*8d1b46d7Szhanghch05 asyncResp(asyncResp), 263*8d1b46d7Szhanghch05 args{std::move(argsIn)} 2644dbb8aeaSWludzik, Jozef {} 2654dbb8aeaSWludzik, Jozef ~AddReport() 2664dbb8aeaSWludzik, Jozef { 2674dbb8aeaSWludzik, Jozef if (asyncResp->res.result() != boost::beast::http::status::ok) 2684dbb8aeaSWludzik, Jozef { 2694dbb8aeaSWludzik, Jozef return; 2704dbb8aeaSWludzik, Jozef } 2714dbb8aeaSWludzik, Jozef 2724dbb8aeaSWludzik, Jozef telemetry::ReadingParameters readingParams; 2734dbb8aeaSWludzik, Jozef readingParams.reserve(args.metrics.size()); 2744dbb8aeaSWludzik, Jozef 2754dbb8aeaSWludzik, Jozef for (const auto& [id, uris] : args.metrics) 2764dbb8aeaSWludzik, Jozef { 2774dbb8aeaSWludzik, Jozef for (size_t i = 0; i < uris.size(); i++) 2784dbb8aeaSWludzik, Jozef { 2794dbb8aeaSWludzik, Jozef const std::string& uri = uris[i]; 2804dbb8aeaSWludzik, Jozef auto el = uriToDbus.find(uri); 2814dbb8aeaSWludzik, Jozef if (el == uriToDbus.end()) 2824dbb8aeaSWludzik, Jozef { 2834dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to find DBus sensor " 2844dbb8aeaSWludzik, Jozef "corresponding to URI " 2854dbb8aeaSWludzik, Jozef << uri; 2864dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(asyncResp->res, uri, 2874dbb8aeaSWludzik, Jozef "MetricProperties/" + 2884dbb8aeaSWludzik, Jozef std::to_string(i)); 2894dbb8aeaSWludzik, Jozef return; 2904dbb8aeaSWludzik, Jozef } 2914dbb8aeaSWludzik, Jozef 2924dbb8aeaSWludzik, Jozef const std::string& dbusPath = el->second; 2934dbb8aeaSWludzik, Jozef readingParams.emplace_back(dbusPath, "SINGLE", id, uri); 2944dbb8aeaSWludzik, Jozef } 2954dbb8aeaSWludzik, Jozef } 296*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> aResp = asyncResp; 2974dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 298*8d1b46d7Szhanghch05 [aResp, name = args.name, uriToDbus = std::move(uriToDbus)]( 2994dbb8aeaSWludzik, Jozef const boost::system::error_code ec, const std::string&) { 3004dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::file_exists) 3014dbb8aeaSWludzik, Jozef { 3024dbb8aeaSWludzik, Jozef messages::resourceAlreadyExists( 303*8d1b46d7Szhanghch05 aResp->res, "MetricReportDefinition", "Id", name); 3044dbb8aeaSWludzik, Jozef return; 3054dbb8aeaSWludzik, Jozef } 3064dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::too_many_files_open) 3074dbb8aeaSWludzik, Jozef { 308*8d1b46d7Szhanghch05 messages::createLimitReachedForResource(aResp->res); 3094dbb8aeaSWludzik, Jozef return; 3104dbb8aeaSWludzik, Jozef } 3114dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::argument_list_too_long) 3124dbb8aeaSWludzik, Jozef { 3134dbb8aeaSWludzik, Jozef nlohmann::json metricProperties = nlohmann::json::array(); 3144dbb8aeaSWludzik, Jozef for (const auto& [uri, _] : uriToDbus) 3154dbb8aeaSWludzik, Jozef { 3164dbb8aeaSWludzik, Jozef metricProperties.emplace_back(uri); 3174dbb8aeaSWludzik, Jozef } 3184dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect( 319*8d1b46d7Szhanghch05 aResp->res, metricProperties, "MetricProperties"); 3204dbb8aeaSWludzik, Jozef return; 3214dbb8aeaSWludzik, Jozef } 3224dbb8aeaSWludzik, Jozef if (ec) 3234dbb8aeaSWludzik, Jozef { 324*8d1b46d7Szhanghch05 messages::internalError(aResp->res); 3254dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 3264dbb8aeaSWludzik, Jozef return; 3274dbb8aeaSWludzik, Jozef } 3284dbb8aeaSWludzik, Jozef 329*8d1b46d7Szhanghch05 messages::created(aResp->res); 3304dbb8aeaSWludzik, Jozef }, 3314dbb8aeaSWludzik, Jozef telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", 3324dbb8aeaSWludzik, Jozef "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", 3334dbb8aeaSWludzik, Jozef "TelemetryService/" + args.name, args.reportingType, 3344dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate, args.logToMetricReportsCollection, 3354dbb8aeaSWludzik, Jozef args.interval, readingParams); 3364dbb8aeaSWludzik, Jozef } 3374dbb8aeaSWludzik, Jozef 3384dbb8aeaSWludzik, Jozef void insert(const boost::container::flat_map<std::string, std::string>& el) 3394dbb8aeaSWludzik, Jozef { 3404dbb8aeaSWludzik, Jozef uriToDbus.insert(el.begin(), el.end()); 3414dbb8aeaSWludzik, Jozef } 3424dbb8aeaSWludzik, Jozef 3434dbb8aeaSWludzik, Jozef private: 344*8d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> asyncResp; 3454dbb8aeaSWludzik, Jozef AddReportArgs args; 3464dbb8aeaSWludzik, Jozef boost::container::flat_map<std::string, std::string> uriToDbus{}; 3474dbb8aeaSWludzik, Jozef }; 348081ebf06SWludzik, Jozef } // namespace telemetry 349081ebf06SWludzik, Jozef 350081ebf06SWludzik, Jozef class MetricReportDefinitionCollection : public Node 351081ebf06SWludzik, Jozef { 352081ebf06SWludzik, Jozef public: 353081ebf06SWludzik, Jozef MetricReportDefinitionCollection(App& app) : 354081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 355081ebf06SWludzik, Jozef { 356081ebf06SWludzik, Jozef entityPrivileges = { 357081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 358081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 359081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 360081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 361081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 362081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 363081ebf06SWludzik, Jozef } 364081ebf06SWludzik, Jozef 365081ebf06SWludzik, Jozef private: 366*8d1b46d7Szhanghch05 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 367*8d1b46d7Szhanghch05 const crow::Request&, const std::vector<std::string>&) override 368081ebf06SWludzik, Jozef { 369*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 370*8d1b46d7Szhanghch05 "#MetricReportDefinitionCollection." 371081ebf06SWludzik, Jozef "MetricReportDefinitionCollection"; 372*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 373081ebf06SWludzik, Jozef "/redfish/v1/TelemetryService/MetricReportDefinitions"; 374*8d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Metric Definition Collection"; 375081ebf06SWludzik, Jozef 376081ebf06SWludzik, Jozef telemetry::getReportCollection(asyncResp, 377081ebf06SWludzik, Jozef telemetry::metricReportDefinitionUri); 378081ebf06SWludzik, Jozef } 3794dbb8aeaSWludzik, Jozef 380*8d1b46d7Szhanghch05 void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 381*8d1b46d7Szhanghch05 const crow::Request& req, 3824dbb8aeaSWludzik, Jozef const std::vector<std::string>&) override 3834dbb8aeaSWludzik, Jozef { 3844dbb8aeaSWludzik, Jozef telemetry::AddReportArgs args; 385*8d1b46d7Szhanghch05 if (!telemetry::getUserParameters(asyncResp->res, req, args)) 3864dbb8aeaSWludzik, Jozef { 3874dbb8aeaSWludzik, Jozef return; 3884dbb8aeaSWludzik, Jozef } 3894dbb8aeaSWludzik, Jozef 3904dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>> 3914dbb8aeaSWludzik, Jozef chassisSensors; 3924dbb8aeaSWludzik, Jozef if (!telemetry::getChassisSensorNode(asyncResp, args.metrics, 3934dbb8aeaSWludzik, Jozef chassisSensors)) 3944dbb8aeaSWludzik, Jozef { 3954dbb8aeaSWludzik, Jozef return; 3964dbb8aeaSWludzik, Jozef } 3974dbb8aeaSWludzik, Jozef 3984dbb8aeaSWludzik, Jozef auto addReportReq = 3994dbb8aeaSWludzik, Jozef std::make_shared<telemetry::AddReport>(std::move(args), asyncResp); 4004dbb8aeaSWludzik, Jozef for (const auto& [chassis, sensorType] : chassisSensors) 4014dbb8aeaSWludzik, Jozef { 4024dbb8aeaSWludzik, Jozef retrieveUriToDbusMap( 4034dbb8aeaSWludzik, Jozef chassis, sensorType, 4044dbb8aeaSWludzik, Jozef [asyncResp, addReportReq]( 4054dbb8aeaSWludzik, Jozef const boost::beast::http::status status, 4064dbb8aeaSWludzik, Jozef const boost::container::flat_map<std::string, std::string>& 4074dbb8aeaSWludzik, Jozef uriToDbus) { 4084dbb8aeaSWludzik, Jozef if (status != boost::beast::http::status::ok) 4094dbb8aeaSWludzik, Jozef { 4104dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to retrieve URI to dbus " 4114dbb8aeaSWludzik, Jozef "sensors map with err " 4124dbb8aeaSWludzik, Jozef << static_cast<unsigned>(status); 4134dbb8aeaSWludzik, Jozef return; 4144dbb8aeaSWludzik, Jozef } 4154dbb8aeaSWludzik, Jozef addReportReq->insert(uriToDbus); 4164dbb8aeaSWludzik, Jozef }); 4174dbb8aeaSWludzik, Jozef } 4184dbb8aeaSWludzik, Jozef } 419081ebf06SWludzik, Jozef }; 420081ebf06SWludzik, Jozef 421081ebf06SWludzik, Jozef class MetricReportDefinition : public Node 422081ebf06SWludzik, Jozef { 423081ebf06SWludzik, Jozef public: 424081ebf06SWludzik, Jozef MetricReportDefinition(App& app) : 425081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/", 426081ebf06SWludzik, Jozef std::string()) 427081ebf06SWludzik, Jozef { 428081ebf06SWludzik, Jozef entityPrivileges = { 429081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 430081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 431081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 432081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 433081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 434081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 435081ebf06SWludzik, Jozef } 436081ebf06SWludzik, Jozef 437081ebf06SWludzik, Jozef private: 438*8d1b46d7Szhanghch05 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 439*8d1b46d7Szhanghch05 const crow::Request&, 440081ebf06SWludzik, Jozef const std::vector<std::string>& params) override 441081ebf06SWludzik, Jozef { 442081ebf06SWludzik, Jozef 443081ebf06SWludzik, Jozef if (params.size() != 1) 444081ebf06SWludzik, Jozef { 445081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 446081ebf06SWludzik, Jozef return; 447081ebf06SWludzik, Jozef } 448081ebf06SWludzik, Jozef 449081ebf06SWludzik, Jozef const std::string& id = params[0]; 450081ebf06SWludzik, Jozef crow::connections::systemBus->async_method_call( 451081ebf06SWludzik, Jozef [asyncResp, 452081ebf06SWludzik, Jozef id](const boost::system::error_code ec, 453081ebf06SWludzik, Jozef const std::vector<std::pair< 454081ebf06SWludzik, Jozef std::string, std::variant<std::string, bool, uint64_t, 455081ebf06SWludzik, Jozef telemetry::ReadingParameters>>>& 456081ebf06SWludzik, Jozef ret) { 457081ebf06SWludzik, Jozef if (ec.value() == EBADR || 458081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 459081ebf06SWludzik, Jozef { 460081ebf06SWludzik, Jozef messages::resourceNotFound(asyncResp->res, 461081ebf06SWludzik, Jozef "MetricReportDefinition", id); 462081ebf06SWludzik, Jozef return; 463081ebf06SWludzik, Jozef } 464081ebf06SWludzik, Jozef if (ec) 465081ebf06SWludzik, Jozef { 466081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 467081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 468081ebf06SWludzik, Jozef return; 469081ebf06SWludzik, Jozef } 470081ebf06SWludzik, Jozef 471081ebf06SWludzik, Jozef telemetry::fillReportDefinition(asyncResp, id, ret); 472081ebf06SWludzik, Jozef }, 473081ebf06SWludzik, Jozef telemetry::service, telemetry::getDbusReportPath(id), 474081ebf06SWludzik, Jozef "org.freedesktop.DBus.Properties", "GetAll", 475081ebf06SWludzik, Jozef telemetry::reportInterface); 476081ebf06SWludzik, Jozef } 4774dbb8aeaSWludzik, Jozef 478*8d1b46d7Szhanghch05 void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 479*8d1b46d7Szhanghch05 const crow::Request&, 4804dbb8aeaSWludzik, Jozef const std::vector<std::string>& params) override 4814dbb8aeaSWludzik, Jozef { 4824dbb8aeaSWludzik, Jozef if (params.size() != 1) 4834dbb8aeaSWludzik, Jozef { 4844dbb8aeaSWludzik, Jozef messages::internalError(asyncResp->res); 4854dbb8aeaSWludzik, Jozef return; 4864dbb8aeaSWludzik, Jozef } 4874dbb8aeaSWludzik, Jozef 4884dbb8aeaSWludzik, Jozef const std::string& id = params[0]; 4894dbb8aeaSWludzik, Jozef const std::string reportPath = telemetry::getDbusReportPath(id); 4904dbb8aeaSWludzik, Jozef 4914dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 4924dbb8aeaSWludzik, Jozef [asyncResp, id](const boost::system::error_code ec) { 4934dbb8aeaSWludzik, Jozef /* 4944dbb8aeaSWludzik, Jozef * boost::system::errc and std::errc are missing value for 4954dbb8aeaSWludzik, Jozef * EBADR error that is defined in Linux. 4964dbb8aeaSWludzik, Jozef */ 4974dbb8aeaSWludzik, Jozef if (ec.value() == EBADR) 4984dbb8aeaSWludzik, Jozef { 4994dbb8aeaSWludzik, Jozef messages::resourceNotFound(asyncResp->res, 5004dbb8aeaSWludzik, Jozef "MetricReportDefinition", id); 5014dbb8aeaSWludzik, Jozef return; 5024dbb8aeaSWludzik, Jozef } 5034dbb8aeaSWludzik, Jozef 5044dbb8aeaSWludzik, Jozef if (ec) 5054dbb8aeaSWludzik, Jozef { 5064dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 5074dbb8aeaSWludzik, Jozef messages::internalError(asyncResp->res); 5084dbb8aeaSWludzik, Jozef return; 5094dbb8aeaSWludzik, Jozef } 5104dbb8aeaSWludzik, Jozef 5114dbb8aeaSWludzik, Jozef asyncResp->res.result(boost::beast::http::status::no_content); 5124dbb8aeaSWludzik, Jozef }, 5134dbb8aeaSWludzik, Jozef telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete", 5144dbb8aeaSWludzik, Jozef "Delete"); 5154dbb8aeaSWludzik, Jozef } 516081ebf06SWludzik, Jozef }; 517081ebf06SWludzik, Jozef } // namespace redfish 518