cache_config.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. #ifndef DATASRC_CACHE_CONFIG_H
  15. #define DATASRC_CACHE_CONFIG_H
  16. #include <exceptions/exceptions.h>
  17. #include <dns/dns_fwd.h>
  18. #include <cc/data.h>
  19. #include <datasrc/memory/load_action.h>
  20. #include <boost/noncopyable.hpp>
  21. #include <map>
  22. #include <string>
  23. namespace isc {
  24. namespace datasrc {
  25. class DataSourceClient;
  26. namespace internal {
  27. /// \brief Exception thrown for configuration error related to in-memory cache.
  28. class CacheConfigError : public Exception {
  29. public:
  30. CacheConfigError(const char* file, size_t line, const char* what) :
  31. Exception(file, line, what)
  32. {}
  33. };
  34. /// \brief Configuration for in-memory cache of a data source.
  35. ///
  36. /// This class understands and validates the configuration parameters for
  37. /// \c DataSourceClient related to in-memory cache, and converts it to native,
  38. /// type-safe objects for the convenience of the user of this class.
  39. /// Specifically, it allows the user to get the underlying memory segment
  40. /// type for the cache as a string and to iterate over zone names to be
  41. /// cached in memory.
  42. ///
  43. /// It also provides unified interface for getting \c memory::LoadAction
  44. /// object that can be used for loading zones, regardless of the underlying
  45. /// data source properties, i.e., whether it's special "MasterFiles" type
  46. /// or other generic data sources.
  47. ///
  48. /// This class is publicly defined so it can be tested directly, but
  49. /// it's essentially private to the \c ConfigurableClientList class.
  50. /// It's therefore defined in an "internal" namespace, and isn't expected
  51. /// to be used by other classes or user applications. Likewise, this file
  52. /// is not expected to be installed with other publicly usable header files.
  53. ///
  54. /// It's defined as noncopyable, simply because it's not expected to be
  55. /// copied in the intended usage for \c ConfigurableClientList. Prohibiting
  56. /// copies will help avoid unexpected disruption due to accidental copy and
  57. /// sharing internal resources as a result of that.
  58. class CacheConfig : boost::noncopyable {
  59. public:
  60. /// \brief Constructor.
  61. ///
  62. /// It performs the following validation on the given configuration:
  63. /// - For the "MasterFiles" type
  64. /// - datasrc_client_ must not be provided (must be null); throws
  65. /// InvalidParameter otherwise.
  66. /// - cache must be enabled: "cache-enable" configuration item exists
  67. /// and is true, and allowed parameter is true, too; throws
  68. /// CacheConfigError otherwise.
  69. /// - "params" configuration item must be provided and of a map type,
  70. /// and each map entry maps a string to another string; throws
  71. /// data::TypeError otherwise.
  72. /// - the key string of each map entry must be a valid textual
  73. /// representation of a domain name. Otherwise corresponding
  74. /// exception from the dns::Name class will be thrown.
  75. /// - For other types
  76. /// - datasrc_client_ must be provided (must not be null); throws
  77. /// InvalidParameter otherwise.
  78. /// - (Unless cache is disabled) "cache-zones" configuration item must
  79. /// exist and must be a list of strings; throws data::TypeError
  80. /// otherwise.
  81. /// - Each string value of cache-zones entries must be a valid textual
  82. /// representation of a domain name. Otherwise corresponding
  83. /// exception from the dns::Name class will be thrown.
  84. /// - Names in the list must not have duplicates;
  85. /// throws CacheConfigError otherwise.
  86. ///
  87. /// For other data source types than "MasterFiles", cache can be disabled.
  88. /// In this case cache-zones configuration item is simply ignored, even
  89. /// it contains an error that would otherwise trigger an exception.
  90. ///
  91. /// The specified set of zones (directly in "params" in case of
  92. /// "MasterFile", and specified in "cache-zones" for others) can be
  93. /// empty.
  94. ///
  95. /// This constructor also identifies the underlying memory segment type
  96. /// used for the cache. It's given via the "cache-type" configuration
  97. /// item if defined; otherwise it defaults to "local".
  98. ///
  99. /// \throw InvalidParameter Program error at the caller side rather than
  100. /// in the configuration (see above)
  101. /// \throw CacheConfigError There is a semantics error in the given
  102. /// configuration (see above)
  103. /// \throw data::TypeError Invalid type of data is found in the
  104. /// configuration (see above)
  105. /// \throw Other Exceptions from the dns::Name class when conversion from
  106. /// text fails (see above)
  107. ///
  108. /// \param datasrc_type Type of data source. This must be the "type"
  109. /// value of the data source configuration.
  110. /// \param datasrc_client Client of the underlying data source for the
  111. /// cache, if it's used; for MasterFiles types it's null.
  112. /// \param datasrc_conf Configuration element for the data source.
  113. /// This must be the value of, e.g., data_sources/classes/IN[0] of
  114. /// BIND 10 configuration.
  115. /// \param allowed Whether in-memory cache is allowed by the process.
  116. /// This must be derived from the allow_cache parameter of
  117. /// \c ConfigurableClientList::configure().
  118. CacheConfig(const std::string& datasrc_type,
  119. const DataSourceClient* datasrc_client,
  120. const data::Element& datasrc_conf,
  121. bool allowed);
  122. /// \brief Return if the cache is enabled.
  123. ///
  124. /// The cache is considered enabled iff the "cache-enable" configuration
  125. /// item (given on construction) existed and was set to true, and
  126. /// the \c allowed parameter to the constructor was true.
  127. ///
  128. /// \throw None
  129. bool isEnabled() const { return (enabled_); }
  130. /// \brief Return the memory segment type to be used for the zone table.
  131. ///
  132. /// \throw None
  133. const std::string& getSegmentType() const { return (segment_type_); }
  134. /// \brief Return a \c LoadAction functor to load zone data into memory.
  135. ///
  136. /// This method returns an appropriate \c LoadAction functor that can be
  137. /// passed to a \c memory::ZoneWriter object to load data of the specified
  138. /// zone into memory. The source of the zone data differs depending on
  139. /// the cache configuration (either a master file or another data source),
  140. /// but this method hides the details and works as a unified interface
  141. /// for the caller.
  142. ///
  143. /// If the specified zone is not configured to be cached, it returns an
  144. /// empty functor (which can be evaluated to be \c false as a boolean).
  145. /// It doesn't throw an exception in this case because the expected caller
  146. /// of this method would handle such a case internally.
  147. ///
  148. /// \throw NoSuchZone The specified zone doesn't exist in the
  149. /// underlying data source storing the original data to be cached.
  150. /// \throw DataSourceError Other, unexpected but possible error happens
  151. /// in the underlying data source.
  152. /// \throw Unexpected Unexpected error happens in the underlying data
  153. /// source. This shouldn't happen as long as the data source
  154. /// implementation meets the public API requirement.
  155. ///
  156. /// \param rrclass The RR class of the zone
  157. /// \param zone_name The origin name of the zone
  158. /// \return A \c LoadAction functor to load zone data or an empty functor
  159. /// (see above).
  160. memory::LoadAction getLoadAction(const dns::RRClass& rrlcass,
  161. const dns::Name& zone_name) const;
  162. /// \brief Read only iterator type over configured cached zones.
  163. ///
  164. /// \note This initial version exposes the internal data structure (i.e.
  165. /// map from name to string) through this public iterator type for
  166. /// simplicity. In terms of data encapsulation it's better to introduce
  167. /// a custom iterator type that only goes through the conceptual list
  168. /// of zone names, but due to the limitation of the expected user of this
  169. /// class that would probably be premature generalization. In future,
  170. /// we might want to allow getting the list of zones directly from the
  171. /// underlying data source. If and when that happens we should introduce
  172. /// a custom type. In any case, the user of this class should only
  173. /// use the typedef, not the original map iterator. It should also
  174. /// use this iterator as a forward iterator (datasource-based iterator
  175. /// wouldn't be able to be bidirectional), and it shouldn't use the
  176. /// value of the map entry (a string, specifying a path to master file
  177. /// for MasterFiles data source).
  178. typedef std::map<dns::Name, std::string>::const_iterator ConstZoneIterator;
  179. /// \brief Return the beginning of cached zones in the form of iterator.
  180. ConstZoneIterator begin() const { return (zone_config_.begin()); }
  181. /// \brief Return the end of cached zones in the form of iterator.
  182. ConstZoneIterator end() const { return (zone_config_.end()); }
  183. private:
  184. const bool enabled_; // if the use of in-memory zone table is enabled
  185. const std::string segment_type_;
  186. // client of underlying data source, will be NULL for MasterFile datasrc
  187. const DataSourceClient* datasrc_client_;
  188. // Maps each of zones to be cached to a string. For "MasterFiles" type
  189. // of data source, the string is a path to the master zone file; for
  190. // others it's an empty string.
  191. typedef std::map<dns::Name, std::string> Zones;
  192. Zones zone_config_;
  193. };
  194. }
  195. }
  196. }
  197. #endif // DATASRC_CACHE_CONFIG_H
  198. // Local Variables:
  199. // mode: c++
  200. // End: