client_connection.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef CLIENT_CONNECTION_H
  7. #define CLIENT_CONNECTION_H
  8. #include <asiolink/io_service.h>
  9. #include <cc/json_feed.h>
  10. #include <boost/shared_ptr.hpp>
  11. #include <functional>
  12. namespace isc {
  13. namespace config {
  14. class ClientConnectionImpl;
  15. /// @brief Represents client side connection over the unix domain socket.
  16. ///
  17. /// This class represents a client side connection between the controlling
  18. /// client and the server exposing control API over a unix domain socket.
  19. /// In particular, this class is used by the Kea Control Agent to establish
  20. /// connections with respective Kea services to forward received commands.
  21. /// As of Kea 1.2 the servers can handle a single connection at the time.
  22. /// In the future, we're planning to support multiple simulatenous connections.
  23. /// In this case, each connection will be handled by a unique instance of the
  24. /// @ref ClientConnection class.
  25. ///
  26. /// The @ref ClientConnection supports asynchronous connections. A caller
  27. /// creates an instance of the @ref ClientConnection and calls
  28. /// @ref ClientConnection::start to start asynchronous communication with
  29. /// a remote server. The caller provides a pointer to the callback function
  30. /// (handler) which will be called when the communication with the server
  31. /// completes, i.e. the command is sent to the server and the response
  32. /// from the server is received. If an error occurs, the callback is
  33. /// invoked with an error code indicating a reason for the failure.
  34. ///
  35. /// The documentation of the @ref ClientConnection::start explains the
  36. /// sequence of operations performed by this class.
  37. ///
  38. /// Even though the @ref ClientConnection is asynchronous in nature, it
  39. /// can also be used in cases requiring synchronous communication. As it
  40. /// has been already mentioned, the servers in Kea 1.2 do not support
  41. /// multiple concurrent connections. The following pseudo code demonstrate
  42. /// how to perform synchronous transaction using this class.
  43. ///
  44. /// @code
  45. /// IOService io_service;
  46. /// ClientConnection conn(io_service);
  47. /// bool cb_invoked = false;
  48. /// conn.start(ClientConnection::SocketPath("/tmp/kea.sock"),
  49. /// ClientConnection::ControlCommand(command),
  50. /// [this, &cb_invoked](const boost::system::error_code& ec,
  51. /// const ConstJSONFeedPtr& feed) {
  52. /// cb_invoked = true;
  53. /// if (ec) {
  54. /// ... handle error here ...
  55. /// } else {
  56. /// ... use feed to retrieve the response ...
  57. /// }
  58. /// }
  59. /// );
  60. /// while (!cb_invoked) {
  61. /// io_service.run_one();
  62. /// }
  63. /// @endcode
  64. ///
  65. class ClientConnection {
  66. public:
  67. /// @name Structures used for strong typing.
  68. ///
  69. //@{
  70. /// @brief Encapsulates socket path.
  71. struct SocketPath {
  72. explicit SocketPath(const std::string& socket_path)
  73. : socket_path_(socket_path) { }
  74. std::string socket_path_;
  75. };
  76. /// @brief Encapsulates control command.
  77. struct ControlCommand {
  78. explicit ControlCommand(const std::string control_command)
  79. : control_command_(control_command) { }
  80. std::string control_command_;
  81. };
  82. /// @brief Encapsulates timeout value.
  83. struct Timeout {
  84. explicit Timeout(const long timeout)
  85. : timeout_(timeout) { }
  86. long timeout_;
  87. };
  88. //@}
  89. /// @brief Type of the callback invoked when the communication with
  90. /// the server is complete or an error has occurred.
  91. typedef std::function<void(const boost::system::error_code& ec,
  92. const ConstJSONFeedPtr& feed)> Handler;
  93. /// @brief Constructor.
  94. ///
  95. /// @param io_service Reference to the IO service.
  96. explicit ClientConnection(asiolink::IOService& io_service);
  97. /// @brief Destructor.
  98. ///
  99. /// Closes current connection.
  100. ~ClientConnection();
  101. /// @brief Starts asynchronous transaction with a remote endpoint.
  102. ///
  103. /// Starts asynchronous connection with the remote endpoint. If the
  104. /// connection is successful, the control command is asynchronously
  105. /// sent to the remote endpoint. When the entire command has been sent,
  106. /// the response is read asynchronously, possibly in multiple chunks.
  107. ///
  108. /// The timeout is specified for the entire transaction in milliseconds.
  109. /// If the transaction takes longer than the timeout value the connection
  110. /// is closed and the callback is called with the error code of
  111. /// @c boost::asio::error::timed_out.
  112. ///
  113. /// In other cases, the callback is called with the error code returned
  114. /// by the boost asynchronous operations. If the transaction is successful
  115. /// the 'success' status is indicated with the error code. In addition
  116. /// the instance of the @ref JSONFeed is returned to the caller. It can
  117. /// be used to retrieve parsed response from the server. Note that the
  118. /// response may still be malformed, even if no error is signalled in
  119. /// the handler. The @ref JSONFeed::toElement will return a parsing
  120. /// error if the JSON appears to be malformed.
  121. ///
  122. /// @param socket_path Path to the socket description that the server
  123. /// is bound to.
  124. /// @param command Control command to be sent to the server.
  125. /// @param handler Pointer to the user suppiled callback function which
  126. /// should be invoked when transaction completes or when an error has
  127. /// occurred during the transaction.
  128. /// @param timeout Connection timeout in milliseconds.
  129. void start(const SocketPath& socket_path, const ControlCommand& command,
  130. const Handler& handler, const Timeout& timeout = Timeout(10000));
  131. /// @brief Closes the connection.
  132. void stop();
  133. private:
  134. /// @brief Pointer to the implementation.
  135. boost::shared_ptr<ClientConnectionImpl> impl_;
  136. };
  137. /// @brief Type of the pointer to the @ref ClientConnection object.
  138. typedef boost::shared_ptr<ClientConnection> ClientConnectionPtr;
  139. } // end of namespace config
  140. } // end of namespace isc
  141. #endif // CLIENT_CONNECTION_H