d_cfg_mgr.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <cc/data.h>
  15. #include <exceptions/exceptions.h>
  16. #include <dhcpsrv/dhcp_parsers.h>
  17. #include <stdint.h>
  18. #include <string>
  19. #ifndef D_CFG_MGR_H
  20. #define D_CFG_MGR_H
  21. namespace isc {
  22. namespace d2 {
  23. /// @brief Exception thrown if the configuration manager encounters an error.
  24. class DCfgMgrBaseError : public isc::Exception {
  25. public:
  26. DCfgMgrBaseError(const char* file, size_t line, const char* what) :
  27. isc::Exception(file, line, what) { };
  28. };
  29. /// @brief Abstract class that implements a container for configuration context.
  30. /// It provides a single enclosure for the storage of configuration parameters
  31. /// and any other context specific information that needs to be accessible
  32. /// during configuration parsing as well as to the application as a whole.
  33. /// The base class supports storage for a small set of simple data types.
  34. /// Derivations simply add additional storage as needed. Note that this class
  35. /// declares the pure virtual clone() method, its copy constructor is protected,
  36. /// and its copy operator is inaccessible. Derivations must supply an
  37. /// implementation of clone that calls the base class copy constructor as
  38. /// well as performing whatever steps are necessary to copy its additional
  39. /// storage. This allows the management class to perform context backup and
  40. /// restoration without derivation specific knowledge using logic like
  41. /// the following:
  42. ///
  43. /// // Make a backup copy
  44. /// DCfgContextBasePtr backup_copy(context_->clone());
  45. /// :
  46. /// // Restore from backup
  47. /// context_ = backup_copy;
  48. ///
  49. class DCfgContextBase {
  50. public:
  51. /// @brief Constructor
  52. DCfgContextBase();
  53. /// @brief Destructor
  54. virtual ~DCfgContextBase();
  55. /// @brief Fetches the value for a given boolean configuration parameter
  56. /// from the context.
  57. ///
  58. /// @param name is the name of the parameter to retrieve.
  59. /// @param value is an output parameter in which to return the retrieved
  60. /// value.
  61. /// @throw throws DhcpConfigError if the context does not contain the
  62. /// parameter.
  63. void getParam(const std::string& name, bool& value) {
  64. value = boolean_values_->getParam(name);
  65. }
  66. /// @brief Fetches the value for a given uint32_t configuration parameter
  67. /// from the context.
  68. ///
  69. /// @param name is the name of the parameter to retrieve.
  70. /// @param value is an output parameter in which to return the retrieved
  71. /// value.
  72. /// @throw throws DhcpConfigError if the context does not contain the
  73. /// parameter.
  74. void getParam(const std::string& name, uint32_t& value) {
  75. value = uint32_values_->getParam(name);
  76. }
  77. /// @brief Fetches the value for a given string configuration parameter
  78. /// from the context.
  79. ///
  80. /// @param name is the name of the parameter to retrieve.
  81. /// @param value is an output parameter in which to return the retrieved
  82. /// value.
  83. /// @throw throws DhcpConfigError if the context does not contain the
  84. /// parameter.
  85. void getParam(const std::string& name, std::string& value) {
  86. value = string_values_->getParam(name);
  87. }
  88. /// @brief Fetches the Boolean Storage. Typically used for passing
  89. /// into parsers.
  90. ///
  91. /// @return returns a pointer to the Boolean Storage.
  92. isc::dhcp::BooleanStoragePtr getBooleanStorage() {
  93. return (boolean_values_);
  94. }
  95. /// @brief Fetches the uint32 Storage. Typically used for passing
  96. /// into parsers.
  97. ///
  98. /// @return returns a pointer to the uint32 Storage.
  99. isc::dhcp::Uint32StoragePtr getUint32Storage() {
  100. return (uint32_values_);
  101. }
  102. /// @brief Fetches the string Storage. Typically used for passing
  103. /// into parsers.
  104. ///
  105. /// @return returns a pointer to the string Storage.
  106. isc::dhcp::StringStoragePtr getStringStorage() {
  107. return (string_values_);
  108. }
  109. /// @brief Creates a clone of this context object. As mentioned in the
  110. /// the class brief, derivation must supply an implementation that
  111. /// initializes the base class storage as well as its own. Typically
  112. /// the derivation's clone method would return the result of passing
  113. /// "*this" into its own copy constructor:
  114. ///
  115. /// -----------------------------------------------------------------
  116. /// class DStubContext : public DCfgContextBase {
  117. /// public:
  118. /// :
  119. /// // Clone calls its own copy constructor
  120. /// virtual DStubContext* clone() {
  121. /// return (new DStubContext(*this));
  122. /// }
  123. ///
  124. /// // Note that the copy constructor calls the base class copy ctor
  125. /// // then initializes its additional storage.
  126. /// DStubContext(const DStubContext& rhs) : DCfgContextBase(rhs),
  127. /// extra_values_(new Uint32Storage(*(rhs.extra_values_))) {
  128. /// }
  129. /// :
  130. /// // Here's the derivation's additional storage.
  131. /// isc::dhcp::Uint32StoragePtr extra_values_;
  132. /// :
  133. /// -----------------------------------------------------------------
  134. ///
  135. /// @return returns a raw pointer to the new clone.
  136. virtual DCfgContextBase* clone() = 0;
  137. protected:
  138. /// @brief Copy constructor for use by derivations in clone().
  139. DCfgContextBase(const DCfgContextBase& rhs);
  140. private:
  141. /// @brief Private assignment operator to avoid potential for slicing.
  142. DCfgContextBase& operator=(const DCfgContextBase& rhs);
  143. /// @brief Storage for boolean parameters.
  144. isc::dhcp::BooleanStoragePtr boolean_values_;
  145. /// @brief Storage for uint32 parameters.
  146. isc::dhcp::Uint32StoragePtr uint32_values_;
  147. /// @brief Storage for string parameters.
  148. isc::dhcp::StringStoragePtr string_values_;
  149. };
  150. /// @brief Pointer to a configuration context.
  151. typedef boost::shared_ptr<DCfgContextBase> DCfgContextBasePtr;
  152. /// @brief Defines an unsorted, list of string Element IDs.
  153. typedef std::vector<std::string> ElementIdList;
  154. /// @brief Configuration Manager
  155. ///
  156. /// DCfgMgrBase is an abstract class that provides the mechanisms for managing
  157. /// an application's configuration. This includes services for parsing sets of
  158. /// configuration values, storing the parsed information in its converted form,
  159. /// and retrieving the information on demand. It is intended to be the worker
  160. /// class which is handed a set of configuration values to process by upper
  161. /// application management layers. Typically this call chain would look like
  162. /// this:
  163. /// External configuration event:
  164. /// --> Controller::configHandler(new configuration)
  165. /// --> Controller.updateConfig(new configuration)
  166. /// --> Controller.Process.configure(new configuration)
  167. /// --> Process.CfgMgr.parseConfig(new configuration)
  168. ///
  169. /// The class presents a public method for receiving new configurations,
  170. /// parseConfig. This method coordinates the parsing effort as follows:
  171. ///
  172. /// make backup copy of configuration context
  173. /// for each top level element in new configuration
  174. /// get derivation-specific parser for element
  175. /// run parser
  176. /// update context with parsed results
  177. /// break on error
  178. ///
  179. /// if an error occurred
  180. /// restore configuration context from backup
  181. ///
  182. /// After making a backup of the current context, it iterates over the top-level
  183. /// elements in the new configuration. The order in which the elements are
  184. /// processed is either:
  185. ///
  186. /// 1. Natural order presented by the configuration set
  187. /// 2. Specific order determined by a list of element ids
  188. ///
  189. /// This allows a derivation to specify the order in which its elements are
  190. /// parsed if there are dependencies between elements.
  191. /// To parse a given element, its id is passed into createConfigParser,
  192. /// which returns an instance of the appropriate parser. This method is
  193. /// abstract so the derivation's implementation determines the type of parser
  194. /// created. This isolates the knowledge of specific element ids and which
  195. /// application specific parsers to derivation.
  196. /// Once the parser has been created, it is used to parse the data value
  197. /// associated with the element id and update the context with the parsed
  198. /// results.
  199. /// In the event that an error occurs, parsing is halted and the configuration
  200. /// context is restored from backup.
  201. class DCfgMgrBase {
  202. public:
  203. /// @brief Constructor
  204. ///
  205. /// @param context is a pointer to the configuration context the manager
  206. /// will use for storing parsed results.
  207. ///
  208. /// @throw throws DCfgMgrBaseError if context is null
  209. DCfgMgrBase(DCfgContextBasePtr context);
  210. /// @brief Destructor
  211. virtual ~DCfgMgrBase();
  212. /// @brief Acts as the receiver of new configurations and coordinates
  213. /// the parsing as described in the class brief.
  214. ///
  215. /// @param config_set is a set of configuration elements to parsed.
  216. ///
  217. /// @return an Element that contains the results of configuration composed
  218. /// of an integer status value (0 means successful, non-zero means failure),
  219. /// and a string explanation of the outcome.
  220. isc::data::ConstElementPtr parseConfig(isc::data::ConstElementPtr
  221. config_set);
  222. /// @brief Adds a given element id to the end of the parse order list.
  223. /// The order in which elements are retrieved from this is FIFO. Elements
  224. /// should be added in the order in which they are to be parsed.
  225. //
  226. /// @param element_id is the string name of the element as it will appear
  227. /// in the configuration set.
  228. void addToParseOrder(std::string& element_id){
  229. parse_order_.push_back(element_id);
  230. }
  231. /// @brief Fetches the parse order list.
  232. ///
  233. /// @return returns a const reference to the list.
  234. const ElementIdList& getParseOrder() const {
  235. return (parse_order_);
  236. }
  237. /// @brief Fetches the configuration context.
  238. ///
  239. /// @return returns a pointer reference to the configuration context.
  240. DCfgContextBasePtr& getContext() {
  241. return (context_);
  242. }
  243. protected:
  244. /// @brief Given an element_id returns an instance of the appropriate
  245. /// parser. This method is abstract, isolating any direct knowledge of
  246. /// element_ids and parsers to within the application-specific derivation.
  247. ///
  248. /// @param element_id is the string name of the element as it will appear
  249. /// in the configuration set.
  250. ///
  251. /// @return returns a ParserPtr to the parser instance.
  252. /// @throw throws DCfgMgrBaseError if an error occurs.
  253. virtual isc::dhcp::ParserPtr
  254. createConfigParser(const std::string& element_id) = 0;
  255. private:
  256. /// @brief Given an element_id and data value, instantiate the appropriate
  257. /// parser, parse the data value, and commit the results.
  258. ///
  259. /// @param element_id is the string name of the element as it will appear
  260. /// in the configuration set.
  261. /// @param value is the data value to be parsed and associated with
  262. /// element_id.
  263. ///
  264. /// @throw throws DCfgMgrBaseError if an error occurs.
  265. void buildAndCommit(std::string& element_id,
  266. isc::data::ConstElementPtr value);
  267. /// @brief An FIFO list of element ids, used to dictate the element
  268. /// parsing order. If the list is empty, the natural order in the
  269. /// configuration set it used.
  270. ElementIdList parse_order_;
  271. /// @brief Pointer to the configuration context instance.
  272. DCfgContextBasePtr context_;
  273. };
  274. /// @brief Defines a shared pointer to DCfgMgrBase.
  275. typedef boost::shared_ptr<DCfgMgrBase> DCfgMgrBasePtr;
  276. }; // end of isc::d2 namespace
  277. }; // end of isc namespace
  278. #endif // D_CFG_MGR_H