xmlrpc2di makes xmlrpc calls to DI interface possible

git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@339 8eb893ce-cfd4-0310-b710-fb5ebe64c474
sayer/1.4-spce2.6
Stefan Sayer 19 years ago
parent 8eb74d1351
commit 36dc1f6669

@ -0,0 +1,20 @@
XMLRPCPP_DIR = xmlrpc++0.7
plug_in_name = xmlrpc2di
module_ldflags =
module_cflags = -I$(XMLRPCPP_DIR)/src
module_extra_objs = $(XMLRPCPP_DIR)/libXmlRpc.a
extra_clean = clean_libxmlrpc
COREPATH ?=../../../core
include $(COREPATH)/plug-in/Makefile.app_module
$(XMLRPCPP_DIR)/libXmlRpc.a:
$(MAKE) -C $(XMLRPCPP_DIR) libXmlRpc.a
clean_libxmlrpc:
$(MAKE) -C $(XMLRPCPP_DIR) clean

@ -0,0 +1,42 @@
xmlrpc2di: DI call via XMLRPC
This module makes the Dynamic Invocation (DI) Interfaces exported
by component modules accessible from XMLRPC. Additionaly the methods
calls, get_loglevel and set_loglevel are implemented (like in the
stats UDP server).
This module uses the XmlRpc++ library (http://xmlrpcpp.sourceforge.net/).
In order to compile it, the xmlrpc library is needed:
cd apps/examples/xmlrpc2di
wget http://switch.dl.sourceforge.net/sourceforge/xmlrpcpp/xmlrpc++0.7.tar.gz && tar xzvf xmlrpc++0.7.tar.gz
If xmlrpcpp is extracted to a different directory, the path in
the Makefile needs to be adapted.
The first parameter to 'di' is alway the factory name, the second the
function name. Further parameters to XMLRPC calls are converted to DI
ArgArray structure, and result of DI calls are converted back to XMLRPC
parameters. At the moment only string, int and double types are implemented
(no DateTime, struct, binary, ...).
Examples (that hopefully trigger some creativity in the reader ;)
-----------------------------------------------------------------
Register fritz at iptel.org using registrar client over XMLRPC
from python:
import xmlrpclib
server = ServerProxy("http://127.0.0.1:8090")
server.di('registrar_client', 'createRegistration',
'iptel.org', 'fritz', 'Frotz',
'fritz', 'secretpass', '')
To call someone into conference over an account at sparvoip.de
using di_dial:
import xmlrpclib
server = ServerProxy("http://127.0.0.1:8090")
server.di('di_dial', 'dial_auth','conference', 'roomname',
'sip:myuser@sparvoip.de', 'sip:0049301234567@sparvoip.de',
'sparvoip.de','myuser','passwd')

@ -0,0 +1,163 @@
/*
* $Id: XMLRPC2DI.cpp 145 2006-11-26 00:01:18Z sayer $
*
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* sems is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* For a license to use the sems software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* sems is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "XMLRPC2DI.h"
#include "AmSessionContainer.h"
#include "AmPlugIn.h"
#include "log.h"
#include "AmConfigReader.h"
#include "AmUtils.h"
#define MOD_NAME "xmlrpc2di"
#define XMLRPC_PORT "8090" // default port
EXPORT_PLUGIN_CLASS_FACTORY(XMLRPC2DI, MOD_NAME)
XMLRPC2DI::XMLRPC2DI(string mod_name)
: AmDynInvokeFactory(mod_name)
{
}
int XMLRPC2DI::onLoad() {
AmConfigReader cfg;
if(cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf")))
return -1;
string conf_xmlrpc_port = cfg.getParameter("xmlrpc_port",XMLRPC_PORT);
if (conf_xmlrpc_port.empty()) {
ERROR("configuration: xmlrpc_port must be defined!\n");
return -1;
}
if (str2i(conf_xmlrpc_port, XMLRPCPort)) {
ERROR("configuration: unable to decode xmlrpc_port value '%s'!\n",
conf_xmlrpc_port.c_str());
return -1;
}
server = new XMLRPC2DIServer(XMLRPCPort);
server->start();
return 0;
}
// XMLRPC server functions
XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port)
: port(port),
calls_method(&s),
setloglevel_method(&s),
getloglevel_method(&s),
di_method(&s)
{
DBG("Initialized XMLRPC2DIServer with: \n");
DBG(" port = %u\n", port);
}
void XMLRPC2DIServer::run() {
DBG("Binding XMLRPC2DIServer to port %u \n", port);
s.bindAndListen(port);
DBG("starting XMLRPC2DIServer...\n");
s.work(-1.0);
}
void XMLRPC2DIServer::on_stop() {
DBG("sorry, don't know how to stop the server.\n");
}
void XMLRPC2DIServerCallsMethod::execute(XmlRpcValue& params, XmlRpcValue& result) {
int res = AmSessionContainer::instance()->getSize();
DBG("XMLRPC2DI: calls = %d\n", res);
result = res;
}
void XMLRPC2DIServerGetLoglevelMethod::execute(XmlRpcValue& params, XmlRpcValue& result) {
int res = log_level;
DBG("XMLRPC2DI: get_loglevel returns %d\n", res);
result = res;
}
void XMLRPC2DIServerSetLoglevelMethod::execute(XmlRpcValue& params, XmlRpcValue& result) {
log_level = params[0];
DBG("XMLRPC2DI: set log level to %d.\n", (int)params[0]);
result = "200 OK";
}
void XMLRPC2DIServerDIMethod::execute(XmlRpcValue& params, XmlRpcValue& result) {
if (params.size() < 2) {
DBG("XMLRPC2DI: ERROR: need at least factory name and function name to call\n");
throw XmlRpcException("need at least factory name and function name to call", 400);
}
string fact_name = params[0];
string fct_name = params[1];
DBG("XMLRPC2DI: factory '%s' function '%s'\n",
fact_name.c_str(), fct_name.c_str());
// get args
AmArgArray args;
for (int i=2; i<params.size();i++) {
switch (params[i].getType()) {
case XmlRpcValue::TypeInt: { args.push(AmArg((int)params[i])); } break;
case XmlRpcValue::TypeDouble:{ args.push(AmArg((double)params[i])); } break;
case XmlRpcValue::TypeString:{ args.push(AmArg(((string)params[i]).c_str())); } break;
// TODO: support more types (datetime, struct, ...)
default: throw XmlRpcException("unsupported parameter type", 400);
};
}
AmDynInvokeFactory* di_f = AmPlugIn::instance()->getFactory4Di(fact_name);
if(!di_f){
throw XmlRpcException("could not get factory", 500);
}
AmDynInvoke* di = di_f->getInstance();
if(!di){
throw XmlRpcException("could not get instance from factory", 500);
}
AmArgArray ret;
di->invoke(fct_name, args, ret);
if (ret.size()) {
result.setSize(ret.size());
for (unsigned int i=0;i<ret.size();i++) {
const AmArg& r = ret.get(i);
switch (r.getType()) {
case AmArg::CStr:
result[i]= string(r.asCStr()); break;
case AmArg::Int:
result[i]=r.asInt(); break;
case AmArg::Double:
result[i]=r.asDouble(); break;
default: break;
// TODO: do sth with the data here
}
}
}
}

@ -0,0 +1,80 @@
/*
* $Id: XMLRPC2DI.h 145 2006-11-26 00:01:18Z sayer $
*
* Copyright (C) 2007 iptego GmbH
*
* This file is part of sems, a free SIP media server.
*
* sems is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* For a license to use the sems software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* sems is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XMLRPC2DISERVER_H
#define XMLRPC2DISERVER_H
#include "XmlRpc.h"
using namespace XmlRpc;
#include "AmThread.h"
#include "AmApi.h"
#define DEF_XMLRPCSERVERMETHOD(cls_name, func_name) \
class cls_name \
: public XmlRpcServerMethod { \
\
public: \
cls_name(XmlRpcServer* s) : \
XmlRpcServerMethod(func_name, s) { } \
\
void execute(XmlRpcValue& params, XmlRpcValue& result); \
};
DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerCallsMethod, "calls")
DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerSetLoglevelMethod, "set_loglevel")
DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerGetLoglevelMethod, "get_loglevel")
DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerDIMethod, "di")
class XMLRPC2DIServer : public AmThread {
XmlRpcServer s;
unsigned int port;
XMLRPC2DIServerCallsMethod calls_method;
XMLRPC2DIServerSetLoglevelMethod setloglevel_method;
XMLRPC2DIServerGetLoglevelMethod getloglevel_method;
XMLRPC2DIServerDIMethod di_method;
public:
XMLRPC2DIServer(unsigned int port);
void run();
void on_stop();
};
class XMLRPC2DI : public AmDynInvokeFactory {
XMLRPC2DIServer* server;
unsigned int XMLRPCPort;
public:
XMLRPC2DI(string mod_name);
~XMLRPC2DI() { }
int onLoad();
AmDynInvoke* getInstance() { return NULL; }
};
#endif
Loading…
Cancel
Save