1*081ebf06SWludzik, Jozef #pragma once 2*081ebf06SWludzik, Jozef 3*081ebf06SWludzik, Jozef #include "node.hpp" 4*081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp" 5*081ebf06SWludzik, Jozef 6*081ebf06SWludzik, Jozef namespace redfish 7*081ebf06SWludzik, Jozef { 8*081ebf06SWludzik, Jozef 9*081ebf06SWludzik, Jozef namespace telemetry 10*081ebf06SWludzik, Jozef { 11*081ebf06SWludzik, Jozef 12*081ebf06SWludzik, Jozef using Readings = 13*081ebf06SWludzik, Jozef std::vector<std::tuple<std::string, std::string, double, uint64_t>>; 14*081ebf06SWludzik, Jozef using TimestampReadings = std::tuple<uint64_t, Readings>; 15*081ebf06SWludzik, Jozef 16*081ebf06SWludzik, Jozef inline nlohmann::json toMetricValues(const Readings& readings) 17*081ebf06SWludzik, Jozef { 18*081ebf06SWludzik, Jozef nlohmann::json metricValues = nlohmann::json::array_t(); 19*081ebf06SWludzik, Jozef 20*081ebf06SWludzik, Jozef for (auto& [id, metadata, sensorValue, timestamp] : readings) 21*081ebf06SWludzik, Jozef { 22*081ebf06SWludzik, Jozef metricValues.push_back({ 23*081ebf06SWludzik, Jozef {"MetricId", id}, 24*081ebf06SWludzik, Jozef {"MetricProperty", metadata}, 25*081ebf06SWludzik, Jozef {"MetricValue", std::to_string(sensorValue)}, 26*081ebf06SWludzik, Jozef {"Timestamp", 27*081ebf06SWludzik, Jozef crow::utility::getDateTime(static_cast<time_t>(timestamp))}, 28*081ebf06SWludzik, Jozef }); 29*081ebf06SWludzik, Jozef } 30*081ebf06SWludzik, Jozef 31*081ebf06SWludzik, Jozef return metricValues; 32*081ebf06SWludzik, Jozef } 33*081ebf06SWludzik, Jozef 34*081ebf06SWludzik, Jozef inline void fillReport(const std::shared_ptr<AsyncResp>& asyncResp, 35*081ebf06SWludzik, Jozef const std::string& id, 36*081ebf06SWludzik, Jozef const std::variant<TimestampReadings>& var) 37*081ebf06SWludzik, Jozef { 38*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.type"] = 39*081ebf06SWludzik, Jozef "#MetricReport.v1_3_0.MetricReport"; 40*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.id"] = telemetry::metricReportUri + id; 41*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Id"] = id; 42*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Name"] = id; 43*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReportDefinition"]["@odata.id"] = 44*081ebf06SWludzik, Jozef telemetry::metricReportDefinitionUri + id; 45*081ebf06SWludzik, Jozef 46*081ebf06SWludzik, Jozef const TimestampReadings* timestampReadings = 47*081ebf06SWludzik, Jozef std::get_if<TimestampReadings>(&var); 48*081ebf06SWludzik, Jozef if (!timestampReadings) 49*081ebf06SWludzik, Jozef { 50*081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; 51*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 52*081ebf06SWludzik, Jozef return; 53*081ebf06SWludzik, Jozef } 54*081ebf06SWludzik, Jozef 55*081ebf06SWludzik, Jozef const auto& [timestamp, readings] = *timestampReadings; 56*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Timestamp"] = 57*081ebf06SWludzik, Jozef crow::utility::getDateTime(static_cast<time_t>(timestamp)); 58*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricValues"] = toMetricValues(readings); 59*081ebf06SWludzik, Jozef } 60*081ebf06SWludzik, Jozef } // namespace telemetry 61*081ebf06SWludzik, Jozef 62*081ebf06SWludzik, Jozef class MetricReportCollection : public Node 63*081ebf06SWludzik, Jozef { 64*081ebf06SWludzik, Jozef public: 65*081ebf06SWludzik, Jozef MetricReportCollection(App& app) : 66*081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReports/") 67*081ebf06SWludzik, Jozef { 68*081ebf06SWludzik, Jozef entityPrivileges = { 69*081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 70*081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 71*081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 72*081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 73*081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 74*081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 75*081ebf06SWludzik, Jozef } 76*081ebf06SWludzik, Jozef 77*081ebf06SWludzik, Jozef private: 78*081ebf06SWludzik, Jozef void doGet(crow::Response& res, const crow::Request&, 79*081ebf06SWludzik, Jozef const std::vector<std::string>&) override 80*081ebf06SWludzik, Jozef { 81*081ebf06SWludzik, Jozef res.jsonValue["@odata.type"] = 82*081ebf06SWludzik, Jozef "#MetricReportCollection.MetricReportCollection"; 83*081ebf06SWludzik, Jozef res.jsonValue["@odata.id"] = 84*081ebf06SWludzik, Jozef "/redfish/v1/TelemetryService/MetricReports"; 85*081ebf06SWludzik, Jozef res.jsonValue["Name"] = "Metric Report Collection"; 86*081ebf06SWludzik, Jozef 87*081ebf06SWludzik, Jozef auto asyncResp = std::make_shared<AsyncResp>(res); 88*081ebf06SWludzik, Jozef telemetry::getReportCollection(asyncResp, telemetry::metricReportUri); 89*081ebf06SWludzik, Jozef } 90*081ebf06SWludzik, Jozef }; 91*081ebf06SWludzik, Jozef 92*081ebf06SWludzik, Jozef class MetricReport : public Node 93*081ebf06SWludzik, Jozef { 94*081ebf06SWludzik, Jozef public: 95*081ebf06SWludzik, Jozef MetricReport(App& app) : 96*081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReports/<str>/", 97*081ebf06SWludzik, Jozef std::string()) 98*081ebf06SWludzik, Jozef { 99*081ebf06SWludzik, Jozef entityPrivileges = { 100*081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 101*081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 102*081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 103*081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 104*081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 105*081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 106*081ebf06SWludzik, Jozef } 107*081ebf06SWludzik, Jozef 108*081ebf06SWludzik, Jozef private: 109*081ebf06SWludzik, Jozef void doGet(crow::Response& res, const crow::Request&, 110*081ebf06SWludzik, Jozef const std::vector<std::string>& params) override 111*081ebf06SWludzik, Jozef { 112*081ebf06SWludzik, Jozef auto asyncResp = std::make_shared<AsyncResp>(res); 113*081ebf06SWludzik, Jozef 114*081ebf06SWludzik, Jozef if (params.size() != 1) 115*081ebf06SWludzik, Jozef { 116*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 117*081ebf06SWludzik, Jozef return; 118*081ebf06SWludzik, Jozef } 119*081ebf06SWludzik, Jozef 120*081ebf06SWludzik, Jozef const std::string& id = params[0]; 121*081ebf06SWludzik, Jozef const std::string reportPath = telemetry::getDbusReportPath(id); 122*081ebf06SWludzik, Jozef crow::connections::systemBus->async_method_call( 123*081ebf06SWludzik, Jozef [asyncResp, id, reportPath](const boost::system::error_code& ec) { 124*081ebf06SWludzik, Jozef if (ec.value() == EBADR || 125*081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 126*081ebf06SWludzik, Jozef { 127*081ebf06SWludzik, Jozef messages::resourceNotFound(asyncResp->res, "MetricReport", 128*081ebf06SWludzik, Jozef id); 129*081ebf06SWludzik, Jozef return; 130*081ebf06SWludzik, Jozef } 131*081ebf06SWludzik, Jozef if (ec) 132*081ebf06SWludzik, Jozef { 133*081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 134*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 135*081ebf06SWludzik, Jozef return; 136*081ebf06SWludzik, Jozef } 137*081ebf06SWludzik, Jozef 138*081ebf06SWludzik, Jozef crow::connections::systemBus->async_method_call( 139*081ebf06SWludzik, Jozef [asyncResp, id]( 140*081ebf06SWludzik, Jozef const boost::system::error_code ec, 141*081ebf06SWludzik, Jozef const std::variant<telemetry::TimestampReadings>& ret) { 142*081ebf06SWludzik, Jozef if (ec) 143*081ebf06SWludzik, Jozef { 144*081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 145*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 146*081ebf06SWludzik, Jozef return; 147*081ebf06SWludzik, Jozef } 148*081ebf06SWludzik, Jozef 149*081ebf06SWludzik, Jozef telemetry::fillReport(asyncResp, id, ret); 150*081ebf06SWludzik, Jozef }, 151*081ebf06SWludzik, Jozef telemetry::service, reportPath, 152*081ebf06SWludzik, Jozef "org.freedesktop.DBus.Properties", "Get", 153*081ebf06SWludzik, Jozef telemetry::reportInterface, "Readings"); 154*081ebf06SWludzik, Jozef }, 155*081ebf06SWludzik, Jozef telemetry::service, reportPath, telemetry::reportInterface, 156*081ebf06SWludzik, Jozef "Update"); 157*081ebf06SWludzik, Jozef } 158*081ebf06SWludzik, Jozef }; 159*081ebf06SWludzik, Jozef } // namespace redfish 160