Kea  1.9.9-git
hooks_manager.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2020 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 <hooks/callout_handle.h>
10 #include <hooks/callout_manager.h>
11 #include <hooks/library_handle.h>
13 #include <hooks/hooks_manager.h>
14 #include <hooks/server_hooks.h>
15 
16 #include <boost/shared_ptr.hpp>
17 #include <boost/weak_ptr.hpp>
18 
19 #include <string>
20 #include <vector>
21 
22 using namespace std;
23 
24 namespace isc {
25 namespace hooks {
26 
27 // Constructor
28 
29 HooksManager::HooksManager() : test_mode_(false) {
30  // Nothing present, so create the collection with any empty set of
31  // libraries, and get the CalloutManager.
32  HookLibsCollection libraries;
33  lm_collection_.reset(new LibraryManagerCollection(libraries));
34  lm_collection_->loadLibraries();
35  callout_manager_ = lm_collection_->getCalloutManager();
36 }
37 
38 // Return reference to singleton hooks manager.
39 
40 HooksManager&
41 HooksManager::getHooksManager() {
42  static HooksManager manager;
43  return (manager);
44 }
45 
46 // Are callouts present?
47 
48 bool
49 HooksManager::calloutsPresentInternal(int index) {
50  return (callout_manager_->calloutsPresent(index));
51 }
52 
53 bool
54 HooksManager::calloutsPresent(int index) {
55  return (getHooksManager().calloutsPresentInternal(index));
56 }
57 
58 bool
59 HooksManager::commandHandlersPresentInternal(const std::string& command_name) {
60  return (callout_manager_->commandHandlersPresent(command_name));
61 }
62 
63 bool
64 HooksManager::commandHandlersPresent(const std::string& command_name) {
65  return (getHooksManager().commandHandlersPresentInternal(command_name));
66 }
67 
68 // Call the callouts
69 
70 void
71 HooksManager::callCalloutsInternal(int index, CalloutHandle& handle) {
72  callout_manager_->callCallouts(index, handle);
73 }
74 
75 void
76 HooksManager::callCallouts(int index, CalloutHandle& handle) {
77  getHooksManager().callCalloutsInternal(index, handle);
78 }
79 
80 void
81 HooksManager::callCommandHandlersInternal(const std::string& command_name,
82  CalloutHandle& handle) {
83  callout_manager_->callCommandHandlers(command_name, handle);
84 }
85 
86 void
87 HooksManager::callCommandHandlers(const std::string& command_name,
88  CalloutHandle& handle) {
89  getHooksManager().callCommandHandlersInternal(command_name, handle);
90 }
91 
92 // Load the libraries. This will delete the previously-loaded libraries
93 // (if present) and load new ones. If loading libraries fails, initialize with
94 // empty list.
95 
96 bool
97 HooksManager::loadLibrariesInternal(const HookLibsCollection& libraries) {
98  if (test_mode_) {
99  return (true);
100  }
101 
102  ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
103 
104  // Keep a weak pointer on the existing library manager collection.
105  boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
106 
107  // Create the library manager collection.
108  lm_collection_.reset(new LibraryManagerCollection(libraries));
109 
110  // If there was another owner the previous library manager collection
111  // was not destroyed and libraries not closed.
112  if (!weak_lmc.expired()) {
113  isc_throw(LibrariesStillOpened, "some libraries are still opened");
114  }
115 
116  // Load the libraries.
117  bool status = lm_collection_->loadLibraries();
118 
119  if (status) {
120  // ... and obtain the callout manager for them if successful.
121  callout_manager_ = lm_collection_->getCalloutManager();
122  } else {
123  // Unable to load libraries, reset to state before this function was
124  // called.
125  static_cast<void>(unloadLibrariesInternal());
126  }
127 
128  return (status);
129 }
130 
131 bool
132 HooksManager::loadLibraries(const HookLibsCollection& libraries) {
133  return (getHooksManager().loadLibrariesInternal(libraries));
134 }
135 
136 // Unload the libraries. This just deletes all internal objects (which will
137 // cause the libraries to be unloaded) and initializes them with empty list if
138 // requested.
139 
140 bool
141 HooksManager::unloadLibrariesInternal() {
142  if (test_mode_) {
143  return (true);
144  }
145 
146  ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
147 
148  // Keep a weak pointer on the existing library manager collection.
149  boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
150 
151  // Create the collection with any empty set of libraries.
152  HookLibsCollection libraries;
153  lm_collection_.reset(new LibraryManagerCollection(libraries));
154 
155  // If there was another owner the previous library manager collection
156  // was not destroyed and libraries not closed.
157  boost::shared_ptr<LibraryManagerCollection> still_here = weak_lmc.lock();
158  if (still_here) {
159  // Restore the library manager collection.
160  lm_collection_ = still_here;
161  return (false);
162  }
163 
164  // Load the empty set of libraries.
165  lm_collection_->loadLibraries();
166 
167  // Get the CalloutManager.
168  callout_manager_ = lm_collection_->getCalloutManager();
169 
170  return (true);
171 }
172 
173 bool
174 HooksManager::unloadLibraries() {
175  return (getHooksManager().unloadLibrariesInternal());
176 }
177 
178 void
179 HooksManager::prepareUnloadLibrariesInternal() {
180  if (test_mode_) {
181  return;
182  }
183 
184  static_cast<void>(lm_collection_->prepareUnloadLibraries());
185 }
186 
187 void
188 HooksManager::prepareUnloadLibraries() {
189  getHooksManager().prepareUnloadLibrariesInternal();
190 }
191 
192 // Create a callout handle
193 
194 boost::shared_ptr<CalloutHandle>
195 HooksManager::createCalloutHandleInternal() {
196  return (boost::make_shared<CalloutHandle>(callout_manager_, lm_collection_));
197 }
198 
199 boost::shared_ptr<CalloutHandle>
200 HooksManager::createCalloutHandle() {
201  return (getHooksManager().createCalloutHandleInternal());
202 }
203 
204 // Get the list of the names of loaded libraries.
205 
206 std::vector<std::string>
207 HooksManager::getLibraryNamesInternal() const {
208  return (lm_collection_->getLibraryNames());
209 }
210 
212 HooksManager::getLibraryInfoInternal() const {
213  return (lm_collection_->getLibraryInfo());
214 }
215 
216 std::vector<std::string>
217 HooksManager::getLibraryNames() {
218  return (getHooksManager().getLibraryNamesInternal());
219 }
220 
222 HooksManager::getLibraryInfo() {
223  return (getHooksManager().getLibraryInfoInternal());
224 }
225 
226 // Shell around ServerHooks::registerHook()
227 
228 int
229 HooksManager::registerHook(const std::string& name) {
230  return (ServerHooks::getServerHooks().registerHook(name));
231 }
232 
233 // Return pre- and post- library handles.
234 
236 HooksManager::preCalloutsLibraryHandleInternal() {
237  return (callout_manager_->getPreLibraryHandle());
238 }
239 
241 HooksManager::preCalloutsLibraryHandle() {
242  return (getHooksManager().preCalloutsLibraryHandleInternal());
243 }
244 
246 HooksManager::postCalloutsLibraryHandleInternal() {
247  return (callout_manager_->getPostLibraryHandle());
248 }
249 
251 HooksManager::postCalloutsLibraryHandle() {
252  return (getHooksManager().postCalloutsLibraryHandleInternal());
253 }
254 
255 // Validate libraries
256 
257 std::vector<std::string>
258 HooksManager::validateLibraries(const std::vector<std::string>& libraries) {
259  return (LibraryManagerCollection::validateLibraries(libraries));
260 }
261 
262 // Test mode
263 
264 void
265 HooksManager::setTestMode(bool mode) {
266  getHooksManager().test_mode_ = mode;
267 }
268 
269 bool
270 HooksManager::getTestMode() {
271  return (getHooksManager().test_mode_);
272 }
273 
274 } // namespace util
275 } // namespace isc
STL namespace.
std::vector< HookLibInfo > HookLibsCollection
A storage for information about hook libraries.
Definition: libinfo.h:31
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Per-packet callout handle.
Defines the logger used by the top-level component of kea-dhcp-ddns.