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 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) : 15e2362796SWludzik, Jozef bus(std::move(bus)), 161477fe6aSWludzik, Jozef objServer(objServer), sensorCache(sensorCache) 172f9f9b87SWludzik, Jozef {} 182f9f9b87SWludzik, Jozef 192f9f9b87SWludzik, Jozef std::unique_ptr<interfaces::Report> ReportFactory::make( 20b8cc78ddSKrzysztof Grobelny const std::string& id, const std::string& name, 21b8cc78ddSKrzysztof Grobelny const ReportingType reportingType, 2251497a0cSKrzysztof Grobelny const std::vector<ReportAction>& reportActions, Milliseconds period, 2351497a0cSKrzysztof Grobelny uint64_t appendLimit, const ReportUpdates reportUpdates, 243eb56865SSzymon Dompke interfaces::ReportManager& reportManager, 25d2238194SKrzysztof Grobelny interfaces::JsonStorage& reportStorage, 26493e62ebSKrzysztof Grobelny std::vector<LabeledMetricParameters> labeledMetricParams, bool enabled, 27493e62ebSKrzysztof Grobelny Readings readings) const 282f9f9b87SWludzik, Jozef { 29f7ea2997SKrzysztof Grobelny auto metrics = utils::transform( 30d2238194SKrzysztof Grobelny labeledMetricParams, 31d2238194SKrzysztof Grobelny [this](const LabeledMetricParameters& param) 32d2238194SKrzysztof Grobelny -> std::shared_ptr<interfaces::Metric> { 33dcc4e193SKrzysztof Grobelny namespace ts = utils::tstring; 34dcc4e193SKrzysztof Grobelny 35d2238194SKrzysztof Grobelny return std::make_shared<Metric>( 36dcc4e193SKrzysztof Grobelny getSensors(param.at_label<ts::SensorPath>()), 37dcc4e193SKrzysztof Grobelny param.at_label<ts::OperationType>(), param.at_label<ts::Id>(), 38dcc4e193SKrzysztof Grobelny param.at_label<ts::CollectionTimeScope>(), 398069771cSKrzysztof Grobelny param.at_label<ts::CollectionDuration>(), 408069771cSKrzysztof Grobelny std::make_unique<Clock>()); 41d2238194SKrzysztof Grobelny }); 42c8e3a64aSKrzysztof Grobelny 43493e62ebSKrzysztof Grobelny return std::make_unique<Report>( 44493e62ebSKrzysztof Grobelny bus->get_io_context(), objServer, id, name, reportingType, 45493e62ebSKrzysztof Grobelny reportActions, period, appendLimit, reportUpdates, reportManager, 46493e62ebSKrzysztof Grobelny reportStorage, std::move(metrics), *this, enabled, 47493e62ebSKrzysztof Grobelny std::make_unique<Clock>(), std::move(readings)); 48fdb06a14SSzymon Dompke } 49fdb06a14SSzymon Dompke 50fdb06a14SSzymon Dompke void ReportFactory::updateMetrics( 51fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>>& metrics, bool enabled, 5232305f14SSzymon Dompke const std::vector<LabeledMetricParameters>& labeledMetricParams) const 53fdb06a14SSzymon Dompke { 54fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>> oldMetrics = metrics; 55fdb06a14SSzymon Dompke std::vector<std::shared_ptr<interfaces::Metric>> newMetrics; 56fdb06a14SSzymon Dompke 57fdb06a14SSzymon Dompke for (const auto& labeledMetricParam : labeledMetricParams) 58fdb06a14SSzymon Dompke { 59fdb06a14SSzymon Dompke auto existing = std::find_if(oldMetrics.begin(), oldMetrics.end(), 60fdb06a14SSzymon Dompke [labeledMetricParam](auto metric) { 61fdb06a14SSzymon Dompke return labeledMetricParam == 62fdb06a14SSzymon Dompke metric->dumpConfiguration(); 63fdb06a14SSzymon Dompke }); 64fdb06a14SSzymon Dompke 65fdb06a14SSzymon Dompke if (existing != oldMetrics.end()) 66fdb06a14SSzymon Dompke { 67fdb06a14SSzymon Dompke newMetrics.emplace_back(*existing); 68fdb06a14SSzymon Dompke oldMetrics.erase(existing); 69fdb06a14SSzymon Dompke continue; 70fdb06a14SSzymon Dompke } 71fdb06a14SSzymon Dompke 72fdb06a14SSzymon Dompke namespace ts = utils::tstring; 73fdb06a14SSzymon Dompke newMetrics.emplace_back(std::make_shared<Metric>( 74fdb06a14SSzymon Dompke getSensors(labeledMetricParam.at_label<ts::SensorPath>()), 75fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::OperationType>(), 76fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::Id>(), 77fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionTimeScope>(), 78fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionDuration>(), 79fdb06a14SSzymon Dompke std::make_unique<Clock>())); 80fdb06a14SSzymon Dompke 81fdb06a14SSzymon Dompke if (enabled) 82fdb06a14SSzymon Dompke { 83fdb06a14SSzymon Dompke newMetrics.back()->initialize(); 84fdb06a14SSzymon Dompke } 85fdb06a14SSzymon Dompke } 86fdb06a14SSzymon Dompke 87fdb06a14SSzymon Dompke if (enabled) 88fdb06a14SSzymon Dompke { 89fdb06a14SSzymon Dompke for (auto& metric : oldMetrics) 90fdb06a14SSzymon Dompke { 91fdb06a14SSzymon Dompke metric->deinitialize(); 92fdb06a14SSzymon Dompke } 93fdb06a14SSzymon Dompke } 94fdb06a14SSzymon Dompke 95fdb06a14SSzymon Dompke metrics = std::move(newMetrics); 962f9f9b87SWludzik, Jozef } 976ccfcbf5SKrzysztof Grobelny 98dcc4e193SKrzysztof Grobelny Sensors ReportFactory::getSensors( 9994f71c51SSzymon Dompke const std::vector<LabeledSensorInfo>& sensorPaths) const 1006ccfcbf5SKrzysztof Grobelny { 101d2238194SKrzysztof Grobelny using namespace utils::tstring; 102d2238194SKrzysztof Grobelny 103b8cc78ddSKrzysztof Grobelny return utils::transform( 104b8cc78ddSKrzysztof Grobelny sensorPaths, 10594f71c51SSzymon Dompke [this](const LabeledSensorInfo& sensorPath) 106dcc4e193SKrzysztof Grobelny -> std::shared_ptr<interfaces::Sensor> { 107dcc4e193SKrzysztof Grobelny return sensorCache.makeSensor<Sensor>( 108b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Service>(), sensorPath.at_label<Path>(), 109b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Metadata>(), bus->get_io_context(), bus); 110dcc4e193SKrzysztof Grobelny }); 1116ccfcbf5SKrzysztof Grobelny } 1126ccfcbf5SKrzysztof Grobelny 113d2238194SKrzysztof Grobelny std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams( 114d2238194SKrzysztof Grobelny boost::asio::yield_context& yield, 115d2238194SKrzysztof Grobelny const ReadingParameters& metricParams) const 1166ccfcbf5SKrzysztof Grobelny { 117fdb06a14SSzymon Dompke if (metricParams.empty()) 118fdb06a14SSzymon Dompke { 119fdb06a14SSzymon Dompke return {}; 120fdb06a14SSzymon Dompke } 121*62c08e9bSKrzysztof Grobelny 1221477fe6aSWludzik, Jozef auto tree = utils::getSubTreeSensors(yield, bus); 123fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree); 124fdb06a14SSzymon Dompke } 125d2238194SKrzysztof Grobelny 126fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams( 127fdb06a14SSzymon Dompke const ReadingParameters& metricParams) const 128fdb06a14SSzymon Dompke { 129fdb06a14SSzymon Dompke if (metricParams.empty()) 130fdb06a14SSzymon Dompke { 131fdb06a14SSzymon Dompke return {}; 132fdb06a14SSzymon Dompke } 133*62c08e9bSKrzysztof Grobelny 134fdb06a14SSzymon Dompke auto tree = utils::getSubTreeSensors(bus); 135fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree); 136fdb06a14SSzymon Dompke } 137fdb06a14SSzymon Dompke 138fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters> 139fdb06a14SSzymon Dompke ReportFactory::getMetricParamsFromSensorTree( 140fdb06a14SSzymon Dompke const ReadingParameters& metricParams, 141fdb06a14SSzymon Dompke const std::vector<utils::SensorTree>& tree) const 142fdb06a14SSzymon Dompke { 143*62c08e9bSKrzysztof Grobelny try 144*62c08e9bSKrzysztof Grobelny { 145d2238194SKrzysztof Grobelny return utils::transform(metricParams, [&tree](const auto& item) { 146b8cc78ddSKrzysztof Grobelny auto [sensorPaths, operationType, id, collectionTimeScope, 147b8cc78ddSKrzysztof Grobelny collectionDuration] = item; 148d2238194SKrzysztof Grobelny 14994f71c51SSzymon Dompke std::vector<LabeledSensorInfo> sensorParameters; 150dcc4e193SKrzysztof Grobelny 151b8cc78ddSKrzysztof Grobelny for (const auto& [sensorPath, metadata] : sensorPaths) 152dcc4e193SKrzysztof Grobelny { 153*62c08e9bSKrzysztof Grobelny auto it = std::find_if(tree.begin(), tree.end(), 154*62c08e9bSKrzysztof Grobelny [path = sensorPath](const auto& v) { 155*62c08e9bSKrzysztof Grobelny return v.first == path; 156*62c08e9bSKrzysztof Grobelny }); 157d2238194SKrzysztof Grobelny 158e8fc5751SKrzysztof Grobelny if (it != tree.end() && it->second.size() == 1) 159d2238194SKrzysztof Grobelny { 160e8fc5751SKrzysztof Grobelny const auto& [service, ifaces] = it->second.front(); 161*62c08e9bSKrzysztof Grobelny sensorParameters.emplace_back(service, sensorPath, 162*62c08e9bSKrzysztof Grobelny metadata); 163dcc4e193SKrzysztof Grobelny } 164d2238194SKrzysztof Grobelny } 165d2238194SKrzysztof Grobelny 166dcc4e193SKrzysztof Grobelny if (sensorParameters.size() != sensorPaths.size()) 167dcc4e193SKrzysztof Grobelny { 168*62c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters", 169*62c08e9bSKrzysztof Grobelny "Service not found."); 170dcc4e193SKrzysztof Grobelny } 171dcc4e193SKrzysztof Grobelny 172b8cc78ddSKrzysztof Grobelny if (operationType.empty()) 173b8cc78ddSKrzysztof Grobelny { 174b8cc78ddSKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg); 175b8cc78ddSKrzysztof Grobelny } 17660fee077SKrzysztof Grobelny else if (operationType == "SINGLE") 17760fee077SKrzysztof Grobelny { 17860fee077SKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg); 17960fee077SKrzysztof Grobelny collectionTimeScope = 18060fee077SKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point); 18160fee077SKrzysztof Grobelny } 182b8cc78ddSKrzysztof Grobelny 183b8cc78ddSKrzysztof Grobelny if (collectionTimeScope.empty()) 184b8cc78ddSKrzysztof Grobelny { 185b8cc78ddSKrzysztof Grobelny collectionTimeScope = 186b8cc78ddSKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point); 187b8cc78ddSKrzysztof Grobelny } 188b8cc78ddSKrzysztof Grobelny 189dcc4e193SKrzysztof Grobelny return LabeledMetricParameters( 190*62c08e9bSKrzysztof Grobelny std::move(sensorParameters), 191*62c08e9bSKrzysztof Grobelny utils::toOperationType(operationType), id, 192*62c08e9bSKrzysztof Grobelny utils::toCollectionTimeScope(collectionTimeScope), 193dcc4e193SKrzysztof Grobelny CollectionDuration(Milliseconds(collectionDuration))); 194d2238194SKrzysztof Grobelny }); 1956ccfcbf5SKrzysztof Grobelny } 196*62c08e9bSKrzysztof Grobelny catch (const errors::InvalidArgument& e) 197*62c08e9bSKrzysztof Grobelny { 198*62c08e9bSKrzysztof Grobelny if (e.propertyName == "ReadingParameters") 199*62c08e9bSKrzysztof Grobelny { 200*62c08e9bSKrzysztof Grobelny throw; 201*62c08e9bSKrzysztof Grobelny } 202*62c08e9bSKrzysztof Grobelny 203*62c08e9bSKrzysztof Grobelny using namespace std::literals::string_literals; 204*62c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters."s + e.propertyName); 205*62c08e9bSKrzysztof Grobelny } 206*62c08e9bSKrzysztof Grobelny } 207