ccsession.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright (C) 2009 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. // $Id$
  15. #ifndef __CCSESSION_H
  16. #define __CCSESSION_H 1
  17. #include <string>
  18. #include <config/config_data.h>
  19. #include <config/module_spec.h>
  20. #include <cc/session.h>
  21. #include <cc/data.h>
  22. namespace boost {
  23. namespace asio {
  24. class io_service;
  25. }
  26. }
  27. namespace isc {
  28. namespace config {
  29. ///
  30. /// \brief A standard cc session exception that is thrown if a function
  31. /// is there is a problem with one of the messages
  32. ///
  33. // todo: include types and called function in the exception
  34. class CCSessionError : public isc::Exception {
  35. public:
  36. CCSessionError(const char* file, size_t line, const char* what) :
  37. isc::Exception(file, line, what) {}
  38. };
  39. ///
  40. /// \brief This modules keeps a connection to the command channel,
  41. /// holds configuration information, and handles messages from
  42. /// the command channel
  43. ///
  44. class ModuleCCSession : public ConfigData {
  45. public:
  46. /**
  47. * Initialize a config/command session
  48. * @param module_name: The name of this module. This is not a
  49. * reference because we expect static strings
  50. * to be passed here.
  51. * @param spec_file_name: The name of the file containing the
  52. * module specification.
  53. */
  54. ModuleCCSession(std::string spec_file_name,
  55. isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config) = NULL,
  56. isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args) = NULL
  57. ) throw (isc::cc::SessionError);
  58. ModuleCCSession(std::string spec_file_name,
  59. boost::asio::io_service& io_service,
  60. isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config) = NULL,
  61. isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args) = NULL
  62. ) throw (isc::cc::SessionError);
  63. int getSocket();
  64. /**
  65. * Check if there is a command or config change on the command
  66. * session. If so, the appropriate handler is called if set.
  67. * If not set, a default answer is returned.
  68. * This is a non-blocking read; if there is nothing this function
  69. * will return 0.
  70. */
  71. int check_command();
  72. /**
  73. * The config handler function should expect an ElementPtr containing
  74. * the full configuration where non-default values have been set.
  75. * Later we might want to think about more granular control
  76. * (i.e. this does not scale to for instance lists containing
  77. * 100000 zones, where the whole list is passed every time a single
  78. * thing changes)
  79. */
  80. void setConfigHandler(isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config)) { config_handler_ = config_handler; };
  81. /**
  82. * Set a command handler; the function that is passed takes an
  83. * ElementPtr, pointing to a list element, containing
  84. * [ module_name, command_name, arg1, arg2, ... ]
  85. * The returned ElementPtr should look like
  86. * { "result": [ return_value, result_value ] }
  87. * result value here is optional and depends on the command
  88. *
  89. * This protocol is very likely to change.
  90. */
  91. void set_command_handler(isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args)) { command_handler_ = command_handler; };
  92. /**
  93. * Gives access to the configuration values of a different module
  94. * Once this function has been called with the name of the specification
  95. * file of the module you want the configuration of, you can use
  96. * \c getRemoteConfigValue() to get a specific setting.
  97. * Changes are automatically updated, but you cannot specify handlers
  98. * for those changes, must use \c getRemoteConfigValue() to get a value
  99. * This function will subscribe to the relevant module channel.
  100. *
  101. * \param spec_file_name The path to the specification file of
  102. * the module we want to have configuration
  103. * values from
  104. * \return The name of the module specified in the given specification
  105. * file
  106. */
  107. std::string addRemoteConfig(const std::string& spec_file_name);
  108. /**
  109. * Removes the module with the given name from the remote config
  110. * settings. If the module was not added with \c addRemoteConfig(),
  111. * nothing happens.
  112. */
  113. void removeRemoteConfig(const std::string& module_name);
  114. /**
  115. * Returns the current configuration value for the given module
  116. * name at the given identifier. See \c ConfigData::getValue() for
  117. * more details.
  118. * Raises a ModuleCCSessionError if the module name is unknown
  119. * Raises a DataNotFoundError if the identifier does not exist
  120. * in the specification.
  121. *
  122. * \param module_name The name of the module to get a config value for
  123. * \param identifier The identifier of the config value
  124. * \return The configuration setting at the given identifier
  125. */
  126. ElementPtr getRemoteConfigValue(const std::string& module_name, const std::string& identifier);
  127. private:
  128. void init(
  129. std::string spec_file_name,
  130. isc::data::ElementPtr(*config_handler)(
  131. isc::data::ElementPtr new_config),
  132. isc::data::ElementPtr(*command_handler)(
  133. const std::string& command, const isc::data::ElementPtr args)
  134. ) throw (isc::cc::SessionError);
  135. ModuleSpec read_module_specification(const std::string& filename);
  136. void startCheck();
  137. std::string module_name_;
  138. isc::cc::Session session_;
  139. ModuleSpec module_specification_;
  140. isc::data::ElementPtr config_;
  141. ElementPtr handleConfigUpdate(ElementPtr new_config);
  142. isc::data::ElementPtr(*config_handler_)(isc::data::ElementPtr new_config);
  143. isc::data::ElementPtr(*command_handler_)(const std::string& command, const isc::data::ElementPtr args);
  144. std::map<std::string, ConfigData> remote_module_configs_;
  145. void updateRemoteConfig(const std::string& module_name, ElementPtr new_config);
  146. };
  147. ElementPtr createAnswer(const int rcode);
  148. ElementPtr createAnswer(const int rcode, const ElementPtr arg);
  149. ElementPtr createAnswer(const int rcode, const std::string& arg);
  150. }
  151. }
  152. #endif // __CCSESSION_H
  153. // Local Variables:
  154. // mode: c++
  155. // End: