Imported existing code
This commit is contained in:
315
indra/llmessage/llsdrpcclient.h
Normal file
315
indra/llmessage/llsdrpcclient.h
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @file llsdrpcclient.h
|
||||
* @author Phoenix
|
||||
* @date 2005-11-05
|
||||
* @brief Implementation and helpers for structure data RPC clients.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2005-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLSDRPCCLIENT_H
|
||||
#define LL_LLSDRPCCLIENT_H
|
||||
|
||||
/**
|
||||
* This file declares classes to encapsulate a basic structured data
|
||||
* remote procedure client.
|
||||
*/
|
||||
|
||||
#include "llchainio.h"
|
||||
#include "llfiltersd2xmlrpc.h"
|
||||
#include "lliopipe.h"
|
||||
#include "llurlrequest.h"
|
||||
|
||||
/**
|
||||
* @class LLSDRPCClientResponse
|
||||
* @brief Abstract base class to represent a response from an SD server.
|
||||
*
|
||||
* This is used as a base class for callbacks generated from an
|
||||
* structured data remote procedure call. The
|
||||
* <code>extractResponse</code> method will deal with the llsdrpc method
|
||||
* call overhead, and keep track of what to call during the next call
|
||||
* into <code>process</code>. If you use this as a base class, you
|
||||
* need to implement <code>response</code>, <code>fault</code>, and
|
||||
* <code>error</code> to do something useful. When in those methods,
|
||||
* you can parse and utilize the mReturnValue member data.
|
||||
*/
|
||||
class LLSDRPCResponse : public LLIOPipe
|
||||
{
|
||||
public:
|
||||
LLSDRPCResponse();
|
||||
virtual ~LLSDRPCResponse();
|
||||
|
||||
/**
|
||||
* @brief This method extracts the response out of the sd passed in
|
||||
*
|
||||
* Any appropriate data found in the sd passed in will be
|
||||
* extracted and managed by this object - not copied or cloned. It
|
||||
* will still be up to the caller to delete the pointer passed in.
|
||||
* @param sd The raw structured data response from the remote server.
|
||||
* @return Returns true if this was able to parse the structured data.
|
||||
*/
|
||||
bool extractResponse(const LLSD& sd);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Method called when the response is ready.
|
||||
*/
|
||||
virtual bool response(LLPumpIO* pump) = 0;
|
||||
|
||||
/**
|
||||
* @brief Method called when a fault is generated by the remote server.
|
||||
*/
|
||||
virtual bool fault(LLPumpIO* pump) = 0;
|
||||
|
||||
/**
|
||||
* @brief Method called when there was an error
|
||||
*/
|
||||
virtual bool error(LLPumpIO* pump) = 0;
|
||||
|
||||
protected:
|
||||
/* @name LLIOPipe virtual implementations
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* @brief Process the data in buffer
|
||||
*/
|
||||
virtual EStatus process_impl(
|
||||
const LLChannelDescriptors& channels,
|
||||
buffer_ptr_t& buffer,
|
||||
bool& eos,
|
||||
LLSD& context,
|
||||
LLPumpIO* pump);
|
||||
//@}
|
||||
|
||||
protected:
|
||||
LLSD mReturnValue;
|
||||
bool mIsError;
|
||||
bool mIsFault;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLSDRPCClient
|
||||
* @brief Client class for a structured data remote procedure call.
|
||||
*
|
||||
* This class helps deal with making structured data calls to a remote
|
||||
* server. You can visualize the calls as:
|
||||
* <code>
|
||||
* response = uri.method(parameter)
|
||||
* </code>
|
||||
* where you pass in everything to <code>call</code> and this class
|
||||
* takes care of the rest of the details.
|
||||
* In typical usage, you will derive a class from this class and
|
||||
* provide an API more useful for the specific application at
|
||||
* hand. For example, if you were writing a service to send an instant
|
||||
* message, you could create an API for it to send the messsage, and
|
||||
* that class would do the work of translating it into the method and
|
||||
* parameter, find the destination, and invoke <code>call</call> with
|
||||
* a useful implementation of LLSDRPCResponse passed in to handle the
|
||||
* response from the network.
|
||||
*/
|
||||
class LLSDRPCClient : public LLIOPipe
|
||||
{
|
||||
public:
|
||||
LLSDRPCClient();
|
||||
virtual ~LLSDRPCClient();
|
||||
|
||||
/**
|
||||
* @brief Enumeration for tracking which queue to process the
|
||||
* response.
|
||||
*/
|
||||
enum EPassBackQueue
|
||||
{
|
||||
EPBQ_PROCESS,
|
||||
EPBQ_CALLBACK,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Call a method on a remote LLSDRPCServer
|
||||
*
|
||||
* @param uri The remote object to call, eg,
|
||||
* http://localhost/usher. If you are using a factory with a fixed
|
||||
* url, the uri passed in will probably be ignored.
|
||||
* @param method The method to call on the remote object
|
||||
* @param parameter The parameter to pass into the remote
|
||||
* object. It is up to the caller to delete the value passed in.
|
||||
* @param response The object which gets the response.
|
||||
* @param queue Specifies to call the response on the process or
|
||||
* callback queue.
|
||||
* @return Returns true if this object will be able to make the RPC call.
|
||||
*/
|
||||
bool call(
|
||||
const std::string& uri,
|
||||
const std::string& method,
|
||||
const LLSD& parameter,
|
||||
LLSDRPCResponse* response,
|
||||
EPassBackQueue queue);
|
||||
|
||||
/**
|
||||
* @brief Call a method on a remote LLSDRPCServer
|
||||
*
|
||||
* @param uri The remote object to call, eg,
|
||||
* http://localhost/usher. If you are using a factory with a fixed
|
||||
* url, the uri passed in will probably be ignored.
|
||||
* @param method The method to call on the remote object
|
||||
* @param parameter The seriailized parameter to pass into the
|
||||
* remote object.
|
||||
* @param response The object which gets the response.
|
||||
* @param queue Specifies to call the response on the process or
|
||||
* callback queue.
|
||||
* @return Returns true if this object will be able to make the RPC call.
|
||||
*/
|
||||
bool call(
|
||||
const std::string& uri,
|
||||
const std::string& method,
|
||||
const std::string& parameter,
|
||||
LLSDRPCResponse* response,
|
||||
EPassBackQueue queue);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Enumeration for tracking client state.
|
||||
*/
|
||||
enum EState
|
||||
{
|
||||
STATE_NONE,
|
||||
STATE_READY,
|
||||
STATE_WAITING_FOR_RESPONSE,
|
||||
STATE_DONE
|
||||
};
|
||||
|
||||
/* @name LLIOPipe virtual implementations
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* @brief Process the data in buffer
|
||||
*/
|
||||
virtual EStatus process_impl(
|
||||
const LLChannelDescriptors& channels,
|
||||
buffer_ptr_t& buffer,
|
||||
bool& eos,
|
||||
LLSD& context,
|
||||
LLPumpIO* pump);
|
||||
//@}
|
||||
|
||||
protected:
|
||||
EState mState;
|
||||
std::string mURI;
|
||||
std::string mRequest;
|
||||
EPassBackQueue mQueue;
|
||||
LLIOPipe::ptr_t mResponse;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLSDRPCClientFactory
|
||||
* @brief Basic implementation for making an SD RPC client factory
|
||||
*
|
||||
* This class eases construction of a basic sd rpc client. Here is an
|
||||
* example of it's use:
|
||||
* <code>
|
||||
* class LLUsefulService : public LLService { ... }
|
||||
* LLService::registerCreator(
|
||||
* "useful",
|
||||
* LLService::creator_t(new LLSDRPCClientFactory<LLUsefulService>))
|
||||
* </code>
|
||||
*/
|
||||
template<class Client>
|
||||
class LLSDRPCClientFactory : public LLChainIOFactory
|
||||
{
|
||||
public:
|
||||
LLSDRPCClientFactory() {}
|
||||
LLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
|
||||
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
|
||||
{
|
||||
lldebugs << "LLSDRPCClientFactory::build" << llendl;
|
||||
LLIOPipe::ptr_t service(new Client);
|
||||
chain.push_back(service);
|
||||
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
|
||||
LLIOPipe::ptr_t http_pipe(http);
|
||||
http->addHeader("Content-Type: text/llsd");
|
||||
if(mURL.empty())
|
||||
{
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
|
||||
}
|
||||
else
|
||||
{
|
||||
http->setURL(mURL);
|
||||
}
|
||||
chain.push_back(http_pipe);
|
||||
chain.push_back(service);
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
std::string mURL;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLXMLSDRPCClientFactory
|
||||
* @brief Basic implementation for making an XMLRPC to SD RPC client factory
|
||||
*
|
||||
* This class eases construction of a basic sd rpc client which uses
|
||||
* xmlrpc as a serialization grammar. Here is an example of it's use:
|
||||
* <code>
|
||||
* class LLUsefulService : public LLService { ... }
|
||||
* LLService::registerCreator(
|
||||
* "useful",
|
||||
* LLService::creator_t(new LLXMLSDRPCClientFactory<LLUsefulService>))
|
||||
* </code>
|
||||
*/
|
||||
template<class Client>
|
||||
class LLXMLSDRPCClientFactory : public LLChainIOFactory
|
||||
{
|
||||
public:
|
||||
LLXMLSDRPCClientFactory() {}
|
||||
LLXMLSDRPCClientFactory(const std::string& fixed_url) : mURL(fixed_url) {}
|
||||
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
|
||||
{
|
||||
lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
|
||||
LLIOPipe::ptr_t service(new Client);
|
||||
chain.push_back(service);
|
||||
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
|
||||
LLIOPipe::ptr_t http_pipe(http);
|
||||
http->addHeader("Content-Type: text/xml");
|
||||
if(mURL.empty())
|
||||
{
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
|
||||
}
|
||||
else
|
||||
{
|
||||
http->setURL(mURL);
|
||||
}
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLFilterSD2XMLRPCRequest(NULL)));
|
||||
chain.push_back(http_pipe);
|
||||
chain.push_back(LLIOPipe::ptr_t(new LLFilterXMLRPCResponse2LLSD));
|
||||
chain.push_back(service);
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
std::string mURL;
|
||||
};
|
||||
|
||||
#endif // LL_LLSDRPCCLIENT_H
|
||||
Reference in New Issue
Block a user