: std::vector<std::string>());
}
+HookLibsCollection
+HooksManager::getLibraryInfoInternal() const {
+ return (lm_collection_ ? lm_collection_->getLibraryInfo()
+ : HookLibsCollection());
+}
+
std::vector<std::string>
HooksManager::getLibraryNames() {
return (getHooksManager().getLibraryNamesInternal());
HookLibsCollection
HooksManager::getLibraryInfo() {
- return (getHooksManager().getLibraryInfo());
+ return (getHooksManager().getLibraryInfoInternal());
}
// Perform conditional initialization if nothing is loaded.
/// @return List of loaded library names.
std::vector<std::string> getLibraryNamesInternal() const;
+ /// @brief Return a collection of library names with parameters.
+ HookLibsCollection getLibraryInfoInternal() const;
+
//@}
/// @brief Initialization to No Libraries
#include <hooks/callout_manager.h>
#include <hooks/library_handle.h>
+#include <hooks/hooks_manager.h>
namespace isc {
namespace hooks {
return (status);
}
+isc::data::ConstElementPtr
+LibraryHandle::getParameter(const std::string& name) {
+ HookLibsCollection libinfo = HooksManager::getHooksManager().getLibraryInfo();
+
+ if ((index_ >= libinfo.size()) || (index_ < 0)) {
+ // Something is very wrong here. However, this is user facing
+ // interface, so we should not throw here.
+ return (isc::data::ConstElementPtr());
+ }
+
+ // Try to find appropriate parameter. May return NULL
+ return (libinfo[index_].second->get(name));
+}
+
} // namespace util
} // namespace isc
#define LIBRARY_HANDLE_H
#include <string>
+#include <cc/data.h>
namespace isc {
namespace hooks {
/// @throw NoSuchHook Thrown if the hook name is unrecognized.
bool deregisterAllCallouts(const std::string& name);
+
+ /// @brief Returns configuration parameter for the library.
+ ///
+ /// This method returns configuration parameters specified in the
+ /// configuration file. Here's the example. Let's assume that there
+ /// are two hook libraries configured:
+ ///
+ /// "hooks-libraries": [
+ /// {
+ /// "library": "/opt/charging.so",
+ /// "parameters": {}
+ /// },
+ /// {
+ /// "library": "/opt/local/notification.so",
+ /// "parameters": {
+ /// "mail": "alarm@example.com",
+ /// "floor": 42,
+ /// "debug": false,
+ /// "users": [ "alice", "bob", "charlie" ],
+ /// "header": {
+ /// "french": "bonjour",
+ /// "klingon": "yl'el"
+ /// }
+ /// }
+ /// }
+ ///]
+ ///
+ /// The first library has no parameters, so regardles of the name
+ /// specified, for that library getParameter will always return NULL.
+ ///
+ /// For the second paramter, depending the following calls will return:
+ /// - x = getParameter("mail") will return instance of
+ /// isc::data::StringElement. The content can be accessed with
+ /// x->stringValue() and will return std::string.
+ /// - x = getParameter("floor") will return an instance of isc::data::IntElement.
+ /// The content can be accessed with x->intValue() and will return int.
+ /// - x = getParameter("debug") will return an instance of isc::data::BoolElement.
+ /// Its value can be accessed with x->boolValue() and will return bool.
+ /// - x = getParameter("users") will return an instance of ListElement.
+ /// Its content can be accessed with the following methods:
+ /// x->size(), x->get(index)
+ /// - x = getParameter("watch-list") will return an instance of isc::data::MapElement.
+ /// Its content can be accessed with the following methods:
+ /// x->find("klingon"), x->contains("french"), x->size()
+ ///
+ /// For more examples and complete API, see documentation for
+ /// @ref isc::data::Element class and its derivatives:
+ /// - @ref isc::data::IntElement
+ /// - @ref isc::data::DoubleElement
+ /// - @ref isc::data::BoolElement
+ /// - @ref isc::data::StringElement
+ /// - @ref isc::data::ListElement
+ /// - @ref isc::data::MapElement
+ ///
+ /// Another good way to learn how to use Element interface is to look at the
+ /// unittests in data_unittests.cc.
+ ///
+ /// @param name text name of the parameter.
+ isc::data::ConstElementPtr
+ getParameter(const std::string& name);
+
private:
/// @brief Copy constructor
///
# ignored for unit tests built here.
noinst_LTLIBRARIES = libnvl.la libivl.la libfxl.la libbcl.la liblcl.la \
- liblecl.la libucl.la libfcl.la
+ liblecl.la libucl.la libfcl.la libpcl.la
# -rpath /nowhere is a hack to trigger libtool to not create a
# convenience archive, resulting in shared modules
libfcl_la_CPPFLAGS = $(AM_CPPFLAGS)
libfcl_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere
+# The parameters checking callout library - expects
+libpcl_la_SOURCES = callout_params_library.cc
+libpcl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libpcl_la_CPPFLAGS = $(AM_CPPFLAGS)
+libpcl_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere
+libpcl_la_LDFLAGS += $(top_builddir)/src/lib/util/libkea-util.la
+
TESTS += run_unittests
run_unittests_SOURCES = run_unittests.cc
run_unittests_SOURCES += callout_handle_unittest.cc
#include <hooks/tests/common_test_class.h>
#include <hooks/tests/test_libraries.h>
+#include <cc/data.h>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h>
#include <algorithm>
#include <string>
-
using namespace isc;
using namespace isc::hooks;
+using namespace isc::data;
using namespace std;
namespace {
EXPECT_TRUE(failed == expected_failures);
}
+// This test verifies that the specified parameters are accessed properly.
+TEST_F(HooksManagerTest, LibraryParameters) {
+
+ // Prepare paramters for the callout parameters library.
+ ElementPtr params = Element::createMap();
+ params->set("svalue", Element::create("string value"));
+ params->set("ivalue", Element::create(42));
+ params->set("bvalue", Element::create(true));
+
+ // Set up the list of libraries to be loaded.
+ HookLibsCollection library_names;
+ library_names.push_back(make_pair(std::string(BASIC_CALLOUT_LIBRARY),
+ data::ConstElementPtr()));
+ library_names.push_back(make_pair(std::string(CALLOUT_PARAMS_LIBRARY),
+ params));
+
+ // Load the libraries. Note that callout params library checks if
+ // all mandatory parameters are there, so if anything is missing, its
+ // load() function will return error, thus causing the library to not
+ // load.
+ EXPECT_TRUE(HooksManager::loadLibraries(library_names));
+
+ // Try unloading the libraries.
+ EXPECT_NO_THROW(HooksManager::unloadLibraries());
+}
+
} // Anonymous namespace
libraries.push_back(BASIC_CALLOUT_LIBRARY);
libraries.push_back(FULL_CALLOUT_LIBRARY);
libraries.push_back(UNLOAD_CALLOUT_LIBRARY);
+ libraries.push_back(CALLOUT_PARAMS_LIBRARY);
failed = LibraryManagerCollection::validateLibraries(libraries);
EXPECT_TRUE(failed.empty());
EXPECT_FALSE(LibraryManager::validateLibrary(NOT_PRESENT_LIBRARY));
EXPECT_FALSE(LibraryManager::validateLibrary(NO_VERSION_LIBRARY));
EXPECT_TRUE(LibraryManager::validateLibrary(UNLOAD_CALLOUT_LIBRARY));
+ EXPECT_TRUE(LibraryManager::validateLibrary(CALLOUT_PARAMS_LIBRARY));
}
// Check that log messages are properly registered and unregistered.
// Library where there is an unload() function.
static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl.so";
+// Library where parameters are checked.
+static const char* CALLOUT_PARAMS_LIBRARY = "@abs_builddir@/.libs/libpcl.so";
+
} // anonymous namespace