1 #include "report_factory.hpp" 2 3 #include "metric.hpp" 4 #include "report.hpp" 5 #include "sensor.hpp" 6 #include "utils/transform.hpp" 7 8 ReportFactory::ReportFactory( 9 std::shared_ptr<sdbusplus::asio::connection> bus, 10 const std::shared_ptr<sdbusplus::asio::object_server>& objServer) : 11 bus(std::move(bus)), 12 objServer(objServer) 13 {} 14 15 std::unique_ptr<interfaces::Report> ReportFactory::make( 16 boost::asio::yield_context& yield, const std::string& name, 17 const std::string& reportingType, bool emitsReadingsSignal, 18 bool logToMetricReportsCollection, std::chrono::milliseconds period, 19 const ReadingParameters& metricParams, 20 interfaces::ReportManager& reportManager, 21 interfaces::JsonStorage& reportStorage) const 22 { 23 return make(name, reportingType, emitsReadingsSignal, 24 logToMetricReportsCollection, period, metricParams, 25 reportManager, reportStorage, 26 convertMetricParams(yield, metricParams)); 27 } 28 29 std::unique_ptr<interfaces::Report> ReportFactory::make( 30 const std::string& name, const std::string& reportingType, 31 bool emitsReadingsSignal, bool logToMetricReportsCollection, 32 std::chrono::milliseconds period, const ReadingParameters& metricParams, 33 interfaces::ReportManager& reportManager, 34 interfaces::JsonStorage& reportStorage, 35 std::vector<LabeledMetricParameters> labeledMetricParams) const 36 { 37 std::vector<std::shared_ptr<interfaces::Metric>> metrics = utils::transform( 38 labeledMetricParams, 39 [this](const LabeledMetricParameters& param) 40 -> std::shared_ptr<interfaces::Metric> { 41 return std::make_shared<Metric>( 42 getSensors(param.at_index<0>()), param.at_index<1>(), 43 param.at_index<2>(), param.at_index<3>()); 44 }); 45 46 return std::make_unique<Report>( 47 bus->get_io_context(), objServer, name, reportingType, 48 emitsReadingsSignal, logToMetricReportsCollection, period, metricParams, 49 reportManager, reportStorage, std::move(metrics)); 50 } 51 52 std::vector<std::shared_ptr<interfaces::Sensor>> ReportFactory::getSensors( 53 const std::vector<LabeledSensorParameters>& sensorPaths) const 54 { 55 return utils::transform(sensorPaths, 56 [this](const LabeledSensorParameters& param) 57 -> std::shared_ptr<interfaces::Sensor> { 58 using namespace utils::tstring; 59 60 return sensorCache.makeSensor<Sensor>( 61 param.at_label<Service>(), 62 param.at_label<Path>(), 63 bus->get_io_context(), bus); 64 }); 65 } 66 67 std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams( 68 boost::asio::yield_context& yield, 69 const ReadingParameters& metricParams) const 70 { 71 std::array<const char*, 1> interfaces = { 72 "xyz.openbmc_project.Sensor.Value"}; 73 boost::system::error_code ec; 74 75 auto tree = bus->yield_method_call<std::vector<SensorTree>>( 76 yield, ec, "xyz.openbmc_project.ObjectMapper", 77 "/xyz/openbmc_project/object_mapper", 78 "xyz.openbmc_project.ObjectMapper", "GetSubTree", 79 "/xyz/openbmc_project/sensors", 2, interfaces); 80 if (ec) 81 { 82 throw std::runtime_error("Failed to query ObjectMapper!"); 83 } 84 85 return utils::transform(metricParams, [&tree](const auto& item) { 86 std::vector<LabeledSensorParameters> sensors; 87 88 for (const auto& sensorPath : std::get<0>(item)) 89 { 90 auto it = std::find_if( 91 tree.begin(), tree.end(), 92 [&sensorPath](const auto& v) { return v.first == sensorPath; }); 93 94 if (it != tree.end()) 95 { 96 for (const auto& [service, ifaces] : it->second) 97 { 98 sensors.emplace_back(service, sensorPath); 99 } 100 } 101 } 102 103 return LabeledMetricParameters(std::move(sensors), std::get<1>(item), 104 std::get<2>(item), std::get<3>(item)); 105 }); 106 } 107