| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 1 | #include "report.hpp" | 
|  | 2 |  | 
| Krzysztof Grobelny | e6d4887 | 2022-02-08 13:41:30 +0100 | [diff] [blame] | 3 | #include "messages/collect_trigger_id.hpp" | 
|  | 4 | #include "messages/trigger_presence_changed_ind.hpp" | 
|  | 5 | #include "messages/update_report_ind.hpp" | 
| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 6 | #include "report_manager.hpp" | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 7 | #include "utils/clock.hpp" | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 8 | #include "utils/contains.hpp" | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 9 | #include "utils/ensure.hpp" | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 10 | #include "utils/transform.hpp" | 
|  | 11 |  | 
|  | 12 | #include <phosphor-logging/log.hpp> | 
| Wludzik, Jozef | b1ff1f6 | 2020-10-23 13:20:52 +0200 | [diff] [blame] | 13 | #include <sdbusplus/vtable.hpp> | 
| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 14 |  | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 15 | #include <limits> | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 16 | #include <numeric> | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 17 | #include <optional> | 
| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 18 |  | 
|  | 19 | Report::Report(boost::asio::io_context& ioc, | 
|  | 20 | const std::shared_ptr<sdbusplus::asio::object_server>& objServer, | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 21 | const std::string& reportId, const std::string& reportName, | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 22 | const ReportingType reportingTypeIn, | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 23 | std::vector<ReportAction> reportActionsIn, | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 24 | const Milliseconds intervalIn, const uint64_t appendLimitIn, | 
|  | 25 | const ReportUpdates reportUpdatesIn, | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 26 | interfaces::ReportManager& reportManager, | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 27 | interfaces::JsonStorage& reportStorageIn, | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 28 | std::vector<std::shared_ptr<interfaces::Metric>> metricsIn, | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 29 | const interfaces::ReportFactory& reportFactory, | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 30 | const bool enabledIn, std::unique_ptr<interfaces::Clock> clock, | 
|  | 31 | Readings readingsIn) : | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 32 | id(reportId), | 
|  | 33 | name(reportName), reportingType(reportingTypeIn), interval(intervalIn), | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 34 | reportActions(reportActionsIn.begin(), reportActionsIn.end()), | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 35 | sensorCount(getSensorCount(metricsIn)), | 
|  | 36 | appendLimit(deduceAppendLimit(appendLimitIn)), | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 37 | reportUpdates(reportUpdatesIn), readings(std::move(readingsIn)), | 
|  | 38 | readingsBuffer(std::get<1>(readings), | 
|  | 39 | deduceBufferSize(reportUpdates, reportingType)), | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 40 | objServer(objServer), metrics(std::move(metricsIn)), timer(ioc), | 
| Krzysztof Grobelny | e6d4887 | 2022-02-08 13:41:30 +0100 | [diff] [blame] | 41 | triggerIds(collectTriggerIds(ioc)), reportStorage(reportStorageIn), | 
|  | 42 | enabled(enabledIn), clock(std::move(clock)), messanger(ioc) | 
| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 43 | { | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 44 | readingParameters = | 
|  | 45 | toReadingParameters(utils::transform(metrics, [](const auto& metric) { | 
|  | 46 | return metric->dumpConfiguration(); | 
|  | 47 | })); | 
|  | 48 |  | 
|  | 49 | readingParametersPastVersion = | 
|  | 50 | utils::transform(readingParameters, [](const auto& item) { | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 51 | const auto& [sensorData, operationType, id, collectionTimeScope, | 
|  | 52 | collectionDuration] = item; | 
|  | 53 |  | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 54 | return ReadingParametersPastVersion::value_type( | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 55 | std::get<0>(sensorData.front()), operationType, id, | 
|  | 56 | std::get<1>(sensorData.front())); | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 57 | }); | 
|  | 58 |  | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 59 | reportActions.insert(ReportAction::logToMetricReportsCollection); | 
|  | 60 |  | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 61 | deleteIface = objServer->add_unique_interface( | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 62 | getPath(), deleteIfaceName, | 
|  | 63 | [this, &ioc, &reportManager](auto& dbusIface) { | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 64 | dbusIface.register_method("Delete", [this, &ioc, &reportManager] { | 
|  | 65 | if (persistency) | 
|  | 66 | { | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 67 | persistency = false; | 
|  | 68 |  | 
|  | 69 | reportIface->signal_property("Persistency"); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 70 | } | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 71 |  | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 72 | boost::asio::post(ioc, [this, &reportManager] { | 
|  | 73 | reportManager.removeReport(this); | 
|  | 74 | }); | 
|  | 75 | }); | 
|  | 76 | }); | 
|  | 77 |  | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 78 | persistency = storeConfiguration(); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 79 | reportIface = makeReportInterface(reportFactory); | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 80 |  | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 81 | updateReportingType(reportingType); | 
| Krzysztof Grobelny | d223819 | 2020-12-02 09:27:28 +0000 | [diff] [blame] | 82 |  | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 83 | if (enabled) | 
| Krzysztof Grobelny | d223819 | 2020-12-02 09:27:28 +0000 | [diff] [blame] | 84 | { | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 85 | for (auto& metric : this->metrics) | 
|  | 86 | { | 
|  | 87 | metric->initialize(); | 
|  | 88 | } | 
| Krzysztof Grobelny | d223819 | 2020-12-02 09:27:28 +0000 | [diff] [blame] | 89 | } | 
| Krzysztof Grobelny | e6d4887 | 2022-02-08 13:41:30 +0100 | [diff] [blame] | 90 |  | 
|  | 91 | messanger.on_receive<messages::TriggerPresenceChangedInd>( | 
|  | 92 | [this](const auto& msg) { | 
|  | 93 | const auto oldSize = triggerIds.size(); | 
|  | 94 |  | 
|  | 95 | if (msg.presence == messages::Presence::Exist) | 
|  | 96 | { | 
|  | 97 | if (utils::contains(msg.reportIds, id)) | 
|  | 98 | { | 
|  | 99 | triggerIds.insert(msg.triggerId); | 
|  | 100 | } | 
|  | 101 | else if (!utils::contains(msg.reportIds, id)) | 
|  | 102 | { | 
|  | 103 | triggerIds.erase(msg.triggerId); | 
|  | 104 | } | 
|  | 105 | } | 
|  | 106 | else if (msg.presence == messages::Presence::Removed) | 
|  | 107 | { | 
|  | 108 | triggerIds.erase(msg.triggerId); | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | if (triggerIds.size() != oldSize) | 
|  | 112 | { | 
|  | 113 | reportIface->signal_property("TriggerIds"); | 
|  | 114 | } | 
|  | 115 | }); | 
|  | 116 |  | 
|  | 117 | messanger.on_receive<messages::UpdateReportInd>([this](const auto& msg) { | 
|  | 118 | if (utils::contains(msg.reportIds, id)) | 
|  | 119 | { | 
|  | 120 | updateReadings(); | 
|  | 121 | } | 
|  | 122 | }); | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 123 | } | 
|  | 124 |  | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 125 | Report::~Report() | 
|  | 126 | { | 
|  | 127 | if (persistency) | 
|  | 128 | { | 
|  | 129 | if (shouldStoreMetricValues()) | 
|  | 130 | { | 
|  | 131 | storeConfiguration(); | 
|  | 132 | } | 
|  | 133 | } | 
|  | 134 | else | 
|  | 135 | { | 
|  | 136 | reportStorage.remove(reportFileName()); | 
|  | 137 | } | 
|  | 138 | } | 
|  | 139 |  | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 140 | uint64_t Report::getSensorCount( | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 141 | const std::vector<std::shared_ptr<interfaces::Metric>>& metrics) | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 142 | { | 
|  | 143 | uint64_t sensorCount = 0; | 
|  | 144 | for (auto& metric : metrics) | 
|  | 145 | { | 
|  | 146 | sensorCount += metric->sensorCount(); | 
|  | 147 | } | 
|  | 148 | return sensorCount; | 
|  | 149 | } | 
|  | 150 |  | 
| Krzysztof Grobelny | e6c417c | 2022-02-02 17:25:53 +0100 | [diff] [blame] | 151 | std::optional<uint64_t> | 
|  | 152 | Report::deduceAppendLimit(const uint64_t appendLimitIn) const | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 153 | { | 
|  | 154 | if (appendLimitIn == std::numeric_limits<uint64_t>::max()) | 
|  | 155 | { | 
| Krzysztof Grobelny | e6c417c | 2022-02-02 17:25:53 +0100 | [diff] [blame] | 156 | return std::nullopt; | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 157 | } | 
|  | 158 | else | 
|  | 159 | { | 
|  | 160 | return appendLimitIn; | 
|  | 161 | } | 
|  | 162 | } | 
|  | 163 |  | 
|  | 164 | uint64_t Report::deduceBufferSize(const ReportUpdates reportUpdatesIn, | 
|  | 165 | const ReportingType reportingTypeIn) const | 
|  | 166 | { | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 167 | if (reportUpdatesIn == ReportUpdates::overwrite || | 
|  | 168 | reportingTypeIn == ReportingType::onRequest) | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 169 | { | 
|  | 170 | return sensorCount; | 
|  | 171 | } | 
|  | 172 | else | 
|  | 173 | { | 
| Krzysztof Grobelny | e6c417c | 2022-02-02 17:25:53 +0100 | [diff] [blame] | 174 | return appendLimit.value_or(sensorCount); | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 175 | } | 
|  | 176 | } | 
|  | 177 |  | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 178 | void Report::setReadingBuffer(const ReportUpdates newReportUpdates) | 
|  | 179 | { | 
|  | 180 | if (reportingType != ReportingType::onRequest && | 
|  | 181 | (reportUpdates == ReportUpdates::overwrite || | 
|  | 182 | newReportUpdates == ReportUpdates::overwrite)) | 
|  | 183 | { | 
|  | 184 | readingsBuffer.clearAndResize( | 
|  | 185 | deduceBufferSize(newReportUpdates, reportingType)); | 
|  | 186 | } | 
|  | 187 | } | 
|  | 188 |  | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 189 | void Report::setReportUpdates(const ReportUpdates newReportUpdates) | 
|  | 190 | { | 
|  | 191 | if (reportUpdates != newReportUpdates) | 
|  | 192 | { | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 193 | setReadingBuffer(newReportUpdates); | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 194 | reportUpdates = newReportUpdates; | 
|  | 195 | } | 
|  | 196 | } | 
|  | 197 |  | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 198 | std::unique_ptr<sdbusplus::asio::dbus_interface> | 
|  | 199 | Report::makeReportInterface(const interfaces::ReportFactory& reportFactory) | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 200 | { | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 201 | auto dbusIface = | 
|  | 202 | objServer->add_unique_interface(getPath(), reportIfaceName); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 203 | dbusIface->register_property_rw( | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 204 | "Enabled", enabled, sdbusplus::vtable::property_::emits_change, | 
|  | 205 | [this](bool newVal, const auto&) { | 
|  | 206 | if (newVal != enabled) | 
|  | 207 | { | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 208 | if (true == newVal && ReportingType::periodic == reportingType) | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 209 | { | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 210 | scheduleTimerForPeriodicReport(interval); | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 211 | } | 
|  | 212 | if (newVal) | 
|  | 213 | { | 
|  | 214 | for (auto& metric : metrics) | 
|  | 215 | { | 
|  | 216 | metric->initialize(); | 
|  | 217 | } | 
|  | 218 | } | 
|  | 219 | else | 
|  | 220 | { | 
|  | 221 | for (auto& metric : metrics) | 
|  | 222 | { | 
|  | 223 | metric->deinitialize(); | 
|  | 224 | } | 
|  | 225 | } | 
|  | 226 |  | 
|  | 227 | enabled = newVal; | 
|  | 228 | persistency = storeConfiguration(); | 
|  | 229 | } | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 230 | return 1; | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 231 | }, | 
|  | 232 | [this](const auto&) { return enabled; }); | 
|  | 233 | dbusIface->register_property_rw( | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 234 | "Interval", interval.count(), | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 235 | sdbusplus::vtable::property_::emits_change, | 
|  | 236 | [this](uint64_t newVal, auto&) { | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 237 | if (Milliseconds newValT{newVal}; | 
|  | 238 | newValT >= ReportManager::minInterval) | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 239 | { | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 240 | if (newValT != interval) | 
|  | 241 | { | 
|  | 242 | interval = newValT; | 
|  | 243 | persistency = storeConfiguration(); | 
|  | 244 | } | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 245 | return 1; | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 246 | } | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 247 | throw sdbusplus::exception::SdBusError( | 
|  | 248 | static_cast<int>(std::errc::invalid_argument), | 
|  | 249 | "Invalid interval"); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 250 | }, | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 251 | [this](const auto&) { return interval.count(); }); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 252 | dbusIface->register_property_rw( | 
|  | 253 | "Persistency", persistency, sdbusplus::vtable::property_::emits_change, | 
|  | 254 | [this](bool newVal, const auto&) { | 
|  | 255 | if (newVal == persistency) | 
|  | 256 | { | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 257 | return 1; | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 258 | } | 
|  | 259 | if (newVal) | 
|  | 260 | { | 
|  | 261 | persistency = storeConfiguration(); | 
|  | 262 | } | 
|  | 263 | else | 
|  | 264 | { | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 265 | reportStorage.remove(reportFileName()); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 266 | persistency = false; | 
|  | 267 | } | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 268 | return 1; | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 269 | }, | 
|  | 270 | [this](const auto&) { return persistency; }); | 
|  | 271 |  | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 272 | dbusIface->register_property_r("Readings", readings, | 
|  | 273 | sdbusplus::vtable::property_::emits_change, | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 274 | [this](const auto&) { return readings; }); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 275 | dbusIface->register_property_rw( | 
|  | 276 | "ReportingType", std::string(), | 
|  | 277 | sdbusplus::vtable::property_::emits_change, | 
|  | 278 | [this](auto newVal, auto& oldVal) { | 
|  | 279 | ReportingType tmp = utils::toReportingType(newVal); | 
|  | 280 | if (tmp != reportingType) | 
|  | 281 | { | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 282 | if (tmp == ReportingType::periodic) | 
|  | 283 | { | 
|  | 284 | if (interval < ReportManager::minInterval) | 
|  | 285 | { | 
|  | 286 | throw sdbusplus::exception::SdBusError( | 
|  | 287 | static_cast<int>(std::errc::invalid_argument), | 
|  | 288 | "Invalid interval"); | 
|  | 289 | } | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 290 | } | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 291 |  | 
|  | 292 | updateReportingType(tmp); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 293 | setReadingBuffer(reportUpdates); | 
|  | 294 | persistency = storeConfiguration(); | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 295 | oldVal = std::move(newVal); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 296 | } | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 297 | return 1; | 
|  | 298 | }, | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 299 | [this](const auto&) { return utils::enumToString(reportingType); }); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 300 | dbusIface->register_property_r( | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 301 | "ReadingParameters", readingParametersPastVersion, | 
|  | 302 | sdbusplus::vtable::property_::const_, | 
|  | 303 | [this](const auto&) { return readingParametersPastVersion; }); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 304 | dbusIface->register_property_rw( | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 305 | "ReadingParametersFutureVersion", readingParameters, | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 306 | sdbusplus::vtable::property_::emits_change, | 
|  | 307 | [this, &reportFactory](auto newVal, auto& oldVal) { | 
|  | 308 | reportFactory.updateMetrics(metrics, enabled, newVal); | 
|  | 309 | readingParameters = toReadingParameters( | 
|  | 310 | utils::transform(metrics, [](const auto& metric) { | 
|  | 311 | return metric->dumpConfiguration(); | 
|  | 312 | })); | 
|  | 313 | persistency = storeConfiguration(); | 
|  | 314 | oldVal = std::move(newVal); | 
|  | 315 | return 1; | 
|  | 316 | }, | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 317 | [this](const auto&) { return readingParameters; }); | 
|  | 318 | dbusIface->register_property_r( | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 319 | "EmitsReadingsUpdate", bool{}, sdbusplus::vtable::property_::none, | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 320 | [this](const auto&) { | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 321 | return reportActions.contains(ReportAction::emitsReadingsUpdate); | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 322 | }); | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 323 | dbusIface->register_property_r("Name", std::string{}, | 
|  | 324 | sdbusplus::vtable::property_::const_, | 
|  | 325 | [this](const auto&) { return name; }); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 326 | dbusIface->register_property_r( | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 327 | "LogToMetricReportsCollection", bool{}, | 
|  | 328 | sdbusplus::vtable::property_::const_, [this](const auto&) { | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 329 | return reportActions.contains( | 
|  | 330 | ReportAction::logToMetricReportsCollection); | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 331 | }); | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 332 | dbusIface->register_property_rw( | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 333 | "ReportActions", std::vector<std::string>{}, | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 334 | sdbusplus::vtable::property_::emits_change, | 
|  | 335 | [this](auto newVal, auto& oldVal) { | 
|  | 336 | auto tmp = utils::transform<std::unordered_set>( | 
|  | 337 | newVal, [](const auto& reportAction) { | 
|  | 338 | return utils::toReportAction(reportAction); | 
|  | 339 | }); | 
|  | 340 | tmp.insert(ReportAction::logToMetricReportsCollection); | 
|  | 341 |  | 
|  | 342 | if (tmp != reportActions) | 
|  | 343 | { | 
|  | 344 | reportActions = tmp; | 
|  | 345 | persistency = storeConfiguration(); | 
|  | 346 | oldVal = std::move(newVal); | 
|  | 347 | } | 
|  | 348 | return 1; | 
|  | 349 | }, | 
|  | 350 | [this](const auto&) { | 
|  | 351 | return utils::transform<std::vector>( | 
|  | 352 | reportActions, [](const auto reportAction) { | 
|  | 353 | return utils::enumToString(reportAction); | 
|  | 354 | }); | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 355 | }); | 
| Krzysztof Grobelny | e6c417c | 2022-02-02 17:25:53 +0100 | [diff] [blame] | 356 | dbusIface->register_property_r( | 
|  | 357 | "AppendLimit", appendLimit.value_or(sensorCount), | 
|  | 358 | sdbusplus::vtable::property_::emits_change, | 
|  | 359 | [this](const auto&) { return appendLimit.value_or(sensorCount); }); | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 360 | dbusIface->register_property_rw( | 
|  | 361 | "ReportUpdates", std::string(), | 
|  | 362 | sdbusplus::vtable::property_::emits_change, | 
|  | 363 | [this](auto newVal, auto& oldVal) { | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 364 | setReportUpdates(utils::toReportUpdates(newVal)); | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 365 | oldVal = newVal; | 
| Szymon Dompke | 3e2cc9d | 2021-12-14 12:00:52 +0100 | [diff] [blame] | 366 | return 1; | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 367 | }, | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 368 | [this](const auto&) { return utils::enumToString(reportUpdates); }); | 
| Szymon Dompke | b4ef22e | 2022-02-07 15:15:12 +0100 | [diff] [blame] | 369 | dbusIface->register_property_r( | 
|  | 370 | "TriggerIds", std::vector<std::string>{}, | 
|  | 371 | sdbusplus::vtable::property_::emits_change, [this](const auto&) { | 
|  | 372 | return std::vector<std::string>(triggerIds.begin(), | 
|  | 373 | triggerIds.end()); | 
|  | 374 | }); | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 375 | dbusIface->register_method("Update", [this] { | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 376 | if (reportingType == ReportingType::onRequest) | 
| Krzysztof Grobelny | 85db8bd | 2021-05-28 12:13:23 +0000 | [diff] [blame] | 377 | { | 
|  | 378 | updateReadings(); | 
|  | 379 | } | 
|  | 380 | }); | 
|  | 381 | constexpr bool skipPropertiesChangedSignal = true; | 
|  | 382 | dbusIface->initialize(skipPropertiesChangedSignal); | 
|  | 383 | return dbusIface; | 
|  | 384 | } | 
|  | 385 |  | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 386 | void Report::timerProcForPeriodicReport(boost::system::error_code ec, | 
|  | 387 | Report& self) | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 388 | { | 
|  | 389 | if (ec) | 
|  | 390 | { | 
|  | 391 | return; | 
|  | 392 | } | 
|  | 393 |  | 
|  | 394 | self.updateReadings(); | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 395 | self.scheduleTimerForPeriodicReport(self.interval); | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 396 | } | 
|  | 397 |  | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 398 | void Report::timerProcForOnChangeReport(boost::system::error_code ec, | 
|  | 399 | Report& self) | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 400 | { | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 401 | if (ec) | 
|  | 402 | { | 
|  | 403 | return; | 
|  | 404 | } | 
|  | 405 |  | 
|  | 406 | const auto ensure = | 
|  | 407 | utils::Ensure{[&self] { self.onChangeContext = std::nullopt; }}; | 
|  | 408 |  | 
|  | 409 | self.onChangeContext.emplace(self); | 
|  | 410 |  | 
|  | 411 | const auto steadyTimestamp = self.clock->steadyTimestamp(); | 
|  | 412 |  | 
|  | 413 | for (auto& metric : self.metrics) | 
|  | 414 | { | 
|  | 415 | metric->updateReadings(steadyTimestamp); | 
|  | 416 | } | 
|  | 417 |  | 
|  | 418 | self.scheduleTimerForOnChangeReport(); | 
|  | 419 | } | 
|  | 420 |  | 
|  | 421 | void Report::scheduleTimerForPeriodicReport(Milliseconds timerInterval) | 
|  | 422 | { | 
|  | 423 | if (!enabled) | 
|  | 424 | { | 
|  | 425 | return; | 
|  | 426 | } | 
|  | 427 |  | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 428 | timer.expires_after(timerInterval); | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 429 | timer.async_wait([this](boost::system::error_code ec) { | 
|  | 430 | timerProcForPeriodicReport(ec, *this); | 
|  | 431 | }); | 
|  | 432 | } | 
|  | 433 |  | 
|  | 434 | void Report::scheduleTimerForOnChangeReport() | 
|  | 435 | { | 
|  | 436 | if (!enabled) | 
|  | 437 | { | 
|  | 438 | return; | 
|  | 439 | } | 
|  | 440 |  | 
|  | 441 | constexpr Milliseconds timerInterval{100}; | 
|  | 442 |  | 
|  | 443 | timer.expires_after(timerInterval); | 
|  | 444 | timer.async_wait([this](boost::system::error_code ec) { | 
|  | 445 | timerProcForOnChangeReport(ec, *this); | 
|  | 446 | }); | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 447 | } | 
|  | 448 |  | 
|  | 449 | void Report::updateReadings() | 
|  | 450 | { | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 451 | if (!enabled) | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 452 | { | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 453 | return; | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 454 | } | 
| Krzysztof Grobelny | c8e3a64 | 2020-10-23 12:29:16 +0200 | [diff] [blame] | 455 |  | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 456 | if (reportUpdates == ReportUpdates::overwrite || | 
|  | 457 | reportingType == ReportingType::onRequest) | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 458 | { | 
|  | 459 | readingsBuffer.clear(); | 
|  | 460 | } | 
| Krzysztof Grobelny | dcc4e19 | 2021-03-08 09:09:34 +0000 | [diff] [blame] | 461 |  | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 462 | for (const auto& metric : metrics) | 
|  | 463 | { | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 464 | for (const auto& [id, metadata, value, timestamp] : | 
| Krzysztof Grobelny | 9e8da54 | 2022-02-17 10:40:16 +0100 | [diff] [blame] | 465 | metric->getUpdatedReadings()) | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 466 | { | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 467 | if (reportUpdates == ReportUpdates::appendStopsWhenFull && | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 468 | readingsBuffer.isFull()) | 
|  | 469 | { | 
|  | 470 | enabled = false; | 
| Krzysztof Grobelny | fbeb5bf | 2022-01-03 09:41:29 +0100 | [diff] [blame] | 471 | for (auto& m : metrics) | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 472 | { | 
| Krzysztof Grobelny | fbeb5bf | 2022-01-03 09:41:29 +0100 | [diff] [blame] | 473 | m->deinitialize(); | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 474 | } | 
|  | 475 | break; | 
|  | 476 | } | 
|  | 477 | readingsBuffer.emplace(id, metadata, value, timestamp); | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 478 | } | 
|  | 479 | } | 
| Szymon Dompke | 3eb5686 | 2021-09-20 15:32:04 +0200 | [diff] [blame] | 480 |  | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 481 | std::get<0>(readings) = | 
| Krzysztof Grobelny | 51f0fd5 | 2021-12-28 16:32:08 +0100 | [diff] [blame] | 482 | std::chrono::duration_cast<Milliseconds>(clock->systemTimestamp()) | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 483 | .count(); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 484 |  | 
| Szymon Dompke | fdb06a1 | 2022-02-11 11:04:44 +0100 | [diff] [blame] | 485 | if (utils::contains(reportActions, ReportAction::emitsReadingsUpdate)) | 
|  | 486 | { | 
|  | 487 | reportIface->signal_property("Readings"); | 
|  | 488 | } | 
| Wludzik, Jozef | cb88cfd | 2020-09-28 16:38:57 +0200 | [diff] [blame] | 489 | } | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 490 |  | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 491 | bool Report::shouldStoreMetricValues() const | 
|  | 492 | { | 
|  | 493 | return reportingType != ReportingType::onRequest && | 
|  | 494 | reportUpdates == ReportUpdates::appendStopsWhenFull; | 
|  | 495 | } | 
|  | 496 |  | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 497 | bool Report::storeConfiguration() const | 
|  | 498 | { | 
|  | 499 | try | 
|  | 500 | { | 
|  | 501 | nlohmann::json data; | 
|  | 502 |  | 
| Lukasz Kazmierczak | 7e098e9 | 2021-09-16 15:59:56 +0200 | [diff] [blame] | 503 | data["Enabled"] = enabled; | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 504 | data["Version"] = reportVersion; | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 505 | data["Id"] = id; | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 506 | data["Name"] = name; | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 507 | data["ReportingType"] = utils::toUnderlying(reportingType); | 
|  | 508 | data["ReportActions"] = | 
|  | 509 | utils::transform(reportActions, [](const auto reportAction) { | 
|  | 510 | return utils::toUnderlying(reportAction); | 
|  | 511 | }); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 512 | data["Interval"] = interval.count(); | 
| Krzysztof Grobelny | e6c417c | 2022-02-02 17:25:53 +0100 | [diff] [blame] | 513 | data["AppendLimit"] = | 
|  | 514 | appendLimit.value_or(std::numeric_limits<uint64_t>::max()); | 
| Krzysztof Grobelny | 51497a0 | 2021-11-09 14:56:22 +0100 | [diff] [blame] | 515 | data["ReportUpdates"] = utils::toUnderlying(reportUpdates); | 
| Krzysztof Grobelny | d223819 | 2020-12-02 09:27:28 +0000 | [diff] [blame] | 516 | data["ReadingParameters"] = | 
|  | 517 | utils::transform(metrics, [](const auto& metric) { | 
|  | 518 | return metric->dumpConfiguration(); | 
|  | 519 | }); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 520 |  | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 521 | if (shouldStoreMetricValues()) | 
|  | 522 | { | 
|  | 523 | data["MetricValues"] = utils::toLabeledReadings(readings); | 
|  | 524 | } | 
|  | 525 |  | 
|  | 526 | reportStorage.store(reportFileName(), data); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 527 | } | 
|  | 528 | catch (const std::exception& e) | 
|  | 529 | { | 
|  | 530 | phosphor::logging::log<phosphor::logging::level::ERR>( | 
|  | 531 | "Failed to store a report in storage", | 
| Wludzik, Jozef | 982c5b5 | 2021-01-02 12:05:21 +0100 | [diff] [blame] | 532 | phosphor::logging::entry("EXCEPTION_MSG=%s", e.what())); | 
| Wludzik, Jozef | e236279 | 2020-10-27 17:23:55 +0100 | [diff] [blame] | 533 | return false; | 
|  | 534 | } | 
|  | 535 |  | 
|  | 536 | return true; | 
|  | 537 | } | 
| Szymon Dompke | b4ef22e | 2022-02-07 15:15:12 +0100 | [diff] [blame] | 538 |  | 
| Krzysztof Grobelny | 493e62e | 2022-02-14 10:55:50 +0100 | [diff] [blame] | 539 | interfaces::JsonStorage::FilePath Report::reportFileName() const | 
| Krzysztof Grobelny | b8cc78d | 2021-11-29 15:54:53 +0100 | [diff] [blame] | 540 | { | 
|  | 541 | return interfaces::JsonStorage::FilePath{ | 
|  | 542 | std::to_string(std::hash<std::string>{}(id))}; | 
|  | 543 | } | 
| Szymon Dompke | b4ef22e | 2022-02-07 15:15:12 +0100 | [diff] [blame] | 544 |  | 
| Krzysztof Grobelny | e6d4887 | 2022-02-08 13:41:30 +0100 | [diff] [blame] | 545 | std::unordered_set<std::string> | 
|  | 546 | Report::collectTriggerIds(boost::asio::io_context& ioc) const | 
| Szymon Dompke | b4ef22e | 2022-02-07 15:15:12 +0100 | [diff] [blame] | 547 | { | 
| Krzysztof Grobelny | e6d4887 | 2022-02-08 13:41:30 +0100 | [diff] [blame] | 548 | utils::Messanger tmp(ioc); | 
|  | 549 |  | 
|  | 550 | auto result = std::unordered_set<std::string>(); | 
|  | 551 |  | 
|  | 552 | tmp.on_receive<messages::CollectTriggerIdResp>( | 
|  | 553 | [&result](const auto& msg) { result.insert(msg.triggerId); }); | 
|  | 554 |  | 
|  | 555 | tmp.send(messages::CollectTriggerIdReq{id}); | 
|  | 556 |  | 
|  | 557 | return result; | 
| Szymon Dompke | b4ef22e | 2022-02-07 15:15:12 +0100 | [diff] [blame] | 558 | } | 
| Krzysztof Grobelny | f7ea299 | 2022-01-27 11:04:58 +0100 | [diff] [blame] | 559 |  | 
|  | 560 | void Report::metricUpdated() | 
|  | 561 | { | 
|  | 562 | if (onChangeContext) | 
|  | 563 | { | 
|  | 564 | onChangeContext->metricUpdated(); | 
|  | 565 | return; | 
|  | 566 | } | 
|  | 567 |  | 
|  | 568 | updateReadings(); | 
|  | 569 | } | 
|  | 570 |  | 
|  | 571 | void Report::updateReportingType(ReportingType newReportingType) | 
|  | 572 | { | 
|  | 573 | if (reportingType != newReportingType) | 
|  | 574 | { | 
|  | 575 | timer.cancel(); | 
|  | 576 | unregisterFromMetrics = nullptr; | 
|  | 577 | } | 
|  | 578 |  | 
|  | 579 | reportingType = newReportingType; | 
|  | 580 |  | 
|  | 581 | switch (reportingType) | 
|  | 582 | { | 
|  | 583 | case ReportingType::periodic: | 
|  | 584 | { | 
|  | 585 | scheduleTimerForPeriodicReport(interval); | 
|  | 586 | break; | 
|  | 587 | } | 
|  | 588 | case ReportingType::onChange: | 
|  | 589 | { | 
|  | 590 | unregisterFromMetrics = [this] { | 
|  | 591 | for (auto& metric : metrics) | 
|  | 592 | { | 
|  | 593 | metric->unregisterFromUpdates(*this); | 
|  | 594 | } | 
|  | 595 | }; | 
|  | 596 |  | 
|  | 597 | bool isTimerRequired = false; | 
|  | 598 |  | 
|  | 599 | for (auto& metric : metrics) | 
|  | 600 | { | 
|  | 601 | metric->registerForUpdates(*this); | 
|  | 602 | if (metric->isTimerRequired()) | 
|  | 603 | { | 
|  | 604 | isTimerRequired = true; | 
|  | 605 | } | 
|  | 606 | } | 
|  | 607 |  | 
|  | 608 | if (isTimerRequired) | 
|  | 609 | { | 
|  | 610 | scheduleTimerForOnChangeReport(); | 
|  | 611 | } | 
|  | 612 | break; | 
|  | 613 | } | 
|  | 614 | default: | 
|  | 615 | break; | 
|  | 616 | } | 
|  | 617 | } |