rippled
Loading...
Searching...
No Matches
RPCSub.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/net/RPCCall.h>
21#include <xrpld/net/RPCSub.h>
22#include <xrpl/basics/Log.h>
23#include <xrpl/basics/StringUtilities.h>
24#include <xrpl/basics/contract.h>
25#include <xrpl/json/to_string.h>
26
27#include <deque>
28
29namespace ripple {
30
31// Subscription object for JSON-RPC
32class RPCSubImp : public RPCSub
33{
34public:
36 InfoSub::Source& source,
37 boost::asio::io_service& io_service,
38 JobQueue& jobQueue,
39 std::string const& strUrl,
40 std::string const& strUsername,
41 std::string const& strPassword,
42 Logs& logs)
43 : RPCSub(source)
44 , m_io_service(io_service)
45 , m_jobQueue(jobQueue)
46 , mUrl(strUrl)
47 , mSSL(false)
48 , mUsername(strUsername)
49 , mPassword(strPassword)
50 , mSending(false)
51 , j_(logs.journal("RPCSub"))
52 , logs_(logs)
53 {
54 parsedURL pUrl;
55
56 if (!parseUrl(pUrl, strUrl))
57 Throw<std::runtime_error>("Failed to parse url.");
58 else if (pUrl.scheme == "https")
59 mSSL = true;
60 else if (pUrl.scheme != "http")
61 Throw<std::runtime_error>("Only http and https is supported.");
62
63 mSeq = 1;
64
65 mIp = pUrl.domain;
66 mPort = (!pUrl.port) ? (mSSL ? 443 : 80) : *pUrl.port;
67 mPath = pUrl.path;
68
69 JLOG(j_.info()) << "RPCCall::fromNetwork sub: ip=" << mIp
70 << " port=" << mPort
71 << " ssl= " << (mSSL ? "yes" : "no") << " path='"
72 << mPath << "'";
73 }
74
75 ~RPCSubImp() = default;
76
77 void
78 send(Json::Value const& jvObj, bool broadcast) override
79 {
81
82 if (mDeque.size() >= eventQueueMax)
83 {
84 // Drop the previous event.
85 JLOG(j_.warn()) << "RPCCall::fromNetwork drop";
87 }
88
89 auto jm = broadcast ? j_.debug() : j_.info();
90 JLOG(jm) << "RPCCall::fromNetwork push: " << jvObj;
91
93
94 if (!mSending)
95 {
96 // Start a sending thread.
97 JLOG(j_.info()) << "RPCCall::fromNetwork start";
98
100 jtCLIENT_SUBSCRIBE, "RPCSub::sendThread", [this]() {
101 sendThread();
102 });
103 }
104 }
105
106 void
107 setUsername(std::string const& strUsername) override
108 {
110
111 mUsername = strUsername;
112 }
113
114 void
115 setPassword(std::string const& strPassword) override
116 {
118
119 mPassword = strPassword;
120 }
121
122private:
123 // XXX Could probably create a bunch of send jobs in a single get of the
124 // lock.
125 void
127 {
128 Json::Value jvEvent;
129 bool bSend;
130
131 do
132 {
133 {
134 // Obtain the lock to manipulate the queue and change sending.
136
137 if (mDeque.empty())
138 {
139 mSending = false;
140 bSend = false;
141 }
142 else
143 {
144 auto const [seq, env] = mDeque.front();
145
147
148 jvEvent = env;
149 jvEvent["seq"] = seq;
150
151 bSend = true;
152 }
153 }
154
155 // Send outside of the lock.
156 if (bSend)
157 {
158 // XXX Might not need this in a try.
159 try
160 {
161 JLOG(j_.info()) << "RPCCall::fromNetwork: " << mIp;
162
165 mIp,
166 mPort,
167 mUsername,
168 mPassword,
169 mPath,
170 "event",
171 jvEvent,
172 mSSL,
173 true,
174 logs_);
175 }
176 catch (const std::exception& e)
177 {
178 JLOG(j_.info())
179 << "RPCCall::fromNetwork exception: " << e.what();
180 }
181 }
182 } while (bSend);
183 }
184
185private:
186 enum { eventQueueMax = 32 };
187
188 boost::asio::io_service& m_io_service;
190
194 bool mSSL;
198
199 int mSeq; // Next id to allocate.
200
201 bool mSending; // Sending threead is active.
202
204
207};
208
209//------------------------------------------------------------------------------
210
212{
213}
214
217 InfoSub::Source& source,
218 boost::asio::io_service& io_service,
219 JobQueue& jobQueue,
220 std::string const& strUrl,
221 std::string const& strUsername,
222 std::string const& strPassword,
223 Logs& logs)
224{
225 return std::make_shared<RPCSubImp>(
226 std::ref(source),
227 std::ref(io_service),
228 std::ref(jobQueue),
229 strUrl,
230 strUsername,
231 strPassword,
232 logs);
233}
234
235} // namespace ripple
Represents a JSON value.
Definition: json_value.h:148
A generic endpoint for log messages.
Definition: Journal.h:60
Stream debug() const
Definition: Journal.h:328
Stream info() const
Definition: Journal.h:334
Stream warn() const
Definition: Journal.h:340
Abstracts the source of subscription data.
Definition: InfoSub.h:67
Manages a client's subscription to data feeds.
Definition: InfoSub.h:51
std::mutex mLock
Definition: InfoSub.h:238
A pool of threads to perform work.
Definition: JobQueue.h:55
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:165
Manages partitions for logging.
Definition: Log.h:51
boost::asio::io_service & m_io_service
Definition: RPCSub.cpp:188
~RPCSubImp()=default
std::string mIp
Definition: RPCSub.cpp:192
std::deque< std::pair< int, Json::Value > > mDeque
Definition: RPCSub.cpp:203
void setPassword(std::string const &strPassword) override
Definition: RPCSub.cpp:115
std::string mUsername
Definition: RPCSub.cpp:195
void sendThread()
Definition: RPCSub.cpp:126
beast::Journal const j_
Definition: RPCSub.cpp:205
std::uint16_t mPort
Definition: RPCSub.cpp:193
JobQueue & m_jobQueue
Definition: RPCSub.cpp:189
RPCSubImp(InfoSub::Source &source, boost::asio::io_service &io_service, JobQueue &jobQueue, std::string const &strUrl, std::string const &strUsername, std::string const &strPassword, Logs &logs)
Definition: RPCSub.cpp:35
void setUsername(std::string const &strUsername) override
Definition: RPCSub.cpp:107
std::string mPath
Definition: RPCSub.cpp:197
void send(Json::Value const &jvObj, bool broadcast) override
Definition: RPCSub.cpp:78
std::string mPassword
Definition: RPCSub.cpp:196
std::string mUrl
Definition: RPCSub.cpp:191
Subscription object for JSON RPC.
Definition: RPCSub.h:32
RPCSub(InfoSub::Source &source)
Definition: RPCSub.cpp:211
An endpoint that consumes resources.
Definition: Consumer.h:35
T empty(T... args)
T front(T... args)
T make_pair(T... args)
void fromNetwork(boost::asio::io_service &io_service, std::string const &strIp, const std::uint16_t iPort, std::string const &strUsername, std::string const &strPassword, std::string const &strPath, std::string const &strMethod, Json::Value const &jvParams, const bool bSSL, const bool quiet, Logs &logs, std::function< void(Json::Value const &jvInput)> callbackFuncP, std::unordered_map< std::string, std::string > headers)
Definition: RPCCall.cpp:1630
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::shared_ptr< RPCSub > make_RPCSub(InfoSub::Source &source, boost::asio::io_service &io_service, JobQueue &jobQueue, std::string const &strUrl, std::string const &strUsername, std::string const &strPassword, Logs &logs)
Definition: RPCSub.cpp:216
bool parseUrl(parsedURL &pUrl, std::string const &strUrl)
@ jtCLIENT_SUBSCRIBE
Definition: Job.h:45
T pop_back(T... args)
T pop_front(T... args)
T push_back(T... args)
T ref(T... args)
T size(T... args)
std::optional< std::uint16_t > port
T what(T... args)