1081ebf06SWludzik, Jozef #pragma once 2081ebf06SWludzik, Jozef 3*3ccb3adbSEd Tanous #include "app.hpp" 4*3ccb3adbSEd Tanous #include "dbus_utility.hpp" 5*3ccb3adbSEd Tanous #include "query.hpp" 6*3ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 74dbb8aeaSWludzik, Jozef #include "sensors.hpp" 8*3ccb3adbSEd Tanous #include "utils/collection.hpp" 9*3ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 10081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp" 11081ebf06SWludzik, Jozef #include "utils/time_utils.hpp" 12081ebf06SWludzik, Jozef 134dbb8aeaSWludzik, Jozef #include <boost/container/flat_map.hpp> 1489474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 1589474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 164dbb8aeaSWludzik, Jozef 177a1dbc48SGeorge Liu #include <array> 18fe04d49cSNan Zhou #include <map> 197a1dbc48SGeorge Liu #include <string_view> 20081ebf06SWludzik, Jozef #include <tuple> 21081ebf06SWludzik, Jozef #include <variant> 22081ebf06SWludzik, Jozef 23081ebf06SWludzik, Jozef namespace redfish 24081ebf06SWludzik, Jozef { 25081ebf06SWludzik, Jozef 26081ebf06SWludzik, Jozef namespace telemetry 27081ebf06SWludzik, Jozef { 28081ebf06SWludzik, Jozef 29081ebf06SWludzik, Jozef using ReadingParameters = 30081ebf06SWludzik, Jozef std::vector<std::tuple<sdbusplus::message::object_path, std::string, 31081ebf06SWludzik, Jozef std::string, std::string>>; 32081ebf06SWludzik, Jozef 33b9d36b47SEd Tanous inline void 34b9d36b47SEd Tanous fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 35b9d36b47SEd Tanous const std::string& id, 36b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& ret) 37081ebf06SWludzik, Jozef { 38081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.type"] = 39081ebf06SWludzik, Jozef "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; 40079360aeSEd Tanous asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces( 41079360aeSEd Tanous "redfish", "v1", "TelemetryService", "MetricReportDefinitions", id); 42081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Id"] = id; 43081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Name"] = id; 44081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = 45456cd875SSzymon Dompke crow::utility::urlFromPieces("redfish", "v1", "TelemetryService", 46079360aeSEd Tanous "MetricReports", id); 47081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 48081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; 49081ebf06SWludzik, Jozef 50081ebf06SWludzik, Jozef const bool* emitsReadingsUpdate = nullptr; 51081ebf06SWludzik, Jozef const bool* logToMetricReportsCollection = nullptr; 5289474494SKrzysztof Grobelny const ReadingParameters* readingParameters = nullptr; 53081ebf06SWludzik, Jozef const std::string* reportingType = nullptr; 54081ebf06SWludzik, Jozef const uint64_t* interval = nullptr; 5589474494SKrzysztof Grobelny 5689474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 5789474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), ret, "EmitsReadingsUpdate", 5889474494SKrzysztof Grobelny emitsReadingsUpdate, "LogToMetricReportsCollection", 5989474494SKrzysztof Grobelny logToMetricReportsCollection, "ReadingParameters", readingParameters, 6089474494SKrzysztof Grobelny "ReportingType", reportingType, "Interval", interval); 6189474494SKrzysztof Grobelny 6289474494SKrzysztof Grobelny if (!success) 63081ebf06SWludzik, Jozef { 64081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 65081ebf06SWludzik, Jozef return; 66081ebf06SWludzik, Jozef } 67081ebf06SWludzik, Jozef 68081ebf06SWludzik, Jozef std::vector<std::string> redfishReportActions; 69081ebf06SWludzik, Jozef redfishReportActions.reserve(2); 7089474494SKrzysztof Grobelny if (emitsReadingsUpdate != nullptr && *emitsReadingsUpdate) 71081ebf06SWludzik, Jozef { 72081ebf06SWludzik, Jozef redfishReportActions.emplace_back("RedfishEvent"); 73081ebf06SWludzik, Jozef } 7489474494SKrzysztof Grobelny 7589474494SKrzysztof Grobelny if (logToMetricReportsCollection != nullptr && 7689474494SKrzysztof Grobelny *logToMetricReportsCollection) 77081ebf06SWludzik, Jozef { 78081ebf06SWludzik, Jozef redfishReportActions.emplace_back("LogToMetricReportsCollection"); 79081ebf06SWludzik, Jozef } 80081ebf06SWludzik, Jozef 81081ebf06SWludzik, Jozef nlohmann::json metrics = nlohmann::json::array(); 8289474494SKrzysztof Grobelny if (readingParameters != nullptr) 8389474494SKrzysztof Grobelny { 848a592810SEd Tanous for (const auto& [sensorPath, operationType, metricId, metadata] : 8589474494SKrzysztof Grobelny *readingParameters) 86081ebf06SWludzik, Jozef { 87613dabeaSEd Tanous nlohmann::json::object_t metric; 88613dabeaSEd Tanous metric["MetricId"] = metricId; 89613dabeaSEd Tanous metric["MetricProperties"] = nlohmann::json::array_t({metadata}); 90613dabeaSEd Tanous metrics.push_back(std::move(metric)); 91081ebf06SWludzik, Jozef } 9289474494SKrzysztof Grobelny } 9389474494SKrzysztof Grobelny 9489474494SKrzysztof Grobelny if (reportingType != nullptr) 9589474494SKrzysztof Grobelny { 96081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; 9789474494SKrzysztof Grobelny } 9889474494SKrzysztof Grobelny 9989474494SKrzysztof Grobelny if (interval != nullptr) 10089474494SKrzysztof Grobelny { 101081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = 102081ebf06SWludzik, Jozef time_utils::toDurationString(std::chrono::milliseconds(*interval)); 103081ebf06SWludzik, Jozef } 1044dbb8aeaSWludzik, Jozef 10589474494SKrzysztof Grobelny asyncResp->res.jsonValue["Metrics"] = metrics; 10689474494SKrzysztof Grobelny asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; 10789474494SKrzysztof Grobelny } 10889474494SKrzysztof Grobelny 1094dbb8aeaSWludzik, Jozef struct AddReportArgs 1104dbb8aeaSWludzik, Jozef { 1114dbb8aeaSWludzik, Jozef std::string name; 1124dbb8aeaSWludzik, Jozef std::string reportingType; 1134dbb8aeaSWludzik, Jozef bool emitsReadingsUpdate = false; 1144dbb8aeaSWludzik, Jozef bool logToMetricReportsCollection = false; 1154dbb8aeaSWludzik, Jozef uint64_t interval = 0; 1164dbb8aeaSWludzik, Jozef std::vector<std::pair<std::string, std::vector<std::string>>> metrics; 1174dbb8aeaSWludzik, Jozef }; 1184dbb8aeaSWludzik, Jozef 1194dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res, 1204dbb8aeaSWludzik, Jozef std::vector<std::string>& actions, 1214dbb8aeaSWludzik, Jozef AddReportArgs& args) 1224dbb8aeaSWludzik, Jozef { 1234dbb8aeaSWludzik, Jozef size_t index = 0; 1244dbb8aeaSWludzik, Jozef for (auto& action : actions) 1254dbb8aeaSWludzik, Jozef { 1264dbb8aeaSWludzik, Jozef if (action == "RedfishEvent") 1274dbb8aeaSWludzik, Jozef { 1284dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate = true; 1294dbb8aeaSWludzik, Jozef } 1304dbb8aeaSWludzik, Jozef else if (action == "LogToMetricReportsCollection") 1314dbb8aeaSWludzik, Jozef { 1324dbb8aeaSWludzik, Jozef args.logToMetricReportsCollection = true; 1334dbb8aeaSWludzik, Jozef } 1344dbb8aeaSWludzik, Jozef else 1354dbb8aeaSWludzik, Jozef { 1364dbb8aeaSWludzik, Jozef messages::propertyValueNotInList( 1374dbb8aeaSWludzik, Jozef res, action, "ReportActions/" + std::to_string(index)); 1384dbb8aeaSWludzik, Jozef return false; 1394dbb8aeaSWludzik, Jozef } 1404dbb8aeaSWludzik, Jozef index++; 1414dbb8aeaSWludzik, Jozef } 1424dbb8aeaSWludzik, Jozef return true; 1434dbb8aeaSWludzik, Jozef } 1444dbb8aeaSWludzik, Jozef 1454dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req, 1464dbb8aeaSWludzik, Jozef AddReportArgs& args) 1474dbb8aeaSWludzik, Jozef { 1484dbb8aeaSWludzik, Jozef std::vector<nlohmann::json> metrics; 1494dbb8aeaSWludzik, Jozef std::vector<std::string> reportActions; 1504dbb8aeaSWludzik, Jozef std::optional<nlohmann::json> schedule; 15115ed6780SWilly Tu if (!json_util::readJsonPatch(req, res, "Id", args.name, "Metrics", metrics, 15215ed6780SWilly Tu "MetricReportDefinitionType", 15315ed6780SWilly Tu args.reportingType, "ReportActions", 15415ed6780SWilly Tu reportActions, "Schedule", schedule)) 1554dbb8aeaSWludzik, Jozef { 1564dbb8aeaSWludzik, Jozef return false; 1574dbb8aeaSWludzik, Jozef } 1584dbb8aeaSWludzik, Jozef 1594dbb8aeaSWludzik, Jozef constexpr const char* allowedCharactersInName = 1604dbb8aeaSWludzik, Jozef "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 1614dbb8aeaSWludzik, Jozef if (args.name.empty() || args.name.find_first_not_of( 1624dbb8aeaSWludzik, Jozef allowedCharactersInName) != std::string::npos) 1634dbb8aeaSWludzik, Jozef { 1644dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "Failed to match " << args.name 1654dbb8aeaSWludzik, Jozef << " with allowed character " 1664dbb8aeaSWludzik, Jozef << allowedCharactersInName; 1674dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "Id", args.name); 1684dbb8aeaSWludzik, Jozef return false; 1694dbb8aeaSWludzik, Jozef } 1704dbb8aeaSWludzik, Jozef 1714dbb8aeaSWludzik, Jozef if (args.reportingType != "Periodic" && args.reportingType != "OnRequest") 1724dbb8aeaSWludzik, Jozef { 1734dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(res, args.reportingType, 1744dbb8aeaSWludzik, Jozef "MetricReportDefinitionType"); 1754dbb8aeaSWludzik, Jozef return false; 1764dbb8aeaSWludzik, Jozef } 1774dbb8aeaSWludzik, Jozef 1784dbb8aeaSWludzik, Jozef if (!toDbusReportActions(res, reportActions, args)) 1794dbb8aeaSWludzik, Jozef { 1804dbb8aeaSWludzik, Jozef return false; 1814dbb8aeaSWludzik, Jozef } 1824dbb8aeaSWludzik, Jozef 1834dbb8aeaSWludzik, Jozef if (args.reportingType == "Periodic") 1844dbb8aeaSWludzik, Jozef { 1854dbb8aeaSWludzik, Jozef if (!schedule) 1864dbb8aeaSWludzik, Jozef { 1874dbb8aeaSWludzik, Jozef messages::createFailedMissingReqProperties(res, "Schedule"); 1884dbb8aeaSWludzik, Jozef return false; 1894dbb8aeaSWludzik, Jozef } 1904dbb8aeaSWludzik, Jozef 1914dbb8aeaSWludzik, Jozef std::string durationStr; 1924dbb8aeaSWludzik, Jozef if (!json_util::readJson(*schedule, res, "RecurrenceInterval", 1934dbb8aeaSWludzik, Jozef durationStr)) 1944dbb8aeaSWludzik, Jozef { 1954dbb8aeaSWludzik, Jozef return false; 1964dbb8aeaSWludzik, Jozef } 1974dbb8aeaSWludzik, Jozef 1984dbb8aeaSWludzik, Jozef std::optional<std::chrono::milliseconds> durationNum = 1994dbb8aeaSWludzik, Jozef time_utils::fromDurationString(durationStr); 2004dbb8aeaSWludzik, Jozef if (!durationNum) 2014dbb8aeaSWludzik, Jozef { 2024dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "RecurrenceInterval", 2034dbb8aeaSWludzik, Jozef durationStr); 2044dbb8aeaSWludzik, Jozef return false; 2054dbb8aeaSWludzik, Jozef } 2064dbb8aeaSWludzik, Jozef args.interval = static_cast<uint64_t>(durationNum->count()); 2074dbb8aeaSWludzik, Jozef } 2084dbb8aeaSWludzik, Jozef 2094dbb8aeaSWludzik, Jozef args.metrics.reserve(metrics.size()); 2104dbb8aeaSWludzik, Jozef for (auto& m : metrics) 2114dbb8aeaSWludzik, Jozef { 2124dbb8aeaSWludzik, Jozef std::string id; 2134dbb8aeaSWludzik, Jozef std::vector<std::string> uris; 2144dbb8aeaSWludzik, Jozef if (!json_util::readJson(m, res, "MetricId", id, "MetricProperties", 2154dbb8aeaSWludzik, Jozef uris)) 2164dbb8aeaSWludzik, Jozef { 2174dbb8aeaSWludzik, Jozef return false; 2184dbb8aeaSWludzik, Jozef } 2194dbb8aeaSWludzik, Jozef 2204dbb8aeaSWludzik, Jozef args.metrics.emplace_back(std::move(id), std::move(uris)); 2214dbb8aeaSWludzik, Jozef } 2224dbb8aeaSWludzik, Jozef 2234dbb8aeaSWludzik, Jozef return true; 2244dbb8aeaSWludzik, Jozef } 2254dbb8aeaSWludzik, Jozef 226ca1600c1SSzymon Dompke inline bool getChassisSensorNodeFromMetrics( 2278d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2284dbb8aeaSWludzik, Jozef const std::vector<std::pair<std::string, std::vector<std::string>>>& 2294dbb8aeaSWludzik, Jozef metrics, 2304dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>>& matched) 2314dbb8aeaSWludzik, Jozef { 232ca1600c1SSzymon Dompke for (const auto& metric : metrics) 2334dbb8aeaSWludzik, Jozef { 234ca1600c1SSzymon Dompke const std::vector<std::string>& uris = metric.second; 2354dbb8aeaSWludzik, Jozef 236ca1600c1SSzymon Dompke std::optional<IncorrectMetricUri> error = 237ca1600c1SSzymon Dompke getChassisSensorNode(uris, matched); 238ca1600c1SSzymon Dompke if (error) 2394dbb8aeaSWludzik, Jozef { 240ca1600c1SSzymon Dompke messages::propertyValueIncorrect(asyncResp->res, error->uri, 2414dbb8aeaSWludzik, Jozef "MetricProperties/" + 242ca1600c1SSzymon Dompke std::to_string(error->index)); 2434dbb8aeaSWludzik, Jozef return false; 2444dbb8aeaSWludzik, Jozef } 2454dbb8aeaSWludzik, Jozef } 2464dbb8aeaSWludzik, Jozef return true; 2474dbb8aeaSWludzik, Jozef } 2484dbb8aeaSWludzik, Jozef 2494dbb8aeaSWludzik, Jozef class AddReport 2504dbb8aeaSWludzik, Jozef { 2514dbb8aeaSWludzik, Jozef public: 2528d1b46d7Szhanghch05 AddReport(AddReportArgs argsIn, 2538a592810SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) : 2548a592810SEd Tanous asyncResp(asyncRespIn), 2558d1b46d7Szhanghch05 args{std::move(argsIn)} 2564dbb8aeaSWludzik, Jozef {} 2574dbb8aeaSWludzik, Jozef ~AddReport() 2584dbb8aeaSWludzik, Jozef { 2594dbb8aeaSWludzik, Jozef if (asyncResp->res.result() != boost::beast::http::status::ok) 2604dbb8aeaSWludzik, Jozef { 2614dbb8aeaSWludzik, Jozef return; 2624dbb8aeaSWludzik, Jozef } 2634dbb8aeaSWludzik, Jozef 2644dbb8aeaSWludzik, Jozef telemetry::ReadingParameters readingParams; 2654dbb8aeaSWludzik, Jozef readingParams.reserve(args.metrics.size()); 2664dbb8aeaSWludzik, Jozef 2674dbb8aeaSWludzik, Jozef for (const auto& [id, uris] : args.metrics) 2684dbb8aeaSWludzik, Jozef { 2694dbb8aeaSWludzik, Jozef for (size_t i = 0; i < uris.size(); i++) 2704dbb8aeaSWludzik, Jozef { 2714dbb8aeaSWludzik, Jozef const std::string& uri = uris[i]; 2724dbb8aeaSWludzik, Jozef auto el = uriToDbus.find(uri); 2734dbb8aeaSWludzik, Jozef if (el == uriToDbus.end()) 2744dbb8aeaSWludzik, Jozef { 2750fda0f12SGeorge Liu BMCWEB_LOG_ERROR 2760fda0f12SGeorge Liu << "Failed to find DBus sensor corresponding to URI " 2774dbb8aeaSWludzik, Jozef << uri; 2784dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(asyncResp->res, uri, 2794dbb8aeaSWludzik, Jozef "MetricProperties/" + 2804dbb8aeaSWludzik, Jozef std::to_string(i)); 2814dbb8aeaSWludzik, Jozef return; 2824dbb8aeaSWludzik, Jozef } 2834dbb8aeaSWludzik, Jozef 2844dbb8aeaSWludzik, Jozef const std::string& dbusPath = el->second; 2854dbb8aeaSWludzik, Jozef readingParams.emplace_back(dbusPath, "SINGLE", id, uri); 2864dbb8aeaSWludzik, Jozef } 2874dbb8aeaSWludzik, Jozef } 2888d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> aResp = asyncResp; 2894dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 2908d1b46d7Szhanghch05 [aResp, name = args.name, uriToDbus = std::move(uriToDbus)]( 2914dbb8aeaSWludzik, Jozef const boost::system::error_code ec, const std::string&) { 2924dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::file_exists) 2934dbb8aeaSWludzik, Jozef { 2944dbb8aeaSWludzik, Jozef messages::resourceAlreadyExists( 2958d1b46d7Szhanghch05 aResp->res, "MetricReportDefinition", "Id", name); 2964dbb8aeaSWludzik, Jozef return; 2974dbb8aeaSWludzik, Jozef } 2984dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::too_many_files_open) 2994dbb8aeaSWludzik, Jozef { 3008d1b46d7Szhanghch05 messages::createLimitReachedForResource(aResp->res); 3014dbb8aeaSWludzik, Jozef return; 3024dbb8aeaSWludzik, Jozef } 3034dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::argument_list_too_long) 3044dbb8aeaSWludzik, Jozef { 3054dbb8aeaSWludzik, Jozef nlohmann::json metricProperties = nlohmann::json::array(); 3064dbb8aeaSWludzik, Jozef for (const auto& [uri, _] : uriToDbus) 3074dbb8aeaSWludzik, Jozef { 3084dbb8aeaSWludzik, Jozef metricProperties.emplace_back(uri); 3094dbb8aeaSWludzik, Jozef } 310002d39b4SEd Tanous messages::propertyValueIncorrect( 311002d39b4SEd Tanous aResp->res, metricProperties.dump(), "MetricProperties"); 3124dbb8aeaSWludzik, Jozef return; 3134dbb8aeaSWludzik, Jozef } 3144dbb8aeaSWludzik, Jozef if (ec) 3154dbb8aeaSWludzik, Jozef { 3168d1b46d7Szhanghch05 messages::internalError(aResp->res); 3174dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 3184dbb8aeaSWludzik, Jozef return; 3194dbb8aeaSWludzik, Jozef } 3204dbb8aeaSWludzik, Jozef 3218d1b46d7Szhanghch05 messages::created(aResp->res); 3224dbb8aeaSWludzik, Jozef }, 3234dbb8aeaSWludzik, Jozef telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", 3244dbb8aeaSWludzik, Jozef "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", 3254dbb8aeaSWludzik, Jozef "TelemetryService/" + args.name, args.reportingType, 3264dbb8aeaSWludzik, Jozef args.emitsReadingsUpdate, args.logToMetricReportsCollection, 3274dbb8aeaSWludzik, Jozef args.interval, readingParams); 3284dbb8aeaSWludzik, Jozef } 3294dbb8aeaSWludzik, Jozef 330ecd6a3a2SEd Tanous AddReport(const AddReport&) = delete; 331ecd6a3a2SEd Tanous AddReport(AddReport&&) = delete; 332ecd6a3a2SEd Tanous AddReport& operator=(const AddReport&) = delete; 333ecd6a3a2SEd Tanous AddReport& operator=(AddReport&&) = delete; 334ecd6a3a2SEd Tanous 335fe04d49cSNan Zhou void insert(const std::map<std::string, std::string>& el) 3364dbb8aeaSWludzik, Jozef { 3374dbb8aeaSWludzik, Jozef uriToDbus.insert(el.begin(), el.end()); 3384dbb8aeaSWludzik, Jozef } 3394dbb8aeaSWludzik, Jozef 3404dbb8aeaSWludzik, Jozef private: 3418d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp> asyncResp; 3424dbb8aeaSWludzik, Jozef AddReportArgs args; 3434dbb8aeaSWludzik, Jozef boost::container::flat_map<std::string, std::string> uriToDbus{}; 3444dbb8aeaSWludzik, Jozef }; 345081ebf06SWludzik, Jozef } // namespace telemetry 346081ebf06SWludzik, Jozef 3477e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinitionCollection(App& app) 348081ebf06SWludzik, Jozef { 3497e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 350ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinitionCollection) 3517e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 35245ca1b86SEd Tanous [&app](const crow::Request& req, 3537e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 3543ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 35545ca1b86SEd Tanous { 35645ca1b86SEd Tanous return; 35745ca1b86SEd Tanous } 35845ca1b86SEd Tanous 3598d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 3608d1b46d7Szhanghch05 "#MetricReportDefinitionCollection." 361081ebf06SWludzik, Jozef "MetricReportDefinitionCollection"; 3628d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 363ae9031f0SWilly Tu "/redfish/v1/TelemetryService/MetricReportDefinitions"; 364002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Metric Definition Collection"; 3657a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 3667a1dbc48SGeorge Liu telemetry::reportInterface}; 3674028ff77SEd Tanous collection_util::getCollectionMembers( 368ae9031f0SWilly Tu asyncResp, 369ae9031f0SWilly Tu boost::urls::url( 370ae9031f0SWilly Tu "/redfish/v1/TelemetryService/MetricReportDefinitions"), 371ae9031f0SWilly Tu interfaces, 3724028ff77SEd Tanous "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"); 3737e860f15SJohn Edward Broadbent }); 3744dbb8aeaSWludzik, Jozef 3757e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 376ed398213SEd Tanous .privileges(redfish::privileges::postMetricReportDefinitionCollection) 377002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 378002d39b4SEd Tanous [&app](const crow::Request& req, 3797e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 3803ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 38145ca1b86SEd Tanous { 38245ca1b86SEd Tanous return; 38345ca1b86SEd Tanous } 38445ca1b86SEd Tanous 3854dbb8aeaSWludzik, Jozef telemetry::AddReportArgs args; 3868d1b46d7Szhanghch05 if (!telemetry::getUserParameters(asyncResp->res, req, args)) 3874dbb8aeaSWludzik, Jozef { 3884dbb8aeaSWludzik, Jozef return; 3894dbb8aeaSWludzik, Jozef } 3904dbb8aeaSWludzik, Jozef 3914dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>> 3924dbb8aeaSWludzik, Jozef chassisSensors; 393002d39b4SEd Tanous if (!telemetry::getChassisSensorNodeFromMetrics(asyncResp, args.metrics, 394002d39b4SEd Tanous chassisSensors)) 3954dbb8aeaSWludzik, Jozef { 3964dbb8aeaSWludzik, Jozef return; 3974dbb8aeaSWludzik, Jozef } 3984dbb8aeaSWludzik, Jozef 399002d39b4SEd Tanous auto addReportReq = 400002d39b4SEd Tanous std::make_shared<telemetry::AddReport>(std::move(args), asyncResp); 4014dbb8aeaSWludzik, Jozef for (const auto& [chassis, sensorType] : chassisSensors) 4024dbb8aeaSWludzik, Jozef { 4034dbb8aeaSWludzik, Jozef retrieveUriToDbusMap( 404021d32cfSKrzysztof Grobelny chassis, sensorType, 405002d39b4SEd Tanous [asyncResp, addReportReq]( 406002d39b4SEd Tanous const boost::beast::http::status status, 407fe04d49cSNan Zhou const std::map<std::string, std::string>& uriToDbus) { 4084dbb8aeaSWludzik, Jozef if (status != boost::beast::http::status::ok) 4094dbb8aeaSWludzik, Jozef { 4107e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR 4110fda0f12SGeorge Liu << "Failed to retrieve URI to dbus sensors map with err " 4124dbb8aeaSWludzik, Jozef << static_cast<unsigned>(status); 4134dbb8aeaSWludzik, Jozef return; 4144dbb8aeaSWludzik, Jozef } 4154dbb8aeaSWludzik, Jozef addReportReq->insert(uriToDbus); 4164dbb8aeaSWludzik, Jozef }); 4174dbb8aeaSWludzik, Jozef } 4187e860f15SJohn Edward Broadbent }); 419081ebf06SWludzik, Jozef } 420081ebf06SWludzik, Jozef 4217e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinition(App& app) 422081ebf06SWludzik, Jozef { 4237e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 4247e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 425ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinition) 4267e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 42745ca1b86SEd Tanous [&app](const crow::Request& req, 4287e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4297e860f15SJohn Edward Broadbent const std::string& id) { 4303ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 43145ca1b86SEd Tanous { 43245ca1b86SEd Tanous return; 43345ca1b86SEd Tanous } 43445ca1b86SEd Tanous 43589474494SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 43689474494SKrzysztof Grobelny *crow::connections::systemBus, telemetry::service, 43789474494SKrzysztof Grobelny telemetry::getDbusReportPath(id), telemetry::reportInterface, 438168e20c1SEd Tanous [asyncResp, 439168e20c1SEd Tanous id](const boost::system::error_code ec, 440081ebf06SWludzik, Jozef const std::vector<std::pair< 441002d39b4SEd Tanous std::string, dbus::utility::DbusVariantType>>& ret) { 442081ebf06SWludzik, Jozef if (ec.value() == EBADR || 443081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 444081ebf06SWludzik, Jozef { 445002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, 446002d39b4SEd Tanous "MetricReportDefinition", id); 447081ebf06SWludzik, Jozef return; 448081ebf06SWludzik, Jozef } 449081ebf06SWludzik, Jozef if (ec) 450081ebf06SWludzik, Jozef { 451081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 452081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 453081ebf06SWludzik, Jozef return; 454081ebf06SWludzik, Jozef } 455081ebf06SWludzik, Jozef 456081ebf06SWludzik, Jozef telemetry::fillReportDefinition(asyncResp, id, ret); 45789474494SKrzysztof Grobelny }); 4587e860f15SJohn Edward Broadbent }); 4597e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 4607e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 461ed398213SEd Tanous .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) 4627e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 46345ca1b86SEd Tanous [&app](const crow::Request& req, 4647e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4657e860f15SJohn Edward Broadbent const std::string& id) 4664dbb8aeaSWludzik, Jozef 4674dbb8aeaSWludzik, Jozef { 4683ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 46945ca1b86SEd Tanous { 47045ca1b86SEd Tanous return; 47145ca1b86SEd Tanous } 47245ca1b86SEd Tanous 4734dbb8aeaSWludzik, Jozef const std::string reportPath = telemetry::getDbusReportPath(id); 4744dbb8aeaSWludzik, Jozef 4754dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 4764dbb8aeaSWludzik, Jozef [asyncResp, id](const boost::system::error_code ec) { 4774dbb8aeaSWludzik, Jozef /* 4787e860f15SJohn Edward Broadbent * boost::system::errc and std::errc are missing value 4797e860f15SJohn Edward Broadbent * for EBADR error that is defined in Linux. 4804dbb8aeaSWludzik, Jozef */ 4814dbb8aeaSWludzik, Jozef if (ec.value() == EBADR) 4824dbb8aeaSWludzik, Jozef { 483002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, 484002d39b4SEd Tanous "MetricReportDefinition", id); 4854dbb8aeaSWludzik, Jozef return; 4864dbb8aeaSWludzik, Jozef } 4874dbb8aeaSWludzik, Jozef 4884dbb8aeaSWludzik, Jozef if (ec) 4894dbb8aeaSWludzik, Jozef { 4904dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 4914dbb8aeaSWludzik, Jozef messages::internalError(asyncResp->res); 4924dbb8aeaSWludzik, Jozef return; 4934dbb8aeaSWludzik, Jozef } 4944dbb8aeaSWludzik, Jozef 495002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::no_content); 4964dbb8aeaSWludzik, Jozef }, 497002d39b4SEd Tanous telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete", 498002d39b4SEd Tanous "Delete"); 4997e860f15SJohn Edward Broadbent }); 5004dbb8aeaSWludzik, Jozef } 501081ebf06SWludzik, Jozef } // namespace redfish 502