Kea: alarm_store.cc Source File

| Kea 3.2.0-git

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
9#include <exceptions/exceptions.h>
10#include <alarm_store.h>
11#include <util/multi_threading_mgr.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
42 AlarmPtr
43AlarmStore::checkDurationSample(DurationKeyPtr key, const Duration& sample,
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
75 AlarmPtr
76 AlarmStore::addAlarm(AlarmPtr alarm) {
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
88 AlarmPtr
89AlarmStore::addAlarm(DurationKeyPtr key, const Duration& low_water,
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
104 AlarmPtr
105AlarmStore::getAlarm(DurationKeyPtr key) {
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
116AlarmStore::updateAlarm(AlarmPtr& alarm) {
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
132AlarmStore::deleteAlarm(DurationKeyPtr key) {
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
147 AlarmCollectionPtr
148AlarmStore::getAll() {
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
160AlarmStore::clear() {
161 MultiThreadingLock lock(*mutex_);
162 alarms_.clear();
163}
164
165} // end of namespace perfmon
166} // end of namespace isc
167
alarm_store.h
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition exceptions/exceptions.h:143
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::perfmon::AlarmStore::AlarmStore
AlarmStore(uint16_t family)
Constructor.
Definition alarm_store.cc:19
isc::perfmon::AlarmStore::checkDurationSample
AlarmPtr checkDurationSample(DurationKeyPtr key, const Duration &sample, const Duration &report_interval)
Checks a sample against an alarm.
Definition alarm_store.cc:43
isc::perfmon::AlarmStore::updateAlarm
void updateAlarm(AlarmPtr &alarm)
Updates an alarm in the store.
Definition alarm_store.cc:116
isc::perfmon::AlarmStore::deleteAlarm
void deleteAlarm(DurationKeyPtr key)
Removes the alarm from the store.
Definition alarm_store.cc:132
isc::perfmon::AlarmStore::getAll
AlarmCollectionPtr getAll()
Fetches all of the alarms (in order by target).
Definition alarm_store.cc:148
isc::perfmon::AlarmStore::addAlarm
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.
Definition alarm_store.cc:89
isc::perfmon::AlarmStore::getAlarm
AlarmPtr getAlarm(DurationKeyPtr key)
Fetches a duration from the store for a given key.
Definition alarm_store.cc:105
isc::perfmon::AlarmStore::clear
void clear()
Removes all alarms from the store.
Definition alarm_store.cc:160
isc::perfmon::Alarm
Defines an alarm for a duration.
Definition alarm.h:20
isc::perfmon::DuplicateAlarm
Exception thrown when an attempt was made to add a duplicate key to either the duration or alarm stor...
Definition alarm_store.h:30
exceptions.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
multi_threading_mgr.h
isc::perfmon
Definition alarm.cc:19
isc::perfmon::Duration
boost::posix_time::time_duration Duration
Definition monitored_duration.h:21
isc::perfmon::DurationKeyPtr
boost::shared_ptr< DurationKey > DurationKeyPtr
Defines a pointer to a DurationKey instance.
Definition monitored_duration.h:321
isc::perfmon::AlarmCollection
std::vector< AlarmPtr > AlarmCollection
Type for a collection of AlarmPtrs.
Definition alarm_store.h:62
isc::perfmon::AlarmCollectionPtr
boost::shared_ptr< AlarmCollection > AlarmCollectionPtr
Type for a pointer to a collection of AlarmPtrs.
Definition alarm_store.h:65
isc::perfmon::AlarmPtr
boost::shared_ptr< Alarm > AlarmPtr
Defines a pointer to an Alarm instance.
Definition alarm.h:168
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
isc::perfmon::AlarmPrimaryKeyTag
Tag for index by primary key (DurationKey).
Definition alarm_store.h:37
isc::util::MultiThreadingLock
RAII lock object to protect the code in the same scope with a mutex.
Definition multi_threading_mgr.h:349