blob: 9f0ce3ea24486cc8a8731ce10fcd223699b8e2b5 [file] [log] [blame]
Brad Bishop4041d722017-05-21 10:06:07 -04001#pragma once
2
3#include "callback.hpp"
4#include "data_types.hpp"
5
Ratan Gupta882d7412018-02-19 23:43:44 +05306#include <algorithm>
Brad Bishop35e75f02018-02-26 09:43:41 -05007#include <functional>
Ratan Gupta882d7412018-02-19 23:43:44 +05308
Brad Bishop4041d722017-05-21 10:06:07 -04009namespace phosphor
10{
11namespace dbus
12{
13namespace monitoring
14{
15
16/** @class CountCondition
17 * @brief Count properties that satisfy a condition.
18 *
19 * When invoked, a count class instance performs its condition
20 * test in two passes.
21 *
22 * In pass one, apply a C++ relational operator to the value of
23 * each property in the index and a value provided by the
24 * configuration file.
25 *
26 * Count the number of properties that pass the test in pass
27 * one. In pass two, apply a second C++ relational operator
28 * to the number of properties that pass the test from pass one
29 * to a count provided by the configuration file.
Matt Spinlerc458dee2018-02-19 13:09:10 -060030 *
31 * If the oneshot parameter is true, then this condition won't pass
32 * again until it fails at least once.
Brad Bishop4041d722017-05-21 10:06:07 -040033 */
34template <typename T>
35class CountCondition : public IndexedConditional
36{
37 public:
38 CountCondition() = delete;
39 CountCondition(const CountCondition&) = default;
40 CountCondition(CountCondition&&) = default;
41 CountCondition& operator=(const CountCondition&) = default;
42 CountCondition& operator=(CountCondition&&) = default;
43 ~CountCondition() = default;
44
45 CountCondition(
46 const PropertyIndex& conditionIndex,
47 const std::function<bool(size_t)>& _countOp,
Matt Spinlerc458dee2018-02-19 13:09:10 -060048 const std::function<bool(T)>& _propertyOp,
49 bool oneshot = false) :
Brad Bishop4041d722017-05-21 10:06:07 -040050 IndexedConditional(conditionIndex),
51 countOp(_countOp),
Matt Spinlerc458dee2018-02-19 13:09:10 -060052 propertyOp(_propertyOp),
53 oneshot(oneshot) {}
Brad Bishop4041d722017-05-21 10:06:07 -040054
55 bool operator()() override
56 {
57 // Count the number of properties in the index that
58 // pass the condition specified in the config file.
59 auto count = std::count_if(
60 index.cbegin(),
61 index.cend(),
62 [this](const auto & item)
63 // *INDENT-OFF*
64 {
Matt Spinler05a2ac32018-02-19 13:52:59 -060065 //Get the property value from storage[0],
66 //and save the op result in storage[1].
Matt Spinler1abcb062018-02-26 09:14:31 -060067 const auto& storage = std::get<storageIndex>(
Brad Bishop4041d722017-05-21 10:06:07 -040068 item.second);
69 // Don't count properties that don't exist.
Matt Spinler1abcb062018-02-26 09:14:31 -060070 if (std::get<valueIndex>(
71 storage.get()).empty())
Brad Bishop4041d722017-05-21 10:06:07 -040072 {
73 return false;
74 }
75 const auto& value = any_ns::any_cast<T>(
Matt Spinler1abcb062018-02-26 09:14:31 -060076 std::get<valueIndex>(storage.get()));
Matt Spinler05a2ac32018-02-19 13:52:59 -060077 auto r = propertyOp(value);
78
Matt Spinler1abcb062018-02-26 09:14:31 -060079 std::get<resultIndex>(storage.get()) = r;
Matt Spinler05a2ac32018-02-19 13:52:59 -060080
81 return r;
Brad Bishop4041d722017-05-21 10:06:07 -040082 });
83 // *INDENT-ON*
84
85 // Now apply the count condition to the count.
Matt Spinlerc458dee2018-02-19 13:09:10 -060086 auto result = countOp(count);
87
88 // If this was a oneshot and the the condition has already
89 // passed, then don't let it pass again until the condition
90 // has gone back to false.
91 if (oneshot && result && lastResult)
92 {
93 return false;
94 }
95
96 lastResult = result;
97 return result;
Brad Bishop4041d722017-05-21 10:06:07 -040098 }
99
100 private:
101 /** @brief The comparison to perform on the count. */
102 std::function<bool(size_t)> countOp;
103 /** @brief The comparison to perform on each property. */
104 std::function<bool(T)> propertyOp;
Matt Spinlerc458dee2018-02-19 13:09:10 -0600105 /** @brief If the condition can be allowed to pass again
106 on subsequent checks that are also true. */
107 const bool oneshot;
108 /** @brief The result of the previous check. */
109 bool lastResult = false;
Brad Bishop4041d722017-05-21 10:06:07 -0400110};
111} // namespace monitoring
112} // namespace dbus
113} // namespace phosphor