1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2 
3 #ifndef JSONRPCCONNECTION_H
4 #define JSONRPCCONNECTION_H
5 
6 #include "remote/i2-remote.hpp"
7 #include "remote/endpoint.hpp"
8 #include "base/io-engine.hpp"
9 #include "base/tlsstream.hpp"
10 #include "base/timer.hpp"
11 #include "base/workqueue.hpp"
12 #include <memory>
13 #include <vector>
14 #include <boost/asio/io_context.hpp>
15 #include <boost/asio/io_context_strand.hpp>
16 #include <boost/asio/spawn.hpp>
17 
18 namespace icinga
19 {
20 
21 enum ClientRole
22 {
23 	ClientInbound,
24 	ClientOutbound
25 };
26 
27 enum ClientType
28 {
29 	ClientJsonRpc,
30 	ClientHttp
31 };
32 
33 class MessageOrigin;
34 
35 /**
36  * An API client connection.
37  *
38  * @ingroup remote
39  */
40 class JsonRpcConnection final : public Object
41 {
42 public:
43 	DECLARE_PTR_TYPEDEFS(JsonRpcConnection);
44 
45 	JsonRpcConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, ConnectionRole role);
46 
47 	void Start();
48 
49 	double GetTimestamp() const;
50 	String GetIdentity() const;
51 	bool IsAuthenticated() const;
52 	Endpoint::Ptr GetEndpoint() const;
53 	Shared<AsioTlsStream>::Ptr GetStream() const;
54 	ConnectionRole GetRole() const;
55 
56 	void Disconnect();
57 
58 	void SendMessage(const Dictionary::Ptr& request);
59 	void SendRawMessage(const String& request);
60 
61 	static Value HeartbeatAPIHandler(const intrusive_ptr<MessageOrigin>& origin, const Dictionary::Ptr& params);
62 
63 	static double GetWorkQueueRate();
64 
65 	static void SendCertificateRequest(const JsonRpcConnection::Ptr& aclient, const intrusive_ptr<MessageOrigin>& origin, const String& path);
66 
67 private:
68 	String m_Identity;
69 	bool m_Authenticated;
70 	Endpoint::Ptr m_Endpoint;
71 	Shared<AsioTlsStream>::Ptr m_Stream;
72 	ConnectionRole m_Role;
73 	double m_Timestamp;
74 	double m_Seen;
75 	double m_NextHeartbeat;
76 	boost::asio::io_context::strand m_IoStrand;
77 	std::vector<String> m_OutgoingMessagesQueue;
78 	AsioConditionVariable m_OutgoingMessagesQueued;
79 	AsioConditionVariable m_WriterDone;
80 	bool m_ShuttingDown;
81 	boost::asio::deadline_timer m_CheckLivenessTimer, m_HeartbeatTimer;
82 
83 	JsonRpcConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, ConnectionRole role, boost::asio::io_context& io);
84 
85 	void HandleIncomingMessages(boost::asio::yield_context yc);
86 	void WriteOutgoingMessages(boost::asio::yield_context yc);
87 	void HandleAndWriteHeartbeats(boost::asio::yield_context yc);
88 	void CheckLiveness(boost::asio::yield_context yc);
89 
90 	bool ProcessMessage();
91 	void MessageHandler(const String& jsonString);
92 
93 	void CertificateRequestResponseHandler(const Dictionary::Ptr& message);
94 
95 	void SendMessageInternal(const Dictionary::Ptr& request);
96 };
97 
98 }
99 
100 #endif /* JSONRPCCONNECTION_H */
101