LCOV - code coverage report
Current view: top level - datasrc - memory_datasrc.h (source / functions) Hit Total Coverage
Test: report.info Lines: 6 6 100.0 %
Date: 2012-05-15 Functions: 3 5 60.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  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                 :            : 
      15                 :            : #ifndef __MEMORY_DATA_SOURCE_H
      16                 :            : #define __MEMORY_DATA_SOURCE_H 1
      17                 :            : 
      18                 :            : #include <string>
      19                 :            : 
      20                 :            : #include <boost/noncopyable.hpp>
      21                 :            : 
      22                 :            : #include <datasrc/zonetable.h>
      23                 :            : #include <datasrc/client.h>
      24                 :            : 
      25                 :            : #include <cc/data.h>
      26                 :            : 
      27                 :            : namespace isc {
      28                 :            : namespace dns {
      29                 :            : class Name;
      30                 :            : class RRsetList;
      31                 :            : };
      32                 :            : 
      33                 :            : namespace datasrc {
      34                 :            : 
      35                 :            : /// A derived zone finder class intended to be used with the memory data source.
      36                 :            : ///
      37                 :            : /// Conceptually this "finder" maintains a local in-memory copy of all RRs
      38                 :            : /// of a single zone from some kind of source (right now it's a textual
      39                 :            : /// master file, but it could also be another data source with a database
      40                 :            : /// backend).  This is why the class has methods like \c load() or \c add().
      41                 :            : ///
      42                 :            : /// This class is non copyable.
      43                 :            : class InMemoryZoneFinder : boost::noncopyable, public ZoneFinder {
      44                 :            :     ///
      45                 :            :     /// \name Constructors and Destructor.
      46                 :            : public:
      47                 :            :     /// \brief Constructor from zone parameters.
      48                 :            :     ///
      49                 :            :     /// This constructor internally involves resource allocation, and if
      50                 :            :     /// it fails, a corresponding standard exception will be thrown.
      51                 :            :     /// It never throws an exception otherwise.
      52                 :            :     ///
      53                 :            :     /// \param rrclass The RR class of the zone.
      54                 :            :     /// \param origin The origin name of the zone.
      55                 :            :     InMemoryZoneFinder(const isc::dns::RRClass& rrclass,
      56                 :            :                        const isc::dns::Name& origin);
      57                 :            : 
      58                 :            :     /// The destructor.
      59                 :            :     virtual ~InMemoryZoneFinder();
      60                 :            :     //@}
      61                 :            : 
      62                 :            :     /// \brief Returns the origin of the zone.
      63                 :            :     virtual isc::dns::Name getOrigin() const;
      64                 :            : 
      65                 :            :     /// \brief Returns the class of the zone.
      66                 :            :     virtual isc::dns::RRClass getClass() const;
      67                 :            : 
      68                 :            :     /// \brief Find an RRset in the datasource
      69                 :            :     virtual ZoneFinderContextPtr find(const isc::dns::Name& name,
      70                 :            :                                       const isc::dns::RRType& type,
      71                 :            :                                       const FindOptions options =
      72                 :            :                                       FIND_DEFAULT);
      73                 :            : 
      74                 :            :     /// \brief Version of find that returns all types at once
      75                 :            :     ///
      76                 :            :     /// It acts the same as find, just that when the correct node is found,
      77                 :            :     /// all the RRsets are filled into the target parameter instead of being
      78                 :            :     /// returned by the result.
      79                 :            :     virtual ZoneFinderContextPtr findAll(
      80                 :            :         const isc::dns::Name& name,
      81                 :            :         std::vector<isc::dns::ConstRRsetPtr>& target,
      82                 :            :         const FindOptions options = FIND_DEFAULT);
      83                 :            : 
      84                 :            :     /// Look for NSEC3 for proving (non)existence of given name.
      85                 :            :     ///
      86                 :            :     /// See documentation in \c Zone.
      87                 :            :     virtual FindNSEC3Result
      88                 :            :     findNSEC3(const isc::dns::Name& name, bool recursive);
      89                 :            : 
      90                 :            :     /// \brief Imelementation of the ZoneFinder::findPreviousName method
      91                 :            :     ///
      92                 :            :     /// This one throws NotImplemented exception, as InMemory doesn't
      93                 :            :     /// support DNSSEC currently.
      94                 :            :     virtual isc::dns::Name findPreviousName(const isc::dns::Name& query) const;
      95                 :            : 
      96                 :            :     /// \brief Inserts an rrset into the zone.
      97                 :            :     ///
      98                 :            :     /// It puts another RRset into the zone.
      99                 :            :     ///
     100                 :            :     /// In the current implementation, this method doesn't allow an existing
     101                 :            :     /// RRset to be updated or overridden.  So the caller must make sure that
     102                 :            :     /// all RRs of the same type and name must be given in the form of a
     103                 :            :     /// single RRset.  The current implementation will also require that
     104                 :            :     /// when an RRSIG is added the RRset to be covered has already been
     105                 :            :     /// added.  These restrictions are probably too strict when this data
     106                 :            :     /// source accepts various forms of input, so they should be revisited
     107                 :            :     /// later.
     108                 :            :     ///
     109                 :            :     /// Except for NullRRset and OutOfZone, this method does not guarantee
     110                 :            :     /// strong exception safety (it is currently not needed, if it is needed
     111                 :            :     /// in future, it should be implemented).
     112                 :            :     ///
     113                 :            :     /// \throw NullRRset \c rrset is a NULL pointer.
     114                 :            :     /// \throw OutOfZone The owner name of \c rrset is outside of the
     115                 :            :     /// origin of the zone.
     116                 :            :     /// \throw AddError Other general errors.
     117                 :            :     /// \throw Others This method might throw standard allocation exceptions.
     118                 :            :     ///
     119                 :            :     /// \param rrset The set to add.
     120                 :            :     /// \return SUCCESS or EXIST (if an rrset for given name and type already
     121                 :            :     ///    exists).
     122                 :            :     result::Result add(const isc::dns::ConstRRsetPtr& rrset);
     123                 :            : 
     124                 :            :     /// \brief RRset is NULL exception.
     125                 :            :     ///
     126                 :            :     /// This is thrown if the provided RRset parameter is NULL.
     127                 :          1 :     struct NullRRset : public InvalidParameter {
     128                 :            :         NullRRset(const char* file, size_t line, const char* what) :
     129                 :          2 :             InvalidParameter(file, line, what)
     130                 :            :         { }
     131                 :            :     };
     132                 :            : 
     133                 :            :     /// \brief General failure exception for \c add().
     134                 :            :     ///
     135                 :            :     /// This is thrown against general error cases in adding an RRset
     136                 :            :     /// to the zone.
     137                 :            :     ///
     138                 :            :     /// Note: this exception would cover cases for \c OutOfZone or
     139                 :            :     /// \c NullRRset.  We'll need to clarify and unify the granularity
     140                 :            :     /// of exceptions eventually.  For now, exceptions are added as
     141                 :            :     /// developers see the need for it.
     142                 :         26 :     struct AddError : public InvalidParameter {
     143                 :         26 :         AddError(const char* file, size_t line, const char* what) :
     144                 :         52 :             InvalidParameter(file, line, what)
     145                 :         26 :         { }
     146                 :            :     };
     147                 :            : 
     148                 :            :     /// Return the master file name of the zone
     149                 :            :     ///
     150                 :            :     /// This method returns the name of the zone's master file to be loaded.
     151                 :            :     /// The returned string will be an empty unless the zone finder has
     152                 :            :     /// successfully loaded a zone.
     153                 :            :     ///
     154                 :            :     /// This method should normally not throw an exception.  But the creation
     155                 :            :     /// of the return string may involve a resource allocation, and if it
     156                 :            :     /// fails, the corresponding standard exception will be thrown.
     157                 :            :     ///
     158                 :            :     /// \return The name of the zone file loaded in the zone finder, or an empty
     159                 :            :     /// string if the zone hasn't loaded any file.
     160                 :            :     const std::string getFileName() const;
     161                 :            : 
     162                 :            :     /// \brief Load zone from masterfile.
     163                 :            :     ///
     164                 :            :     /// This loads data from masterfile specified by filename. It replaces
     165                 :            :     /// current content. The masterfile parsing ability is kind of limited,
     166                 :            :     /// see isc::dns::masterLoad.
     167                 :            :     ///
     168                 :            :     /// This throws isc::dns::MasterLoadError if there is problem with loading
     169                 :            :     /// (missing file, malformed, it contains different zone, etc - see
     170                 :            :     /// isc::dns::masterLoad for details).
     171                 :            :     ///
     172                 :            :     /// In case of internal problems, OutOfZone, NullRRset or AssertError could
     173                 :            :     /// be thrown, but they should not be expected. Exceptions caused by
     174                 :            :     /// allocation may be thrown as well.
     175                 :            :     ///
     176                 :            :     /// If anything is thrown, the previous content is preserved (so it can
     177                 :            :     /// be used to update the data, but if user makes a typo, the old one
     178                 :            :     /// is kept).
     179                 :            :     ///
     180                 :            :     /// \param filename The master file to load.
     181                 :            :     ///
     182                 :            :     /// \todo We may need to split it to some kind of build and commit/abort.
     183                 :            :     ///     This will probably be needed when a better implementation of
     184                 :            :     ///     configuration reloading is written.
     185                 :            :     void load(const std::string& filename);
     186                 :            : 
     187                 :            :     /// \brief Load zone from another data source.
     188                 :            :     ///
     189                 :            :     /// This is similar to the other version, but zone's RRsets are provided
     190                 :            :     /// by an iterator of another data source.  On successful load, the
     191                 :            :     /// internal filename will be cleared.
     192                 :            :     ///
     193                 :            :     /// This implementation assumes the iterator produces combined RRsets,
     194                 :            :     /// that is, there should exactly one RRset for the same owner name and
     195                 :            :     /// RR type.  This means the caller is expected to create the iterator
     196                 :            :     /// with \c separate_rrs being \c false.  This implementation also assumes
     197                 :            :     /// RRsets of different names are not mixed; so if the iterator produces
     198                 :            :     /// an RRset of a different name than that of the previous RRset, that
     199                 :            :     /// previous name must never appear in the subsequent sequence of RRsets.
     200                 :            :     /// Note that the iterator API does not ensure this.  If the underlying
     201                 :            :     /// implementation does not follow it, load() will fail.  Note, however,
     202                 :            :     /// that this whole interface is tentative.  in-memory zone loading will
     203                 :            :     /// have to be revisited fundamentally, and at that point this restriction
     204                 :            :     /// probably won't matter.
     205                 :            :     void load(ZoneIterator& iterator);
     206                 :            : 
     207                 :            :     /// Exchanges the content of \c this zone finder with that of the given
     208                 :            :     /// \c zone_finder.
     209                 :            :     ///
     210                 :            :     /// This method never throws an exception.
     211                 :            :     ///
     212                 :            :     /// \param zone_finder Another \c InMemoryZone object which is to
     213                 :            :     /// be swapped with \c this zone finder.
     214                 :            :     void swap(InMemoryZoneFinder& zone_finder);
     215                 :            : 
     216                 :            : private:
     217                 :            :     /// \name Hidden private data
     218                 :            :     //@{
     219                 :            :     struct InMemoryZoneFinderImpl;
     220                 :            :     InMemoryZoneFinderImpl* impl_;
     221                 :            :     //@}
     222                 :            :     // The friend here is for InMemoryClient::getIterator. The iterator
     223                 :            :     // needs to access the data inside the zone, so the InMemoryClient
     224                 :            :     // extracts the pointer to data and puts it into the iterator.
     225                 :            :     // The access is read only.
     226                 :            :     friend class InMemoryClient;
     227                 :            : 
     228                 :            :     /// \brief In-memory version of finder context.
     229                 :            :     ///
     230                 :            :     /// The implementation (and any specialized interface) is completely local
     231                 :            :     /// to the InMemoryZoneFinder class, so it's defined as private
     232                 :            :     class Context;
     233                 :            : };
     234                 :            : 
     235                 :            : /// \brief A data source client that holds all necessary data in memory.
     236                 :            : ///
     237                 :            : /// The \c InMemoryClient class provides an access to a conceptual data
     238                 :            : /// source that maintains all necessary data in a memory image, thereby
     239                 :            : /// allowing much faster lookups.  The in memory data is a copy of some
     240                 :            : /// real physical source - in the current implementation a list of zones
     241                 :            : /// are populated as a result of \c addZone() calls; zone data is given
     242                 :            : /// in a standard master file (but there's a plan to use database backends
     243                 :            : /// as a source of the in memory data).
     244                 :            : ///
     245                 :            : /// Although every data source client is assumed to be of the same RR class,
     246                 :            : /// the \c InMemoryClient class does not enforce the assumption through
     247                 :            : /// its interface.
     248                 :            : /// For example, the \c addZone() method does not check if the new zone is of
     249                 :            : /// the same RR class as that of the others already in memory.
     250                 :            : /// It is caller's responsibility to ensure this assumption.
     251                 :            : ///
     252                 :            : /// <b>Notes to developer:</b>
     253                 :            : ///
     254                 :            : /// The addZone() method takes a (Boost) shared pointer because it would be
     255                 :            : /// inconvenient to require the caller to maintain the ownership of zones,
     256                 :            : /// while it wouldn't be safe to delete unnecessary zones inside the dedicated
     257                 :            : /// backend.
     258                 :            : ///
     259                 :            : /// The findZone() method takes a domain name and returns the best matching
     260                 :            : /// \c InMemoryZoneFinder in the form of (Boost) shared pointer, so that it can
     261                 :            : /// provide the general interface for all data sources.
     262                 :            : class InMemoryClient : public DataSourceClient {
     263                 :            : public:
     264                 :            :     ///
     265                 :            :     /// \name Constructors and Destructor.
     266                 :            :     ///
     267                 :            :     //@{
     268                 :            : 
     269                 :            :     /// Default constructor.
     270                 :            :     ///
     271                 :            :     /// This constructor internally involves resource allocation, and if
     272                 :            :     /// it fails, a corresponding standard exception will be thrown.
     273                 :            :     /// It never throws an exception otherwise.
     274                 :            :     InMemoryClient();
     275                 :            : 
     276                 :            :     /// The destructor.
     277                 :            :     ~InMemoryClient();
     278                 :            :     //@}
     279                 :            : 
     280                 :            :     /// Return the number of zones stored in the client.
     281                 :            :     ///
     282                 :            :     /// This method never throws an exception.
     283                 :            :     ///
     284                 :            :     /// \return The number of zones stored in the client.
     285                 :            :     unsigned int getZoneCount() const;
     286                 :            : 
     287                 :            :     /// Add a zone (in the form of \c ZoneFinder) to the \c InMemoryClient.
     288                 :            :     ///
     289                 :            :     /// \c zone_finder must not be associated with a NULL pointer; otherwise
     290                 :            :     /// an exception of class \c InvalidParameter will be thrown.
     291                 :            :     /// If internal resource allocation fails, a corresponding standard
     292                 :            :     /// exception will be thrown.
     293                 :            :     /// This method never throws an exception otherwise.
     294                 :            :     ///
     295                 :            :     /// \param zone_finder A \c ZoneFinder object to be added.
     296                 :            :     /// \return \c result::SUCCESS If the zone_finder is successfully
     297                 :            :     /// added to the client.
     298                 :            :     /// \return \c result::EXIST The memory data source already
     299                 :            :     /// stores a zone that has the same origin.
     300                 :            :     result::Result addZone(ZoneFinderPtr zone_finder);
     301                 :            : 
     302                 :            :     /// Returns a \c ZoneFinder for a zone_finder that best matches the given
     303                 :            :     /// name.
     304                 :            :     ///
     305                 :            :     /// This derived version of the method never throws an exception.
     306                 :            :     /// For other details see \c DataSourceClient::findZone().
     307                 :            :     virtual FindResult findZone(const isc::dns::Name& name) const;
     308                 :            : 
     309                 :            :     /// \brief Implementation of the getIterator method
     310                 :            :     virtual ZoneIteratorPtr getIterator(const isc::dns::Name& name,
     311                 :            :                                         bool separate_rrs = false) const;
     312                 :            : 
     313                 :            :     /// In-memory data source is read-only, so this derived method will
     314                 :            :     /// result in a NotImplemented exception.
     315                 :            :     ///
     316                 :            :     /// \note We plan to use a database-based data source as a backend
     317                 :            :     /// persistent storage for an in-memory data source.  When it's
     318                 :            :     /// implemented we may also want to allow the user of the in-memory client
     319                 :            :     /// to update via its updater (this may or may not be a good idea and
     320                 :            :     /// is subject to further discussions).
     321                 :            :     virtual ZoneUpdaterPtr getUpdater(const isc::dns::Name& name,
     322                 :            :                                       bool replace, bool journaling = false)
     323                 :            :         const;
     324                 :            : 
     325                 :            :     virtual std::pair<ZoneJournalReader::Result, ZoneJournalReaderPtr>
     326                 :            :     getJournalReader(const isc::dns::Name& zone, uint32_t begin_serial,
     327                 :            :                      uint32_t end_serial) const;
     328                 :            : 
     329                 :            : private:
     330                 :            :     // TODO: Do we still need the PImpl if nobody should manipulate this class
     331                 :            :     // directly any more (it should be handled through DataSourceClient)?
     332                 :            :     class InMemoryClientImpl;
     333                 :            :     InMemoryClientImpl* impl_;
     334                 :            : };
     335                 :            : 
     336                 :            : /// \brief Creates an instance of the Memory datasource client
     337                 :            : ///
     338                 :            : /// Currently the configuration passed here must be a MapElement, formed as
     339                 :            : /// follows:
     340                 :            : /// \code
     341                 :            : /// { "type": string ("memory"),
     342                 :            : ///   "class": string ("IN"/"CH"/etc),
     343                 :            : ///   "zones": list
     344                 :            : /// }
     345                 :            : /// Zones list is a list of maps:
     346                 :            : /// { "origin": string,
     347                 :            : ///   "file": string
     348                 :            : /// }
     349                 :            : /// \endcode
     350                 :            : /// (i.e. the configuration that was used prior to the datasource refactor)
     351                 :            : ///
     352                 :            : /// This configuration setup is currently under discussion and will change in
     353                 :            : /// the near future.
     354                 :            : ///
     355                 :            : /// \param config The configuration for the datasource instance
     356                 :            : /// \param error This string will be set to an error message if an error occurs
     357                 :            : ///              during initialization
     358                 :            : /// \return An instance of the memory datasource client, or NULL if there was
     359                 :            : ///         an error
     360                 :            : extern "C" DataSourceClient* createInstance(isc::data::ConstElementPtr config,
     361                 :            :                                             std::string& error);
     362                 :            : 
     363                 :            : /// \brief Destroy the instance created by createInstance()
     364                 :            : extern "C" void destroyInstance(DataSourceClient* instance);
     365                 :            : 
     366                 :            : 
     367                 :            : }
     368                 :            : }
     369                 :            : #endif  // __DATA_SOURCE_MEMORY_H
     370                 :            : // Local Variables:
     371                 :            : // mode: c++
     372                 :            : // End:

Generated by: LCOV version 1.9