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 #include "utils/time_utils.hpp" 6*081ebf06SWludzik, Jozef 7*081ebf06SWludzik, Jozef #include <tuple> 8*081ebf06SWludzik, Jozef #include <variant> 9*081ebf06SWludzik, Jozef 10*081ebf06SWludzik, Jozef namespace redfish 11*081ebf06SWludzik, Jozef { 12*081ebf06SWludzik, Jozef 13*081ebf06SWludzik, Jozef namespace telemetry 14*081ebf06SWludzik, Jozef { 15*081ebf06SWludzik, Jozef 16*081ebf06SWludzik, Jozef using ReadingParameters = 17*081ebf06SWludzik, Jozef std::vector<std::tuple<sdbusplus::message::object_path, std::string, 18*081ebf06SWludzik, Jozef std::string, std::string>>; 19*081ebf06SWludzik, Jozef 20*081ebf06SWludzik, Jozef inline void fillReportDefinition( 21*081ebf06SWludzik, Jozef const std::shared_ptr<AsyncResp>& asyncResp, const std::string& id, 22*081ebf06SWludzik, Jozef const std::vector< 23*081ebf06SWludzik, Jozef std::pair<std::string, std::variant<std::string, bool, uint64_t, 24*081ebf06SWludzik, Jozef ReadingParameters>>>& ret) 25*081ebf06SWludzik, Jozef { 26*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.type"] = 27*081ebf06SWludzik, Jozef "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; 28*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["@odata.id"] = 29*081ebf06SWludzik, Jozef telemetry::metricReportDefinitionUri + id; 30*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Id"] = id; 31*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Name"] = id; 32*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = 33*081ebf06SWludzik, Jozef telemetry::metricReportUri + id; 34*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 35*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; 36*081ebf06SWludzik, Jozef 37*081ebf06SWludzik, Jozef const bool* emitsReadingsUpdate = nullptr; 38*081ebf06SWludzik, Jozef const bool* logToMetricReportsCollection = nullptr; 39*081ebf06SWludzik, Jozef const ReadingParameters* readingParams = nullptr; 40*081ebf06SWludzik, Jozef const std::string* reportingType = nullptr; 41*081ebf06SWludzik, Jozef const uint64_t* interval = nullptr; 42*081ebf06SWludzik, Jozef for (const auto& [key, var] : ret) 43*081ebf06SWludzik, Jozef { 44*081ebf06SWludzik, Jozef if (key == "EmitsReadingsUpdate") 45*081ebf06SWludzik, Jozef { 46*081ebf06SWludzik, Jozef emitsReadingsUpdate = std::get_if<bool>(&var); 47*081ebf06SWludzik, Jozef } 48*081ebf06SWludzik, Jozef else if (key == "LogToMetricReportsCollection") 49*081ebf06SWludzik, Jozef { 50*081ebf06SWludzik, Jozef logToMetricReportsCollection = std::get_if<bool>(&var); 51*081ebf06SWludzik, Jozef } 52*081ebf06SWludzik, Jozef else if (key == "ReadingParameters") 53*081ebf06SWludzik, Jozef { 54*081ebf06SWludzik, Jozef readingParams = std::get_if<ReadingParameters>(&var); 55*081ebf06SWludzik, Jozef } 56*081ebf06SWludzik, Jozef else if (key == "ReportingType") 57*081ebf06SWludzik, Jozef { 58*081ebf06SWludzik, Jozef reportingType = std::get_if<std::string>(&var); 59*081ebf06SWludzik, Jozef } 60*081ebf06SWludzik, Jozef else if (key == "Interval") 61*081ebf06SWludzik, Jozef { 62*081ebf06SWludzik, Jozef interval = std::get_if<uint64_t>(&var); 63*081ebf06SWludzik, Jozef } 64*081ebf06SWludzik, Jozef } 65*081ebf06SWludzik, Jozef if (!emitsReadingsUpdate || !logToMetricReportsCollection || 66*081ebf06SWludzik, Jozef !readingParams || !reportingType || !interval) 67*081ebf06SWludzik, Jozef { 68*081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; 69*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 70*081ebf06SWludzik, Jozef return; 71*081ebf06SWludzik, Jozef } 72*081ebf06SWludzik, Jozef 73*081ebf06SWludzik, Jozef std::vector<std::string> redfishReportActions; 74*081ebf06SWludzik, Jozef redfishReportActions.reserve(2); 75*081ebf06SWludzik, Jozef if (*emitsReadingsUpdate) 76*081ebf06SWludzik, Jozef { 77*081ebf06SWludzik, Jozef redfishReportActions.emplace_back("RedfishEvent"); 78*081ebf06SWludzik, Jozef } 79*081ebf06SWludzik, Jozef if (*logToMetricReportsCollection) 80*081ebf06SWludzik, Jozef { 81*081ebf06SWludzik, Jozef redfishReportActions.emplace_back("LogToMetricReportsCollection"); 82*081ebf06SWludzik, Jozef } 83*081ebf06SWludzik, Jozef 84*081ebf06SWludzik, Jozef nlohmann::json metrics = nlohmann::json::array(); 85*081ebf06SWludzik, Jozef for (auto& [sensorPath, operationType, id, metadata] : *readingParams) 86*081ebf06SWludzik, Jozef { 87*081ebf06SWludzik, Jozef metrics.push_back({ 88*081ebf06SWludzik, Jozef {"MetricId", id}, 89*081ebf06SWludzik, Jozef {"MetricProperties", {metadata}}, 90*081ebf06SWludzik, Jozef }); 91*081ebf06SWludzik, Jozef } 92*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Metrics"] = metrics; 93*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; 94*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; 95*081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = 96*081ebf06SWludzik, Jozef time_utils::toDurationString(std::chrono::milliseconds(*interval)); 97*081ebf06SWludzik, Jozef } 98*081ebf06SWludzik, Jozef } // namespace telemetry 99*081ebf06SWludzik, Jozef 100*081ebf06SWludzik, Jozef class MetricReportDefinitionCollection : public Node 101*081ebf06SWludzik, Jozef { 102*081ebf06SWludzik, Jozef public: 103*081ebf06SWludzik, Jozef MetricReportDefinitionCollection(App& app) : 104*081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 105*081ebf06SWludzik, Jozef { 106*081ebf06SWludzik, Jozef entityPrivileges = { 107*081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 108*081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 109*081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 110*081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 111*081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 112*081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 113*081ebf06SWludzik, Jozef } 114*081ebf06SWludzik, Jozef 115*081ebf06SWludzik, Jozef private: 116*081ebf06SWludzik, Jozef void doGet(crow::Response& res, const crow::Request&, 117*081ebf06SWludzik, Jozef const std::vector<std::string>&) override 118*081ebf06SWludzik, Jozef { 119*081ebf06SWludzik, Jozef res.jsonValue["@odata.type"] = "#MetricReportDefinitionCollection." 120*081ebf06SWludzik, Jozef "MetricReportDefinitionCollection"; 121*081ebf06SWludzik, Jozef res.jsonValue["@odata.id"] = 122*081ebf06SWludzik, Jozef "/redfish/v1/TelemetryService/MetricReportDefinitions"; 123*081ebf06SWludzik, Jozef res.jsonValue["Name"] = "Metric Definition Collection"; 124*081ebf06SWludzik, Jozef 125*081ebf06SWludzik, Jozef auto asyncResp = std::make_shared<AsyncResp>(res); 126*081ebf06SWludzik, Jozef telemetry::getReportCollection(asyncResp, 127*081ebf06SWludzik, Jozef telemetry::metricReportDefinitionUri); 128*081ebf06SWludzik, Jozef } 129*081ebf06SWludzik, Jozef }; 130*081ebf06SWludzik, Jozef 131*081ebf06SWludzik, Jozef class MetricReportDefinition : public Node 132*081ebf06SWludzik, Jozef { 133*081ebf06SWludzik, Jozef public: 134*081ebf06SWludzik, Jozef MetricReportDefinition(App& app) : 135*081ebf06SWludzik, Jozef Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/", 136*081ebf06SWludzik, Jozef std::string()) 137*081ebf06SWludzik, Jozef { 138*081ebf06SWludzik, Jozef entityPrivileges = { 139*081ebf06SWludzik, Jozef {boost::beast::http::verb::get, {{"Login"}}}, 140*081ebf06SWludzik, Jozef {boost::beast::http::verb::head, {{"Login"}}}, 141*081ebf06SWludzik, Jozef {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 142*081ebf06SWludzik, Jozef {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 143*081ebf06SWludzik, Jozef {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 144*081ebf06SWludzik, Jozef {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 145*081ebf06SWludzik, Jozef } 146*081ebf06SWludzik, Jozef 147*081ebf06SWludzik, Jozef private: 148*081ebf06SWludzik, Jozef void doGet(crow::Response& res, const crow::Request&, 149*081ebf06SWludzik, Jozef const std::vector<std::string>& params) override 150*081ebf06SWludzik, Jozef { 151*081ebf06SWludzik, Jozef auto asyncResp = std::make_shared<AsyncResp>(res); 152*081ebf06SWludzik, Jozef 153*081ebf06SWludzik, Jozef if (params.size() != 1) 154*081ebf06SWludzik, Jozef { 155*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 156*081ebf06SWludzik, Jozef return; 157*081ebf06SWludzik, Jozef } 158*081ebf06SWludzik, Jozef 159*081ebf06SWludzik, Jozef const std::string& id = params[0]; 160*081ebf06SWludzik, Jozef crow::connections::systemBus->async_method_call( 161*081ebf06SWludzik, Jozef [asyncResp, 162*081ebf06SWludzik, Jozef id](const boost::system::error_code ec, 163*081ebf06SWludzik, Jozef const std::vector<std::pair< 164*081ebf06SWludzik, Jozef std::string, std::variant<std::string, bool, uint64_t, 165*081ebf06SWludzik, Jozef telemetry::ReadingParameters>>>& 166*081ebf06SWludzik, Jozef ret) { 167*081ebf06SWludzik, Jozef if (ec.value() == EBADR || 168*081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 169*081ebf06SWludzik, Jozef { 170*081ebf06SWludzik, Jozef messages::resourceNotFound(asyncResp->res, 171*081ebf06SWludzik, Jozef "MetricReportDefinition", id); 172*081ebf06SWludzik, Jozef return; 173*081ebf06SWludzik, Jozef } 174*081ebf06SWludzik, Jozef if (ec) 175*081ebf06SWludzik, Jozef { 176*081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 177*081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 178*081ebf06SWludzik, Jozef return; 179*081ebf06SWludzik, Jozef } 180*081ebf06SWludzik, Jozef 181*081ebf06SWludzik, Jozef telemetry::fillReportDefinition(asyncResp, id, ret); 182*081ebf06SWludzik, Jozef }, 183*081ebf06SWludzik, Jozef telemetry::service, telemetry::getDbusReportPath(id), 184*081ebf06SWludzik, Jozef "org.freedesktop.DBus.Properties", "GetAll", 185*081ebf06SWludzik, Jozef telemetry::reportInterface); 186*081ebf06SWludzik, Jozef } 187*081ebf06SWludzik, Jozef }; 188*081ebf06SWludzik, Jozef } // namespace redfish 189