Kea 2.7.6
alarm_store.cc
Go to the documentation of this file.
1// Copyright (C) 2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
10#include <alarm_store.h>
12
13using namespace isc;
14using namespace isc::util;
15
16namespace isc {
17namespace perfmon {
18
19AlarmStore::AlarmStore(uint16_t family)
20 : family_(family),
21 alarms_(),
22 mutex_(new std::mutex) {
23 if (family_ != AF_INET && family_ != AF_INET6) {
24 isc_throw(BadValue, "AlarmStore - invalid family "
25 << family_ << ", must be AF_INET or AF_INET6");
26 }
27}
28
29void
30AlarmStore::validateKey(const std::string& label, DurationKeyPtr key) const {
31 if (!key) {
32 isc_throw(BadValue, "AlarmStore::" << label << " - key is empty");
33 }
34
35 if (key->getFamily() != family_) {
36 isc_throw(BadValue, "AlarmStore::" << label
37 << " - family mismatch, key is " << (family_ == AF_INET ?
38 "v6, store is v4" : "v4, store is v6"));
39 }
40}
41
44 const Duration& report_interval) {
45 validateKey("checkDurationSample", key);
46
47 MultiThreadingLock lock(*mutex_);
48 auto& index = alarms_.get<AlarmPrimaryKeyTag>();
49 auto alarm_iter = index.find(*key);
50
51 // If we find an alarm then we check the sample. Alarm::checkSample()
52 // does not alter the key so it can be done in-place.
53 if (alarm_iter != index.end()) {
54 bool should_report = false;
55 bool modified = index.modify(alarm_iter,
56 [sample, report_interval, &should_report](AlarmPtr alarm) {
57 should_report = alarm->checkSample(sample, report_interval);
58 });
59
60 if (!modified) {
61 // Possible but unlikely.
62 isc_throw(Unexpected, "AlarmStore::checkDurationSample - modify failed for: " << key->getLabel());
63 }
64
65 if (should_report) {
66 // Alarm state needs to be reported, return a copy of the alarm.
67 return (AlarmPtr(new Alarm(**alarm_iter)));
68 }
69 }
70
71 // Nothing to alarm.
72 return (AlarmPtr());
73}
74
77 MultiThreadingLock lock(*mutex_);
78 auto ret = alarms_.insert(alarm);
79 if (ret.second == false) {
80 isc_throw(DuplicateAlarm, "AlarmStore::addAlarm: alarm already exists for: "
81 << alarm->getLabel());
82 }
83
84 // Return a copy of what we inserted.
85 return (AlarmPtr(new Alarm(*alarm)));
86}
87
90 const Duration& high_water, bool enabled /* = true */) {
91 validateKey("addAlarm", key);
92
93 // Create the alarm instance.
94 AlarmPtr alarm;
95 try {
96 alarm.reset(new Alarm(*key, low_water, high_water, enabled));
97 } catch (const std::exception& ex) {
98 isc_throw(BadValue, "AlarmStore::addAlarm failed: " << ex.what());
99 }
100
101 return (addAlarm(alarm));
102}
103
106 validateKey("getAlarm", key);
107
108 MultiThreadingLock lock(*mutex_);
109 const auto& index = alarms_.get<AlarmPrimaryKeyTag>();
110 auto alarm_iter = index.find(*key);
111 return (alarm_iter == index.end() ? AlarmPtr()
112 : AlarmPtr(new Alarm(**alarm_iter)));
113}
114
115void
117 validateKey("updateAlarm", alarm);
118
119 MultiThreadingLock lock(*mutex_);
120 auto& index = alarms_.get<AlarmPrimaryKeyTag>();
121 auto alarm_iter = index.find(*alarm);
122 if (alarm_iter == index.end()) {
123 isc_throw(InvalidOperation, "AlarmStore::updateAlarm alarm not found: "
124 << alarm->getLabel());
125 }
126
127 // Use replace() which only re-indexes if keys change.
128 index.replace(alarm_iter, AlarmPtr(new Alarm(*alarm)));
129}
130
131void
133 validateKey("deleteAlarm", key);
134
135 MultiThreadingLock lock(*mutex_);
136 auto& index = alarms_.get<AlarmPrimaryKeyTag>();
137 auto alarm_iter = index.find(*key);
138 if (alarm_iter == index.end()) {
139 // Not there, just return.
140 return;
141 }
142
143 // Remove the alarm from the store.
144 alarms_.erase(alarm_iter);
145}
146
149 MultiThreadingLock lock(*mutex_);
150 const auto& index = alarms_.get<AlarmPrimaryKeyTag>();
151 AlarmCollectionPtr collection(new AlarmCollection());
152 for (auto const& alarm : index) {
153 collection->push_back(AlarmPtr(new Alarm(*alarm)));
154 }
155
156 return (collection);
157}
158
159void
161 MultiThreadingLock lock(*mutex_);
162 alarms_.clear();
163}
164
165} // end of namespace perfmon
166} // end of namespace isc
167
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
AlarmStore(uint16_t family)
Constructor.
AlarmPtr checkDurationSample(DurationKeyPtr key, const Duration &sample, const Duration &report_interval)
Checks a sample against an alarm.
void updateAlarm(AlarmPtr &alarm)
Updates an alarm in the store.
void deleteAlarm(DurationKeyPtr key)
Removes the alarm from the store.
AlarmCollectionPtr getAll()
Fetches all of the alarms (in order by target)
AlarmPtr addAlarm(DurationKeyPtr key, const Duration &low_water, const Duration &high_water, bool enabled=true)
Creates a new alarm and adds it to the store.
AlarmPtr getAlarm(DurationKeyPtr key)
Fetches a duration from the store for a given key.
void clear()
Removes all alarms from the store.
Defines an alarm for a duration.
Definition alarm.h:20
Exception thrown when an attempt was made to add a duplicate key to either the duration or alarm stor...
Definition alarm_store.h:30
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::posix_time::time_duration Duration
boost::shared_ptr< DurationKey > DurationKeyPtr
Defines a pointer to a DurationKey instance.
std::vector< AlarmPtr > AlarmCollection
Type for a collection of AlarmPtrs.
Definition alarm_store.h:62
boost::shared_ptr< AlarmCollection > AlarmCollectionPtr
Type for a pointer to a collection of AlarmPtrs.
Definition alarm_store.h:65
boost::shared_ptr< Alarm > AlarmPtr
Defines a pointer to an Alarm instance.
Definition alarm.h:168
Defines the logger used by the top-level component of kea-lfc.
Tag for index by primary key (DurationKey).
Definition alarm_store.h:37
RAII lock object to protect the code in the same scope with a mutex.