summaryrefslogtreecommitdiffstats
path: root/src/lib/hooks/hooks_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hooks/hooks_manager.cc')
-rw-r--r--src/lib/hooks/hooks_manager.cc275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/lib/hooks/hooks_manager.cc b/src/lib/hooks/hooks_manager.cc
new file mode 100644
index 0000000..82b741e
--- /dev/null
+++ b/src/lib/hooks/hooks_manager.cc
@@ -0,0 +1,275 @@
+// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <hooks/callout_handle.h>
+#include <hooks/callout_manager.h>
+#include <hooks/library_handle.h>
+#include <hooks/library_manager_collection.h>
+#include <hooks/hooks_manager.h>
+#include <hooks/server_hooks.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+namespace isc {
+namespace hooks {
+
+// Constructor
+
+HooksManager::HooksManager() : test_mode_(false) {
+ // Nothing present, so create the collection with any empty set of
+ // libraries, and get the CalloutManager.
+ HookLibsCollection libraries;
+ lm_collection_.reset(new LibraryManagerCollection(libraries));
+ lm_collection_->loadLibraries();
+ callout_manager_ = lm_collection_->getCalloutManager();
+}
+
+// Return reference to singleton hooks manager.
+
+HooksManager&
+HooksManager::getHooksManager() {
+ static HooksManager manager;
+ return (manager);
+}
+
+// Are callouts present?
+
+bool
+HooksManager::calloutsPresentInternal(int index) {
+ return (callout_manager_->calloutsPresent(index));
+}
+
+bool
+HooksManager::calloutsPresent(int index) {
+ return (getHooksManager().calloutsPresentInternal(index));
+}
+
+bool
+HooksManager::commandHandlersPresentInternal(const std::string& command_name) {
+ return (callout_manager_->commandHandlersPresent(command_name));
+}
+
+bool
+HooksManager::commandHandlersPresent(const std::string& command_name) {
+ return (getHooksManager().commandHandlersPresentInternal(command_name));
+}
+
+// Call the callouts
+
+void
+HooksManager::callCalloutsInternal(int index, CalloutHandle& handle) {
+ callout_manager_->callCallouts(index, handle);
+}
+
+void
+HooksManager::callCallouts(int index, CalloutHandle& handle) {
+ getHooksManager().callCalloutsInternal(index, handle);
+}
+
+void
+HooksManager::callCommandHandlersInternal(const std::string& command_name,
+ CalloutHandle& handle) {
+ callout_manager_->callCommandHandlers(command_name, handle);
+}
+
+void
+HooksManager::callCommandHandlers(const std::string& command_name,
+ CalloutHandle& handle) {
+ getHooksManager().callCommandHandlersInternal(command_name, handle);
+}
+
+// Load the libraries. This will delete the previously-loaded libraries
+// (if present) and load new ones. If loading libraries fails, initialize with
+// empty list.
+
+bool
+HooksManager::loadLibrariesInternal(const HookLibsCollection& libraries) {
+ if (test_mode_) {
+ return (true);
+ }
+
+ ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
+
+ // Keep a weak pointer on the existing library manager collection.
+ boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
+
+ // Create the library manager collection.
+ lm_collection_.reset(new LibraryManagerCollection(libraries));
+
+ // If there was another owner the previous library manager collection
+ // was not destroyed and libraries not closed.
+ if (!weak_lmc.expired()) {
+ isc_throw(LibrariesStillOpened, "some libraries are still opened");
+ }
+
+ // Load the libraries.
+ bool status = lm_collection_->loadLibraries();
+
+ if (status) {
+ // ... and obtain the callout manager for them if successful.
+ callout_manager_ = lm_collection_->getCalloutManager();
+ } else {
+ // Unable to load libraries, reset to state before this function was
+ // called.
+ static_cast<void>(unloadLibrariesInternal());
+ }
+
+ return (status);
+}
+
+bool
+HooksManager::loadLibraries(const HookLibsCollection& libraries) {
+ return (getHooksManager().loadLibrariesInternal(libraries));
+}
+
+// Unload the libraries. This just deletes all internal objects (which will
+// cause the libraries to be unloaded) and initializes them with empty list if
+// requested.
+
+bool
+HooksManager::unloadLibrariesInternal() {
+ if (test_mode_) {
+ return (true);
+ }
+
+ ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
+
+ // Keep a weak pointer on the existing library manager collection.
+ boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
+
+ // Create the collection with any empty set of libraries.
+ HookLibsCollection libraries;
+ lm_collection_.reset(new LibraryManagerCollection(libraries));
+
+ // If there was another owner the previous library manager collection
+ // was not destroyed and libraries not closed.
+ boost::shared_ptr<LibraryManagerCollection> still_here = weak_lmc.lock();
+ if (still_here) {
+ // Restore the library manager collection.
+ lm_collection_ = still_here;
+ return (false);
+ }
+
+ // Load the empty set of libraries.
+ lm_collection_->loadLibraries();
+
+ // Get the CalloutManager.
+ callout_manager_ = lm_collection_->getCalloutManager();
+
+ return (true);
+}
+
+bool
+HooksManager::unloadLibraries() {
+ return (getHooksManager().unloadLibrariesInternal());
+}
+
+void
+HooksManager::prepareUnloadLibrariesInternal() {
+ if (test_mode_) {
+ return;
+ }
+
+ static_cast<void>(lm_collection_->prepareUnloadLibraries());
+}
+
+void
+HooksManager::prepareUnloadLibraries() {
+ getHooksManager().prepareUnloadLibrariesInternal();
+}
+
+// Create a callout handle
+
+boost::shared_ptr<CalloutHandle>
+HooksManager::createCalloutHandleInternal() {
+ return (boost::make_shared<CalloutHandle>(callout_manager_, lm_collection_));
+}
+
+boost::shared_ptr<CalloutHandle>
+HooksManager::createCalloutHandle() {
+ return (getHooksManager().createCalloutHandleInternal());
+}
+
+// Get the list of the names of loaded libraries.
+
+std::vector<std::string>
+HooksManager::getLibraryNamesInternal() const {
+ return (lm_collection_->getLibraryNames());
+}
+
+HookLibsCollection
+HooksManager::getLibraryInfoInternal() const {
+ return (lm_collection_->getLibraryInfo());
+}
+
+std::vector<std::string>
+HooksManager::getLibraryNames() {
+ return (getHooksManager().getLibraryNamesInternal());
+}
+
+HookLibsCollection
+HooksManager::getLibraryInfo() {
+ return (getHooksManager().getLibraryInfoInternal());
+}
+
+// Shell around ServerHooks::registerHook()
+
+int
+HooksManager::registerHook(const std::string& name) {
+ return (ServerHooks::getServerHooks().registerHook(name));
+}
+
+// Return pre- and post- library handles.
+
+isc::hooks::LibraryHandle&
+HooksManager::preCalloutsLibraryHandleInternal() {
+ return (callout_manager_->getPreLibraryHandle());
+}
+
+isc::hooks::LibraryHandle&
+HooksManager::preCalloutsLibraryHandle() {
+ return (getHooksManager().preCalloutsLibraryHandleInternal());
+}
+
+isc::hooks::LibraryHandle&
+HooksManager::postCalloutsLibraryHandleInternal() {
+ return (callout_manager_->getPostLibraryHandle());
+}
+
+isc::hooks::LibraryHandle&
+HooksManager::postCalloutsLibraryHandle() {
+ return (getHooksManager().postCalloutsLibraryHandleInternal());
+}
+
+// Validate libraries
+
+std::vector<std::string>
+HooksManager::validateLibraries(const std::vector<std::string>& libraries) {
+ return (LibraryManagerCollection::validateLibraries(libraries));
+}
+
+// Test mode
+
+void
+HooksManager::setTestMode(bool mode) {
+ getHooksManager().test_mode_ = mode;
+}
+
+bool
+HooksManager::getTestMode() {
+ return (getHooksManager().test_mode_);
+}
+
+} // namespace util
+} // namespace isc