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 std::optional<std::reference_wrapper<boost::asio::yield_context>> yield, 17 const std::string& name, const std::string& reportingType, 18 bool emitsReadingsSignal, bool logToMetricReportsCollection, 19 std::chrono::milliseconds period, const ReadingParameters& metricParams, 20 interfaces::ReportManager& reportManager, 21 interfaces::JsonStorage& reportStorage) const 22 { 23 std::optional<std::vector<ReportFactory::SensorTree>> sensorTree; 24 25 std::vector<std::shared_ptr<interfaces::Metric>> metrics; 26 metrics.reserve(metricParams.size()); 27 28 for (const auto& [sensorPaths, op, id, metadata] : metricParams) 29 { 30 if (!sensorTree && yield && sensorPaths.size() > 0) 31 { 32 sensorTree = getSensorTree(*yield); 33 } 34 35 std::vector<std::shared_ptr<interfaces::Sensor>> sensors = 36 getSensors(sensorTree, sensorPaths); 37 38 metrics.emplace_back( 39 std::make_shared<Metric>(std::move(sensors), op, id, metadata)); 40 } 41 42 return std::make_unique<Report>( 43 bus->get_io_context(), objServer, name, reportingType, 44 emitsReadingsSignal, logToMetricReportsCollection, period, metricParams, 45 reportManager, reportStorage, std::move(metrics)); 46 } 47 48 std::vector<std::shared_ptr<interfaces::Sensor>> ReportFactory::getSensors( 49 const std::optional<std::vector<ReportFactory::SensorTree>>& tree, 50 const std::vector<sdbusplus::message::object_path>& sensorPaths) const 51 { 52 if (tree) 53 { 54 std::vector<std::shared_ptr<interfaces::Sensor>> sensors; 55 56 for (const auto& [sensor, ifacesMap] : *tree) 57 { 58 auto it = std::find(sensorPaths.begin(), sensorPaths.end(), sensor); 59 if (it != sensorPaths.end()) 60 { 61 for (const auto& [service, ifaces] : ifacesMap) 62 { 63 sensors.emplace_back(sensorCache.makeSensor<Sensor>( 64 service, sensor, bus->get_io_context(), bus)); 65 } 66 } 67 } 68 69 return sensors; 70 } 71 else 72 { 73 return utils::transform( 74 sensorPaths, 75 [this](const std::string& sensor) 76 -> std::shared_ptr<interfaces::Sensor> { 77 std::string::size_type pos = sensor.find_first_of(":"); 78 auto service = sensor.substr(0, pos); 79 auto path = sensor.substr(pos + 1); 80 return sensorCache.makeSensor<Sensor>( 81 service, path, bus->get_io_context(), bus); 82 }); 83 } 84 } 85 86 std::vector<ReportFactory::SensorTree> 87 ReportFactory::getSensorTree(boost::asio::yield_context& yield) const 88 { 89 std::array<const char*, 1> interfaces = { 90 "xyz.openbmc_project.Sensor.Value"}; 91 boost::system::error_code ec; 92 93 auto result = bus->yield_method_call<std::vector<SensorTree>>( 94 yield, ec, "xyz.openbmc_project.ObjectMapper", 95 "/xyz/openbmc_project/object_mapper", 96 "xyz.openbmc_project.ObjectMapper", "GetSubTree", 97 "/xyz/openbmc_project/sensors", 2, interfaces); 98 if (ec) 99 { 100 throw std::runtime_error("failed"); 101 } 102 return result; 103 } 104