PageRenderTime 55ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/llsdrpcclient.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 323 lines | 144 code | 22 blank | 157 comment | 4 complexity | 0e23164e0e7181bb31d38fa1d8ee8225 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsdrpcclient.h
  3. * @author Phoenix
  4. * @date 2005-11-05
  5. * @brief Implementation and helpers for structure data RPC clients.
  6. *
  7. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #ifndef LL_LLSDRPCCLIENT_H
  29. #define LL_LLSDRPCCLIENT_H
  30. /**
  31. * This file declares classes to encapsulate a basic structured data
  32. * remote procedure client.
  33. */
  34. #include "llchainio.h"
  35. #include "llfiltersd2xmlrpc.h"
  36. #include "lliopipe.h"
  37. #include "llurlrequest.h"
  38. /**
  39. * @class LLSDRPCClientResponse
  40. * @brief Abstract base class to represent a response from an SD server.
  41. *
  42. * This is used as a base class for callbacks generated from an
  43. * structured data remote procedure call. The
  44. * <code>extractResponse</code> method will deal with the llsdrpc method
  45. * call overhead, and keep track of what to call during the next call
  46. * into <code>process</code>. If you use this as a base class, you
  47. * need to implement <code>response</code>, <code>fault</code>, and
  48. * <code>error</code> to do something useful. When in those methods,
  49. * you can parse and utilize the mReturnValue member data.
  50. */
  51. class LLSDRPCResponse : public LLIOPipe
  52. {
  53. public:
  54. LLSDRPCResponse();
  55. virtual ~LLSDRPCResponse();
  56. /**
  57. * @brief This method extracts the response out of the sd passed in
  58. *
  59. * Any appropriate data found in the sd passed in will be
  60. * extracted and managed by this object - not copied or cloned. It
  61. * will still be up to the caller to delete the pointer passed in.
  62. * @param sd The raw structured data response from the remote server.
  63. * @return Returns true if this was able to parse the structured data.
  64. */
  65. bool extractResponse(const LLSD& sd);
  66. protected:
  67. /**
  68. * @brief Method called when the response is ready.
  69. */
  70. virtual bool response(LLPumpIO* pump) = 0;
  71. /**
  72. * @brief Method called when a fault is generated by the remote server.
  73. */
  74. virtual bool fault(LLPumpIO* pump) = 0;
  75. /**
  76. * @brief Method called when there was an error
  77. */
  78. virtual bool error(LLPumpIO* pump) = 0;
  79. protected:
  80. /* @name LLIOPipe virtual implementations
  81. */
  82. //@{
  83. /**
  84. * @brief Process the data in buffer
  85. */
  86. virtual EStatus process_impl(
  87. const LLChannelDescriptors& channels,
  88. buffer_ptr_t& buffer,
  89. bool& eos,
  90. LLSD& context,
  91. LLPumpIO* pump);
  92. //@}
  93. protected:
  94. LLSD mReturnValue;
  95. bool mIsError;
  96. bool mIsFault;
  97. };
  98. /**
  99. * @class LLSDRPCClient
  100. * @brief Client class for a structured data remote procedure call.
  101. *
  102. * This class helps deal with making structured data calls to a remote
  103. * server. You can visualize the calls as:
  104. * <code>
  105. * response = uri.method(parameter)
  106. * </code>
  107. * where you pass in everything to <code>call</code> and this class
  108. * takes care of the rest of the details.
  109. * In typical usage, you will derive a class from this class and
  110. * provide an API more useful for the specific application at
  111. * hand. For example, if you were writing a service to send an instant
  112. * message, you could create an API for it to send the messsage, and
  113. * that class would do the work of translating it into the method and
  114. * parameter, find the destination, and invoke <code>call</call> with
  115. * a useful implementation of LLSDRPCResponse passed in to handle the
  116. * response from the network.
  117. */
  118. class LLSDRPCClient : public LLIOPipe
  119. {
  120. public:
  121. LLSDRPCClient();
  122. virtual ~LLSDRPCClient();
  123. /**
  124. * @brief Enumeration for tracking which queue to process the
  125. * response.
  126. */
  127. enum EPassBackQueue
  128. {
  129. EPBQ_PROCESS,
  130. EPBQ_CALLBACK,
  131. };
  132. /**
  133. * @brief Call a method on a remote LLSDRPCServer
  134. *
  135. * @param uri The remote object to call, eg,
  136. * http://localhost/usher. If you are using a factory with a fixed
  137. * url, the uri passed in will probably be ignored.
  138. * @param method The method to call on the remote object
  139. * @param parameter The parameter to pass into the remote
  140. * object. It is up to the caller to delete the value passed in.
  141. * @param response The object which gets the response.
  142. * @param queue Specifies to call the response on the process or
  143. * callback queue.
  144. * @return Returns true if this object will be able to make the RPC call.
  145. */
  146. bool call(
  147. const std::string& uri,
  148. const std::string& method,
  149. const LLSD& parameter,
  150. LLSDRPCResponse* response,
  151. EPassBackQueue queue);
  152. /**
  153. * @brief Call a method on a remote LLSDRPCServer
  154. *
  155. * @param uri The remote object to call, eg,
  156. * http://localhost/usher. If you are using a factory with a fixed
  157. * url, the uri passed in will probably be ignored.
  158. * @param method The method to call on the remote object
  159. * @param parameter The seriailized parameter to pass into the
  160. * remote object.
  161. * @param response The object which gets the response.
  162. * @param queue Specifies to call the response on the process or
  163. * callback queue.
  164. * @return Returns true if this object will be able to make the RPC call.
  165. */
  166. bool call(
  167. const std::string& uri,
  168. const std::string& method,
  169. const std::string& parameter,
  170. LLSDRPCResponse* response,
  171. EPassBackQueue queue);
  172. protected:
  173. /**
  174. * @brief Enumeration for tracking client state.
  175. */
  176. enum EState
  177. {
  178. STATE_NONE,
  179. STATE_READY,
  180. STATE_WAITING_FOR_RESPONSE,
  181. STATE_DONE
  182. };
  183. /* @name LLIOPipe virtual implementations
  184. */
  185. //@{
  186. /**
  187. * @brief Process the data in buffer
  188. */
  189. virtual EStatus process_impl(
  190. const LLChannelDescriptors& channels,
  191. buffer_ptr_t& buffer,
  192. bool& eos,
  193. LLSD& context,
  194. LLPumpIO* pump);
  195. //@}
  196. protected:
  197. EState mState;
  198. std::string mURI;
  199. std::string mRequest;
  200. EPassBackQueue mQueue;
  201. LLIOPipe::ptr_t mResponse;
  202. };
  203. /**
  204. * @class LLSDRPCClientFactory
  205. * @brief Basic implementation for making an SD RPC client factory
  206. *
  207. * This class eases construction of a basic sd rpc client. Here is an
  208. * example of it's use:
  209. * <code>
  210. * class LLUsefulService : public LLService { ... }
  211. * LLService::registerCreator(
  212. * "useful",
  213. * LLService::creator_t(new LLSDRPCClientFactory<LLUsefulService>))
  214. * </code>
  215. */
  216. template<class Client>
  217. class LLSDRPCClientFactory : public LLChainIOFactory
  218. {
  219. public:
  220. LLSDRPCClientFactory() {}
  221. LLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
  222. virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
  223. {
  224. lldebugs << "LLSDRPCClientFactory::build" << llendl;
  225. LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
  226. if(!http->isValid())
  227. {
  228. llwarns << "Creating LLURLRequest failed." << llendl ;
  229. delete http;
  230. return false;
  231. }
  232. LLIOPipe::ptr_t service(new Client);
  233. chain.push_back(service);
  234. LLIOPipe::ptr_t http_pipe(http);
  235. http->addHeader("Content-Type: text/llsd");
  236. if(mURL.empty())
  237. {
  238. chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
  239. }
  240. else
  241. {
  242. http->setURL(mURL);
  243. }
  244. chain.push_back(http_pipe);
  245. chain.push_back(service);
  246. return true;
  247. }
  248. protected:
  249. std::string mURL;
  250. };
  251. /**
  252. * @class LLXMLSDRPCClientFactory
  253. * @brief Basic implementation for making an XMLRPC to SD RPC client factory
  254. *
  255. * This class eases construction of a basic sd rpc client which uses
  256. * xmlrpc as a serialization grammar. Here is an example of it's use:
  257. * <code>
  258. * class LLUsefulService : public LLService { ... }
  259. * LLService::registerCreator(
  260. * "useful",
  261. * LLService::creator_t(new LLXMLSDRPCClientFactory<LLUsefulService>))
  262. * </code>
  263. */
  264. template<class Client>
  265. class LLXMLSDRPCClientFactory : public LLChainIOFactory
  266. {
  267. public:
  268. LLXMLSDRPCClientFactory() {}
  269. LLXMLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
  270. virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
  271. {
  272. lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
  273. LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
  274. if(!http->isValid())
  275. {
  276. llwarns << "Creating LLURLRequest failed." << llendl ;
  277. delete http;
  278. return false ;
  279. }
  280. LLIOPipe::ptr_t service(new Client);
  281. chain.push_back(service);
  282. LLIOPipe::ptr_t http_pipe(http);
  283. http->addHeader("Content-Type: text/xml");
  284. if(mURL.empty())
  285. {
  286. chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
  287. }
  288. else
  289. {
  290. http->setURL(mURL);
  291. }
  292. chain.push_back(LLIOPipe::ptr_t(new LLFilterSD2XMLRPCRequest(NULL)));
  293. chain.push_back(http_pipe);
  294. chain.push_back(LLIOPipe::ptr_t(new LLFilterXMLRPCResponse2LLSD));
  295. chain.push_back(service);
  296. return true;
  297. }
  298. protected:
  299. std::string mURL;
  300. };
  301. #endif // LL_LLSDRPCCLIENT_H