factory.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 2011 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 __DATA_SOURCE_FACTORY_H
  15. #define __DATA_SOURCE_FACTORY_H 1
  16. //#include <boost/noncopyable.hpp>
  17. //#include <boost/shared_ptr.hpp>
  18. //#include <exceptions/exceptions.h>
  19. #include <datasrc/data_source.h>
  20. #include <datasrc/client.h>
  21. #include <exceptions/exceptions.h>
  22. #include <cc/data.h>
  23. namespace isc {
  24. namespace datasrc {
  25. /// \brief Raised if there is an error loading the datasource implementation
  26. /// library, or if that library misses a needed symbol
  27. class DataSourceLibraryError : public DataSourceError {
  28. public:
  29. DataSourceLibraryError(const char* file, size_t line, const char* what) :
  30. DataSourceError(file, line, what) {}
  31. };
  32. /// \brief Raised if the given config contains bad data
  33. ///
  34. /// Depending on the datasource type, the configuration may differ (for
  35. /// instance, the sqlite3 datasource needs a database file).
  36. class DataSourceConfigError : public DataSourceError {
  37. public:
  38. DataSourceConfigError(const char* file, size_t line, const char* what) :
  39. DataSourceError(file, line, what) {}
  40. };
  41. typedef DataSourceClient* ds_creator(isc::data::ConstElementPtr config);
  42. typedef void ds_destructor(DataSourceClient* instance);
  43. /// \brief Container class for dynamically loaded libraries
  44. ///
  45. /// This class is used to dlopen() a library, provides access to dlsym(),
  46. /// and cleans up the dlopened library when the instance of this class is
  47. /// destroyed.
  48. ///
  49. /// Its main function is to provide RAII-style access to dlopen'ed libraries.
  50. ///
  51. /// \note Currently it is Datasource-backend specific. If we have need for this
  52. /// in other places than for dynamically loading datasources, then, apart
  53. /// from moving it to another location, we also need to make the
  54. /// exceptions raised more general.
  55. class DLHolder {
  56. public:
  57. /// \brief Constructor
  58. ///
  59. /// \param name The name of the library (.so) file. This file must be in
  60. /// the library path.
  61. ///
  62. /// \exception DataSourceLibraryError If the library cannot be found or
  63. /// cannot be loaded.
  64. DLHolder(const std::string& name);
  65. /// \brief Destructor
  66. ///
  67. /// Cleans up the library by calling dlclose()
  68. ~DLHolder();
  69. /// \brief Retrieve a symbol
  70. ///
  71. /// This retrieves a symbol from the loaded library.
  72. ///
  73. /// \exception DataSourceLibraryError if the symbol cannot be found, or if
  74. /// another error (as reported by dlerror() occurs.
  75. ///
  76. /// \param name The name of the symbol to retrieve
  77. /// \return A pointer to the symbol
  78. void* getSym(const char* name);
  79. private:
  80. /// Pointer to the dynamically loaded library structure
  81. void *ds_lib_;
  82. };
  83. /// \brief Container for a specific instance of a dynamically loaded
  84. /// DataSourceClient implementation
  85. ///
  86. /// Given a datasource type and a type-specific set of configuration data,
  87. /// the corresponding dynamic library is loaded (if it hadn't been already),
  88. /// and an instance is created. This instance is stored within this structure,
  89. /// and can be accessed through getInstance().
  90. ///
  91. /// The 'type' is actually the name of the library, minus the '_ds.so' postfix
  92. /// Datasource implementation libraries therefore have a fixed name, both for
  93. /// easy recognition and to reduce potential mistakes.
  94. /// For example, the sqlite3 implementation has the type 'sqlite3', and the
  95. /// derived filename 'sqlite3_ds.so'
  96. ///
  97. /// There are of course some demands to an implementation, not all of which
  98. /// can be verified compile-time. It must provide a creator and destructor
  99. /// functions. The creator function must return an instance of a subclass of
  100. /// DataSourceClient.
  101. ///
  102. class DataSourceClientContainer {
  103. public:
  104. /// \brief Constructor
  105. ///
  106. /// \exception DataSourceLibraryError if there is an error loading the
  107. /// backend library
  108. /// \exception DataSourceConfigError if the given config is not correct
  109. /// for the given type
  110. ///
  111. /// \param type The type of the datasource client. Based on the value of
  112. /// type, a specific backend library is used, by appending the
  113. /// string '_ds.so' to the given type, and loading that as the
  114. /// implementation library
  115. /// \param config Type-specific configuration data, see the documentation
  116. /// of the datasource backend type for information on what
  117. /// configuration data to pass.
  118. DataSourceClientContainer(const std::string& type,
  119. isc::data::ConstElementPtr config);
  120. /// \brief Destructor
  121. ~DataSourceClientContainer();
  122. /// \brief Accessor to the instance
  123. ///
  124. /// \return Reference to the DataSourceClient instance contained in this
  125. /// container.
  126. DataSourceClient& getInstance() { return *instance_; }
  127. private:
  128. DataSourceClient* instance_;
  129. ds_destructor* destructor_;
  130. DLHolder ds_lib_;
  131. };
  132. } // end namespace datasrc
  133. } // end namespace isc
  134. #endif // DATA_SOURCE_FACTORY_H
  135. // Local Variables:
  136. // mode: c++
  137. // End: