12f9f9b87SWludzik, Jozef #include "report_factory.hpp"
22f9f9b87SWludzik, Jozef
36ccfcbf5SKrzysztof Grobelny #include "metric.hpp"
42f9f9b87SWludzik, Jozef #include "report.hpp"
5e2362796SWludzik, Jozef #include "sensor.hpp"
68069771cSKrzysztof Grobelny #include "utils/clock.hpp"
7e8fc5751SKrzysztof Grobelny #include "utils/conversion.hpp"
81477fe6aSWludzik, Jozef #include "utils/dbus_mapper.hpp"
9e2362796SWludzik, Jozef #include "utils/transform.hpp"
102f9f9b87SWludzik, Jozef
ReportFactory(std::shared_ptr<sdbusplus::asio::connection> bus,const std::shared_ptr<sdbusplus::asio::object_server> & objServer,SensorCache & sensorCache)112f9f9b87SWludzik, Jozef ReportFactory::ReportFactory(
12e2362796SWludzik, Jozef std::shared_ptr<sdbusplus::asio::connection> bus,
131477fe6aSWludzik, Jozef const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
141477fe6aSWludzik, Jozef SensorCache& sensorCache) :
15f535cad6SPatrick Williams bus(std::move(bus)), objServer(objServer), sensorCache(sensorCache)
162f9f9b87SWludzik, Jozef {}
172f9f9b87SWludzik, Jozef
make(const std::string & id,const std::string & name,const ReportingType reportingType,const std::vector<ReportAction> & reportActions,Milliseconds period,uint64_t appendLimit,const ReportUpdates reportUpdates,interfaces::ReportManager & reportManager,interfaces::JsonStorage & reportStorage,std::vector<LabeledMetricParameters> labeledMetricParams,bool enabled,Readings readings) const182f9f9b87SWludzik, Jozef std::unique_ptr<interfaces::Report> ReportFactory::make(
19b8cc78ddSKrzysztof Grobelny const std::string& id, const std::string& name,
20b8cc78ddSKrzysztof Grobelny const ReportingType reportingType,
2151497a0cSKrzysztof Grobelny const std::vector<ReportAction>& reportActions, Milliseconds period,
2251497a0cSKrzysztof Grobelny uint64_t appendLimit, const ReportUpdates reportUpdates,
233eb56865SSzymon Dompke interfaces::ReportManager& reportManager,
24d2238194SKrzysztof Grobelny interfaces::JsonStorage& reportStorage,
25493e62ebSKrzysztof Grobelny std::vector<LabeledMetricParameters> labeledMetricParams, bool enabled,
26493e62ebSKrzysztof Grobelny Readings readings) const
272f9f9b87SWludzik, Jozef {
28*583ba441SPatrick Williams auto metrics = utils::transform(
29*583ba441SPatrick Williams labeledMetricParams,
30d2238194SKrzysztof Grobelny [this](const LabeledMetricParameters& param)
31d2238194SKrzysztof Grobelny -> std::shared_ptr<interfaces::Metric> {
32dcc4e193SKrzysztof Grobelny namespace ts = utils::tstring;
33dcc4e193SKrzysztof Grobelny
34d2238194SKrzysztof Grobelny return std::make_shared<Metric>(
35dcc4e193SKrzysztof Grobelny getSensors(param.at_label<ts::SensorPath>()),
36cff70c14SKrzysztof Grobelny param.at_label<ts::OperationType>(),
37dcc4e193SKrzysztof Grobelny param.at_label<ts::CollectionTimeScope>(),
388069771cSKrzysztof Grobelny param.at_label<ts::CollectionDuration>(),
398069771cSKrzysztof Grobelny std::make_unique<Clock>());
40d2238194SKrzysztof Grobelny });
41c8e3a64aSKrzysztof Grobelny
42493e62ebSKrzysztof Grobelny return std::make_unique<Report>(
43493e62ebSKrzysztof Grobelny bus->get_io_context(), objServer, id, name, reportingType,
44493e62ebSKrzysztof Grobelny reportActions, period, appendLimit, reportUpdates, reportManager,
45493e62ebSKrzysztof Grobelny reportStorage, std::move(metrics), *this, enabled,
46493e62ebSKrzysztof Grobelny std::make_unique<Clock>(), std::move(readings));
47fdb06a14SSzymon Dompke }
48fdb06a14SSzymon Dompke
updateMetrics(std::vector<std::shared_ptr<interfaces::Metric>> & metrics,bool enabled,const std::vector<LabeledMetricParameters> & labeledMetricParams) const49fdb06a14SSzymon Dompke void ReportFactory::updateMetrics(
50fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>>& metrics, bool enabled,
5132305f14SSzymon Dompke const std::vector<LabeledMetricParameters>& labeledMetricParams) const
52fdb06a14SSzymon Dompke {
53fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>> oldMetrics = metrics;
54fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>> newMetrics;
55fdb06a14SSzymon Dompke
56fdb06a14SSzymon Dompke for (const auto& labeledMetricParam : labeledMetricParams)
57fdb06a14SSzymon Dompke {
58fdb06a14SSzymon Dompke auto existing = std::find_if(oldMetrics.begin(), oldMetrics.end(),
59fdb06a14SSzymon Dompke [labeledMetricParam](auto metric) {
60*583ba441SPatrick Williams return labeledMetricParam ==
61*583ba441SPatrick Williams metric->dumpConfiguration();
62fdb06a14SSzymon Dompke });
63fdb06a14SSzymon Dompke
64fdb06a14SSzymon Dompke if (existing != oldMetrics.end())
65fdb06a14SSzymon Dompke {
66fdb06a14SSzymon Dompke newMetrics.emplace_back(*existing);
67fdb06a14SSzymon Dompke oldMetrics.erase(existing);
68fdb06a14SSzymon Dompke continue;
69fdb06a14SSzymon Dompke }
70fdb06a14SSzymon Dompke
71fdb06a14SSzymon Dompke namespace ts = utils::tstring;
72fdb06a14SSzymon Dompke newMetrics.emplace_back(std::make_shared<Metric>(
73fdb06a14SSzymon Dompke getSensors(labeledMetricParam.at_label<ts::SensorPath>()),
74fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::OperationType>(),
75fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionTimeScope>(),
76fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionDuration>(),
77fdb06a14SSzymon Dompke std::make_unique<Clock>()));
78fdb06a14SSzymon Dompke
79fdb06a14SSzymon Dompke if (enabled)
80fdb06a14SSzymon Dompke {
81fdb06a14SSzymon Dompke newMetrics.back()->initialize();
82fdb06a14SSzymon Dompke }
83fdb06a14SSzymon Dompke }
84fdb06a14SSzymon Dompke
85fdb06a14SSzymon Dompke if (enabled)
86fdb06a14SSzymon Dompke {
87fdb06a14SSzymon Dompke for (auto& metric : oldMetrics)
88fdb06a14SSzymon Dompke {
89fdb06a14SSzymon Dompke metric->deinitialize();
90fdb06a14SSzymon Dompke }
91fdb06a14SSzymon Dompke }
92fdb06a14SSzymon Dompke
93fdb06a14SSzymon Dompke metrics = std::move(newMetrics);
942f9f9b87SWludzik, Jozef }
956ccfcbf5SKrzysztof Grobelny
getSensors(const std::vector<LabeledSensorInfo> & sensorPaths) const96dcc4e193SKrzysztof Grobelny Sensors ReportFactory::getSensors(
9794f71c51SSzymon Dompke const std::vector<LabeledSensorInfo>& sensorPaths) const
986ccfcbf5SKrzysztof Grobelny {
99d2238194SKrzysztof Grobelny using namespace utils::tstring;
100d2238194SKrzysztof Grobelny
101*583ba441SPatrick Williams return utils::transform(
102*583ba441SPatrick Williams sensorPaths,
10394f71c51SSzymon Dompke [this](const LabeledSensorInfo& sensorPath)
104dcc4e193SKrzysztof Grobelny -> std::shared_ptr<interfaces::Sensor> {
105dcc4e193SKrzysztof Grobelny return sensorCache.makeSensor<Sensor>(
106b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Service>(), sensorPath.at_label<Path>(),
107b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Metadata>(), bus->get_io_context(), bus);
108dcc4e193SKrzysztof Grobelny });
1096ccfcbf5SKrzysztof Grobelny }
1106ccfcbf5SKrzysztof Grobelny
convertMetricParams(boost::asio::yield_context & yield,const ReadingParameters & metricParams) const111d2238194SKrzysztof Grobelny std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
112d2238194SKrzysztof Grobelny boost::asio::yield_context& yield,
113d2238194SKrzysztof Grobelny const ReadingParameters& metricParams) const
1146ccfcbf5SKrzysztof Grobelny {
115fdb06a14SSzymon Dompke if (metricParams.empty())
116fdb06a14SSzymon Dompke {
117fdb06a14SSzymon Dompke return {};
118fdb06a14SSzymon Dompke }
11962c08e9bSKrzysztof Grobelny
1201477fe6aSWludzik, Jozef auto tree = utils::getSubTreeSensors(yield, bus);
121fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree);
122fdb06a14SSzymon Dompke }
123d2238194SKrzysztof Grobelny
convertMetricParams(const ReadingParameters & metricParams) const124fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams(
125fdb06a14SSzymon Dompke const ReadingParameters& metricParams) const
126fdb06a14SSzymon Dompke {
127fdb06a14SSzymon Dompke if (metricParams.empty())
128fdb06a14SSzymon Dompke {
129fdb06a14SSzymon Dompke return {};
130fdb06a14SSzymon Dompke }
13162c08e9bSKrzysztof Grobelny
132fdb06a14SSzymon Dompke auto tree = utils::getSubTreeSensors(bus);
133fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree);
134fdb06a14SSzymon Dompke }
135fdb06a14SSzymon Dompke
136fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters>
getMetricParamsFromSensorTree(const ReadingParameters & metricParams,const std::vector<utils::SensorTree> & tree) const137fdb06a14SSzymon Dompke ReportFactory::getMetricParamsFromSensorTree(
138fdb06a14SSzymon Dompke const ReadingParameters& metricParams,
139fdb06a14SSzymon Dompke const std::vector<utils::SensorTree>& tree) const
140fdb06a14SSzymon Dompke {
14162c08e9bSKrzysztof Grobelny try
14262c08e9bSKrzysztof Grobelny {
143d2238194SKrzysztof Grobelny return utils::transform(metricParams, [&tree](const auto& item) {
144cff70c14SKrzysztof Grobelny auto [sensorPaths, operationType, collectionTimeScope,
145b8cc78ddSKrzysztof Grobelny collectionDuration] = item;
146d2238194SKrzysztof Grobelny
14794f71c51SSzymon Dompke std::vector<LabeledSensorInfo> sensorParameters;
148dcc4e193SKrzysztof Grobelny
149b8cc78ddSKrzysztof Grobelny for (const auto& [sensorPath, metadata] : sensorPaths)
150dcc4e193SKrzysztof Grobelny {
15162c08e9bSKrzysztof Grobelny auto it = std::find_if(tree.begin(), tree.end(),
15262c08e9bSKrzysztof Grobelny [path = sensorPath](const auto& v) {
15362c08e9bSKrzysztof Grobelny return v.first == path;
15462c08e9bSKrzysztof Grobelny });
155d2238194SKrzysztof Grobelny
156e8fc5751SKrzysztof Grobelny if (it != tree.end() && it->second.size() == 1)
157d2238194SKrzysztof Grobelny {
158e8fc5751SKrzysztof Grobelny const auto& [service, ifaces] = it->second.front();
15962c08e9bSKrzysztof Grobelny sensorParameters.emplace_back(service, sensorPath,
16062c08e9bSKrzysztof Grobelny metadata);
161dcc4e193SKrzysztof Grobelny }
162d2238194SKrzysztof Grobelny }
163d2238194SKrzysztof Grobelny
164dcc4e193SKrzysztof Grobelny if (sensorParameters.size() != sensorPaths.size())
165dcc4e193SKrzysztof Grobelny {
16662c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters",
16762c08e9bSKrzysztof Grobelny "Service not found.");
168dcc4e193SKrzysztof Grobelny }
169dcc4e193SKrzysztof Grobelny
170b8cc78ddSKrzysztof Grobelny if (operationType.empty())
171b8cc78ddSKrzysztof Grobelny {
172b8cc78ddSKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg);
173b8cc78ddSKrzysztof Grobelny }
17460fee077SKrzysztof Grobelny else if (operationType == "SINGLE")
17560fee077SKrzysztof Grobelny {
17660fee077SKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg);
17760fee077SKrzysztof Grobelny collectionTimeScope =
17860fee077SKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point);
17960fee077SKrzysztof Grobelny }
180b8cc78ddSKrzysztof Grobelny
181b8cc78ddSKrzysztof Grobelny if (collectionTimeScope.empty())
182b8cc78ddSKrzysztof Grobelny {
183b8cc78ddSKrzysztof Grobelny collectionTimeScope =
184b8cc78ddSKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point);
185b8cc78ddSKrzysztof Grobelny }
186b8cc78ddSKrzysztof Grobelny
187dcc4e193SKrzysztof Grobelny return LabeledMetricParameters(
18862c08e9bSKrzysztof Grobelny std::move(sensorParameters),
189cff70c14SKrzysztof Grobelny utils::toOperationType(operationType),
19062c08e9bSKrzysztof Grobelny utils::toCollectionTimeScope(collectionTimeScope),
191dcc4e193SKrzysztof Grobelny CollectionDuration(Milliseconds(collectionDuration)));
192d2238194SKrzysztof Grobelny });
1936ccfcbf5SKrzysztof Grobelny }
19462c08e9bSKrzysztof Grobelny catch (const errors::InvalidArgument& e)
19562c08e9bSKrzysztof Grobelny {
19662c08e9bSKrzysztof Grobelny if (e.propertyName == "ReadingParameters")
19762c08e9bSKrzysztof Grobelny {
19862c08e9bSKrzysztof Grobelny throw;
19962c08e9bSKrzysztof Grobelny }
20062c08e9bSKrzysztof Grobelny
20162c08e9bSKrzysztof Grobelny using namespace std::literals::string_literals;
20262c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters."s + e.propertyName);
20362c08e9bSKrzysztof Grobelny }
20462c08e9bSKrzysztof Grobelny }
205