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) { 61*3a1c297aSPatrick Williams return labeledMetricParam == 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::Id>(), 76fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionTimeScope>(), 77fdb06a14SSzymon Dompke labeledMetricParam.at_label<ts::CollectionDuration>(), 78fdb06a14SSzymon Dompke std::make_unique<Clock>())); 79fdb06a14SSzymon Dompke 80fdb06a14SSzymon Dompke if (enabled) 81fdb06a14SSzymon Dompke { 82fdb06a14SSzymon Dompke newMetrics.back()->initialize(); 83fdb06a14SSzymon Dompke } 84fdb06a14SSzymon Dompke } 85fdb06a14SSzymon Dompke 86fdb06a14SSzymon Dompke if (enabled) 87fdb06a14SSzymon Dompke { 88fdb06a14SSzymon Dompke for (auto& metric : oldMetrics) 89fdb06a14SSzymon Dompke { 90fdb06a14SSzymon Dompke metric->deinitialize(); 91fdb06a14SSzymon Dompke } 92fdb06a14SSzymon Dompke } 93fdb06a14SSzymon Dompke 94fdb06a14SSzymon Dompke metrics = std::move(newMetrics); 952f9f9b87SWludzik, Jozef } 966ccfcbf5SKrzysztof Grobelny 97dcc4e193SKrzysztof Grobelny Sensors ReportFactory::getSensors( 9894f71c51SSzymon Dompke const std::vector<LabeledSensorInfo>& sensorPaths) const 996ccfcbf5SKrzysztof Grobelny { 100d2238194SKrzysztof Grobelny using namespace utils::tstring; 101d2238194SKrzysztof Grobelny 102b8cc78ddSKrzysztof Grobelny return utils::transform( 103b8cc78ddSKrzysztof Grobelny sensorPaths, 10494f71c51SSzymon Dompke [this](const LabeledSensorInfo& sensorPath) 105dcc4e193SKrzysztof Grobelny -> std::shared_ptr<interfaces::Sensor> { 106dcc4e193SKrzysztof Grobelny return sensorCache.makeSensor<Sensor>( 107b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Service>(), sensorPath.at_label<Path>(), 108b8cc78ddSKrzysztof Grobelny sensorPath.at_label<Metadata>(), bus->get_io_context(), bus); 109dcc4e193SKrzysztof Grobelny }); 1106ccfcbf5SKrzysztof Grobelny } 1116ccfcbf5SKrzysztof Grobelny 112d2238194SKrzysztof Grobelny std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams( 113d2238194SKrzysztof Grobelny boost::asio::yield_context& yield, 114d2238194SKrzysztof Grobelny const ReadingParameters& metricParams) const 1156ccfcbf5SKrzysztof Grobelny { 116fdb06a14SSzymon Dompke if (metricParams.empty()) 117fdb06a14SSzymon Dompke { 118fdb06a14SSzymon Dompke return {}; 119fdb06a14SSzymon Dompke } 12062c08e9bSKrzysztof Grobelny 1211477fe6aSWludzik, Jozef auto tree = utils::getSubTreeSensors(yield, bus); 122fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree); 123fdb06a14SSzymon Dompke } 124d2238194SKrzysztof Grobelny 125fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters> ReportFactory::convertMetricParams( 126fdb06a14SSzymon Dompke const ReadingParameters& metricParams) const 127fdb06a14SSzymon Dompke { 128fdb06a14SSzymon Dompke if (metricParams.empty()) 129fdb06a14SSzymon Dompke { 130fdb06a14SSzymon Dompke return {}; 131fdb06a14SSzymon Dompke } 13262c08e9bSKrzysztof Grobelny 133fdb06a14SSzymon Dompke auto tree = utils::getSubTreeSensors(bus); 134fdb06a14SSzymon Dompke return getMetricParamsFromSensorTree(metricParams, tree); 135fdb06a14SSzymon Dompke } 136fdb06a14SSzymon Dompke 137fdb06a14SSzymon Dompke std::vector<LabeledMetricParameters> 138fdb06a14SSzymon Dompke ReportFactory::getMetricParamsFromSensorTree( 139fdb06a14SSzymon Dompke const ReadingParameters& metricParams, 140fdb06a14SSzymon Dompke const std::vector<utils::SensorTree>& tree) const 141fdb06a14SSzymon Dompke { 14262c08e9bSKrzysztof Grobelny try 14362c08e9bSKrzysztof Grobelny { 144d2238194SKrzysztof Grobelny return utils::transform(metricParams, [&tree](const auto& item) { 145b8cc78ddSKrzysztof Grobelny auto [sensorPaths, operationType, id, collectionTimeScope, 146b8cc78ddSKrzysztof Grobelny collectionDuration] = item; 147d2238194SKrzysztof Grobelny 14894f71c51SSzymon Dompke std::vector<LabeledSensorInfo> sensorParameters; 149dcc4e193SKrzysztof Grobelny 150b8cc78ddSKrzysztof Grobelny for (const auto& [sensorPath, metadata] : sensorPaths) 151dcc4e193SKrzysztof Grobelny { 15262c08e9bSKrzysztof Grobelny auto it = std::find_if(tree.begin(), tree.end(), 15362c08e9bSKrzysztof Grobelny [path = sensorPath](const auto& v) { 15462c08e9bSKrzysztof Grobelny return v.first == path; 15562c08e9bSKrzysztof Grobelny }); 156d2238194SKrzysztof Grobelny 157e8fc5751SKrzysztof Grobelny if (it != tree.end() && it->second.size() == 1) 158d2238194SKrzysztof Grobelny { 159e8fc5751SKrzysztof Grobelny const auto& [service, ifaces] = it->second.front(); 16062c08e9bSKrzysztof Grobelny sensorParameters.emplace_back(service, sensorPath, 16162c08e9bSKrzysztof Grobelny metadata); 162dcc4e193SKrzysztof Grobelny } 163d2238194SKrzysztof Grobelny } 164d2238194SKrzysztof Grobelny 165dcc4e193SKrzysztof Grobelny if (sensorParameters.size() != sensorPaths.size()) 166dcc4e193SKrzysztof Grobelny { 16762c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters", 16862c08e9bSKrzysztof Grobelny "Service not found."); 169dcc4e193SKrzysztof Grobelny } 170dcc4e193SKrzysztof Grobelny 171b8cc78ddSKrzysztof Grobelny if (operationType.empty()) 172b8cc78ddSKrzysztof Grobelny { 173b8cc78ddSKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg); 174b8cc78ddSKrzysztof Grobelny } 17560fee077SKrzysztof Grobelny else if (operationType == "SINGLE") 17660fee077SKrzysztof Grobelny { 17760fee077SKrzysztof Grobelny operationType = utils::enumToString(OperationType::avg); 17860fee077SKrzysztof Grobelny collectionTimeScope = 17960fee077SKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point); 18060fee077SKrzysztof Grobelny } 181b8cc78ddSKrzysztof Grobelny 182b8cc78ddSKrzysztof Grobelny if (collectionTimeScope.empty()) 183b8cc78ddSKrzysztof Grobelny { 184b8cc78ddSKrzysztof Grobelny collectionTimeScope = 185b8cc78ddSKrzysztof Grobelny utils::enumToString(CollectionTimeScope::point); 186b8cc78ddSKrzysztof Grobelny } 187b8cc78ddSKrzysztof Grobelny 188dcc4e193SKrzysztof Grobelny return LabeledMetricParameters( 18962c08e9bSKrzysztof Grobelny std::move(sensorParameters), 19062c08e9bSKrzysztof Grobelny utils::toOperationType(operationType), id, 19162c08e9bSKrzysztof Grobelny utils::toCollectionTimeScope(collectionTimeScope), 192dcc4e193SKrzysztof Grobelny CollectionDuration(Milliseconds(collectionDuration))); 193d2238194SKrzysztof Grobelny }); 1946ccfcbf5SKrzysztof Grobelny } 19562c08e9bSKrzysztof Grobelny catch (const errors::InvalidArgument& e) 19662c08e9bSKrzysztof Grobelny { 19762c08e9bSKrzysztof Grobelny if (e.propertyName == "ReadingParameters") 19862c08e9bSKrzysztof Grobelny { 19962c08e9bSKrzysztof Grobelny throw; 20062c08e9bSKrzysztof Grobelny } 20162c08e9bSKrzysztof Grobelny 20262c08e9bSKrzysztof Grobelny using namespace std::literals::string_literals; 20362c08e9bSKrzysztof Grobelny throw errors::InvalidArgument("ReadingParameters."s + e.propertyName); 20462c08e9bSKrzysztof Grobelny } 20562c08e9bSKrzysztof Grobelny } 206