server_hooks.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright (C) 2013-2017 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. #ifndef SERVER_HOOKS_H
  7. #define SERVER_HOOKS_H
  8. #include <exceptions/exceptions.h>
  9. #include <boost/noncopyable.hpp>
  10. #include <boost/shared_ptr.hpp>
  11. #include <map>
  12. #include <string>
  13. #include <vector>
  14. namespace isc {
  15. namespace hooks {
  16. /// @brief Duplicate hook
  17. ///
  18. /// Thrown if an attempt is made to register a hook with the same name as a
  19. /// previously-registered hook.
  20. class DuplicateHook : public Exception {
  21. public:
  22. DuplicateHook(const char* file, size_t line, const char* what) :
  23. isc::Exception(file, line, what) {}
  24. };
  25. /// @brief Invalid hook
  26. ///
  27. /// Thrown if an attempt is made to get the index for an invalid hook.
  28. class NoSuchHook : public Exception {
  29. public:
  30. NoSuchHook(const char* file, size_t line, const char* what) :
  31. isc::Exception(file, line, what) {}
  32. };
  33. class ServerHooks;
  34. typedef boost::shared_ptr<ServerHooks> ServerHooksPtr;
  35. /// @brief Server hook collection
  36. ///
  37. /// This class is used by the server-side code to register hooks - points in the
  38. /// server processing at which libraries can register functions (callouts) that
  39. /// the server will call. These functions can modify data and so affect the
  40. /// processing of the server.
  41. ///
  42. /// The ServerHooks class is little more than a wrapper around the std::map
  43. /// class. It stores a hook, assigning to it a unique index number. This
  44. /// number is then used by the server code to identify the hook being called.
  45. /// (Although it would be feasible to use a name as an index, using an integer
  46. /// will speed up the time taken to locate the callouts, which may make a
  47. /// difference in a frequently-executed piece of code.)
  48. ///
  49. /// ServerHooks is a singleton object and is only accessible by the static
  50. /// method getServerHooks().
  51. class ServerHooks : public boost::noncopyable {
  52. public:
  53. /// Index numbers for pre-defined hooks.
  54. static const int CONTEXT_CREATE = 0;
  55. static const int CONTEXT_DESTROY = 1;
  56. /// @brief Reset to Initial State
  57. ///
  58. /// Resets the collection of hooks to the initial state, with just the
  59. /// context_create and context_destroy hooks set. This used during
  60. /// testing to reset the global ServerHooks object; it should never be
  61. /// used in production.
  62. ///
  63. /// @throws isc::Unexpected if the registration of the pre-defined hooks
  64. /// fails in some way.
  65. void reset();
  66. /// @brief Register a hook
  67. ///
  68. /// Registers a hook and returns the hook index.
  69. ///
  70. /// @param name Name of the hook
  71. ///
  72. /// @return Index of the hook, to be used in subsequent hook-related calls.
  73. /// This will be greater than or equal to zero (so allowing a
  74. /// negative value to indicate an invalid index).
  75. ///
  76. /// @throws DuplicateHook A hook with the same name has already been
  77. /// registered.
  78. int registerHook(const std::string& name);
  79. /// @brief Get hook name
  80. ///
  81. /// Returns the name of a hook given the index. This is most likely to be
  82. /// used in log messages.
  83. ///
  84. /// @param index Index of the hoold
  85. ///
  86. /// @return Name of the hook.
  87. ///
  88. /// @throw NoSuchHook if the hook index is invalid.
  89. std::string getName(int index) const;
  90. /// @brief Get hook index
  91. ///
  92. /// Returns the index of a hook.
  93. ///
  94. /// @param name Name of the hook
  95. ///
  96. /// @return Index of the hook, to be used in subsequent calls.
  97. ///
  98. /// @throw NoSuchHook if the hook name is unknown to the caller.
  99. int getIndex(const std::string& name) const;
  100. /// @brief Find hook index
  101. ///
  102. /// Provides exception safe method of retrieving an index of the
  103. /// specified hook.
  104. ///
  105. /// @param name Name of the hook
  106. ///
  107. /// @return Index of the hook if the hook point exists, or -1 if the
  108. /// hook point doesn't exist.
  109. int findIndex(const std::string& name) const;
  110. /// @brief Return number of hooks
  111. ///
  112. /// Returns the total number of hooks registered.
  113. ///
  114. /// @return Number of hooks registered.
  115. int getCount() const {
  116. return (hooks_.size());
  117. }
  118. /// @brief Get hook names
  119. ///
  120. /// Return list of hooks registered in the object.
  121. ///
  122. /// @return Vector of strings holding hook names.
  123. std::vector<std::string> getHookNames() const;
  124. /// @brief Return ServerHooks object
  125. ///
  126. /// Returns the global ServerHooks object.
  127. ///
  128. /// @return Reference to the global ServerHooks object.
  129. static ServerHooks& getServerHooks();
  130. /// @brief Returns pointer to ServerHooks object.
  131. ///
  132. /// @return Pointer to the global ServerHooks object.
  133. static ServerHooksPtr getServerHooksPtr();
  134. /// @brief Generates hook point name for the given control command name.
  135. ///
  136. /// This function is called to generate the name of the hook point
  137. /// when the hook point is used to install command handlers for the
  138. /// given control command.
  139. ///
  140. /// The name of the hook point is generated as follows:
  141. /// - command name is prefixed with a dollar sign,
  142. /// - all hyphens are replaced with underscores.
  143. ///
  144. /// For example, if the command_name is 'foo-bar', the resulting hook
  145. /// point name will be '$foo_bar'.
  146. ///
  147. /// @param command_name Command name for which the hook point name is
  148. /// to be generated.
  149. ///
  150. /// @return Hook point name, or an empty string if the command name
  151. /// can't be converted to a hook name (e.g. when it lacks dollar sign).
  152. static std::string commandToHookName(const std::string& command_name);
  153. /// @brief Returns command name for a specified hook name.
  154. ///
  155. /// This function removes leading dollar sign and replaces underscores
  156. /// with hyphens.
  157. ///
  158. /// @param hook_name Hook name for which command name should be returned.
  159. ///
  160. /// @return Command name.
  161. static std::string hookToCommandName(const std::string& hook_name);
  162. private:
  163. /// @brief Constructor
  164. ///
  165. /// This pre-registers two hooks, context_create and context_destroy, which
  166. /// are called by the server before processing a packet and after processing
  167. /// for the packet has completed. They allow the server code to allocate
  168. /// and destroy per-packet context.
  169. ///
  170. /// The constructor is declared private to enforce the singleton nature of
  171. /// the object. A reference to the singleton is obtainable through the
  172. /// getServerHooks() static method.
  173. ///
  174. /// @throws isc::Unexpected if the registration of the pre-defined hooks
  175. /// fails in some way.
  176. ServerHooks();
  177. /// @brief Initialize hooks
  178. ///
  179. /// Sets the collection of hooks to the initial state, with just the
  180. /// context_create and context_destroy hooks set. This is used during
  181. /// construction.
  182. ///
  183. /// @throws isc::Unexpected if the registration of the pre-defined hooks
  184. /// fails in some way.
  185. void initialize();
  186. /// Useful typedefs.
  187. typedef std::map<std::string, int> HookCollection;
  188. typedef std::map<int, std::string> InverseHookCollection;
  189. /// Two maps, one for name->index, the other for index->name. (This is
  190. /// simpler than using a multi-indexed container.)
  191. HookCollection hooks_; ///< Hook name/index collection
  192. InverseHookCollection inverse_hooks_; ///< Hook index/name collection
  193. };
  194. } // namespace util
  195. } // namespace isc
  196. #endif // SERVER_HOOKS_H