xref: /openbmc/telemetry/src/report_factory.cpp (revision dcc4e1936173a93251a02066432bc2bcbc386240)
1 #include "report_factory.hpp"
2 
3 #include "metric.hpp"
4 #include "report.hpp"
5 #include "sensor.hpp"
6 #include "utils/conversion.hpp"
7 #include "utils/dbus_mapper.hpp"
8 #include "utils/transform.hpp"
9 
10 ReportFactory::ReportFactory(
11     std::shared_ptr<sdbusplus::asio::connection> bus,
12     const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
13     SensorCache& sensorCache) :
14     bus(std::move(bus)),
15     objServer(objServer), sensorCache(sensorCache)
16 {}
17 
18 std::unique_ptr<interfaces::Report> ReportFactory::make(
19     const std::string& name, const std::string& reportingType,
20     bool emitsReadingsSignal, bool logToMetricReportsCollection,
21     Milliseconds period, interfaces::ReportManager& reportManager,
22     interfaces::JsonStorage& reportStorage,
23     std::vector<LabeledMetricParameters> labeledMetricParams) const
24 {
25     std::vector<std::shared_ptr<interfaces::Metric>> metrics = utils::transform(
26         labeledMetricParams,
27         [this](const LabeledMetricParameters& param)
28             -> std::shared_ptr<interfaces::Metric> {
29             namespace ts = utils::tstring;
30 
31             return std::make_shared<Metric>(
32                 getSensors(param.at_label<ts::SensorPath>()),
33                 param.at_label<ts::OperationType>(), param.at_label<ts::Id>(),
34                 param.at_label<ts::MetricMetadata>(),
35                 param.at_label<ts::CollectionTimeScope>(),
36                 param.at_label<ts::CollectionDuration>());
37         });
38 
39     return std::make_unique<Report>(
40         bus->get_io_context(), objServer, name, reportingType,
41         emitsReadingsSignal, logToMetricReportsCollection, period,
42         reportManager, reportStorage, std::move(metrics));
43 }
44 
45 Sensors ReportFactory::getSensors(
46     const std::vector<LabeledSensorParameters>& sensorPaths) const
47 {
48     using namespace utils::tstring;
49 
50     return utils::transform(sensorPaths,
51                             [this](const LabeledSensorParameters& sensorPath)
52                                 -> std::shared_ptr<interfaces::Sensor> {
53                                 return sensorCache.makeSensor<Sensor>(
54                                     sensorPath.at_label<Service>(),
55                                     sensorPath.at_label<Path>(),
56                                     bus->get_io_context(), bus);
57                             });
58 }
59 
60 std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
61     boost::asio::yield_context& yield,
62     const ReadingParameters& metricParams) const
63 {
64     auto tree = utils::getSubTreeSensors(yield, bus);
65 
66     return utils::transform(metricParams, [&tree](const auto& item) {
67         const auto& [sensorPaths, operationType, id, metadata,
68                      collectionTimeScope, collectionDuration] = item;
69 
70         std::vector<LabeledSensorParameters> sensorParameters;
71 
72         for (const auto& sensorPath : sensorPaths)
73         {
74             auto it = std::find_if(
75                 tree.begin(), tree.end(),
76                 [&sensorPath](const auto& v) { return v.first == sensorPath; });
77 
78             if (it != tree.end() && it->second.size() == 1)
79             {
80                 const auto& [service, ifaces] = it->second.front();
81                 sensorParameters.emplace_back(service, sensorPath);
82             }
83         }
84 
85         if (sensorParameters.size() != sensorPaths.size())
86         {
87             throw sdbusplus::exception::SdBusError(
88                 static_cast<int>(std::errc::invalid_argument),
89                 "Could not find service for provided sensors");
90         }
91 
92         return LabeledMetricParameters(
93             std::move(sensorParameters),
94             utils::stringToOperationType(operationType), id, metadata,
95             utils::stringToCollectionTimeScope(collectionTimeScope),
96             CollectionDuration(Milliseconds(collectionDuration)));
97     });
98 }
99