Commit 1caef6f9 authored by Pavel Vainerman's avatar Pavel Vainerman

(REST API): добавил в интерфейс UniSetObect_i функцию apiRequest(query)

для возможности использовать REST API без http-сервера, при помощи uniset(RPC) вызовов.
parent 761c5cff
......@@ -41,9 +41,13 @@
/*! получение информации от объекта
\param userparam - Необязательный пользовательский параметр
\deprecated { Эта функция может быть удалена, желательно использовать более универсальную apiRequest }
*/
uniset::SimpleInfo getInfo( in string userparam );
/*! REST API. Формат запроса: /api/version/query_for_object[?param1&param2...] */
uniset::SimpleInfo apiRequest( in string query );
boolean exist(); /*!< проверка существования объекта */
/*! Функция посылки сообщения объекту */
......
......@@ -51,6 +51,7 @@ static struct option longopts[] =
{ "getCalibrate", required_argument, 0, 'y' },
{ "getTimeChange", required_argument, 0, 't' },
{ "oinfo", required_argument, 0, 'p' },
{ "apiRequest", required_argument, 0, 'a' },
{ "verbose", no_argument, 0, 'v' },
{ "quiet", no_argument, 0, 'q' },
{ "csv", required_argument, 0, 'z' },
......@@ -62,7 +63,8 @@ string conffile("configure.xml");
// --------------------------------------------------------------------------
static bool commandToAll( const string& section, std::shared_ptr<ObjectRepository>& rep, Command cmd );
static void createSections(const std::shared_ptr<Configuration>& c );
static void errDoNotReolve( const std::string& oname );
static void errDoNotResolve( const std::string& oname );
static char* checkArg( int ind, int argc, char* argv[] );
// --------------------------------------------------------------------------
int omap();
int configure( const string& args, UInterface& ui );
......@@ -74,6 +76,7 @@ int getTimeChange( const string& args, UInterface& ui );
int getState( const string& args, UInterface& ui );
int getCalibrate( const string& args, UInterface& ui );
int oinfo(const string& args, UInterface& ui , const string& userparam );
int apiRequest( const string& args, UInterface& ui, const string& query );
// --------------------------------------------------------------------------
static void print_help(int width, const string& cmd, const string& help, const string& tab = " " )
{
......@@ -111,6 +114,9 @@ static void usage()
print_help(36, "-p|--oinfo id1@node1,id2@node2,id3,... [userparam]", "Получить информацию об объектах (SimpleInfo). \n userparam - необязательный параметр передаваемый в getInfo() каждому объекту\n");
print_help(36, "", "userparam - необязательный параметр передаваемый в getInfo() каждому объекту\n");
cout << endl;
print_help(36, "-a|--apiRequest id1@node1,id2@node2,id3,... query", "Вызов REST API для каждого объекта\n");
print_help(36, "", "query - Запрос вида: /api/VERSION/query[?param1&param2...]\n");
cout << endl;
print_help(48, "-x|--setValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Выставить значения датчиков\n");
print_help(36, "-g|--getValue id1@node1,id2@node2,id3,id4 ", "Получить значения датчиков.\n");
cout << endl;
......@@ -145,7 +151,7 @@ int main(int argc, char** argv)
while(1)
{
opt = getopt_long(argc, argv, "hc:beosfur:l:i::x:g:w:y:p:vqz:", longopts, &optindex);
opt = getopt_long(argc, argv, "hc:beosfur:l:i::x:g:w:y:p:vqz:a:", longopts, &optindex);
if( opt == -1 )
break;
......@@ -236,15 +242,35 @@ int main(int argc, char** argv)
UInterface ui(conf);
ui.initBackId(uniset::AdminID);
std::string userparam = {""};
std::string userparam = { "" };
if( optind < argc )
userparam = argv[optind];
if( checkArg(optind + 1, argc, argv) )
userparam = string(argv[optind + 1]);
return oinfo(optarg, ui, userparam);
}
break;
case 'a': //--apiRequest
{
if( checkArg(optind, argc, argv) == 0 )
{
if( !quiet )
cerr << "admin(apiRequest): Unknown 'query'. Use: id,name,name2@nodeX /api/vesion/query.." << endl;
return 1;
}
auto conf = uniset_init(argc, argv, conffile);
UInterface ui(conf);
ui.initBackId(uniset::AdminID);
std::string query = string(argv[optind]);
return apiRequest(optarg, ui, query);
}
break;
case 'e': //--exist
{
// cout<<"(main):received option --exist"<<endl;
......@@ -441,7 +467,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{
if( CORBA::is_nil(obj) )
{
errDoNotReolve(ob);
errDoNotResolve(ob);
break;
}
......@@ -457,7 +483,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{
if(CORBA::is_nil(obj))
{
errDoNotReolve(ob);
errDoNotResolve(ob);
break;
}
......@@ -473,7 +499,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{
if(CORBA::is_nil(obj))
{
errDoNotReolve(ob);
errDoNotResolve(ob);
break;
}
......@@ -1038,11 +1064,53 @@ int oinfo(const string& args, UInterface& ui, const string& userparam )
return 0;
}
// --------------------------------------------------------------------------------------
int apiRequest( const string& args, UInterface& ui, const string& query )
{
auto conf = uniset_conf();
auto sl = uniset::getObjectsList( args, conf );
// if( verb )
// cout << "apiRequest: query: " << query << endl;
for( auto && it : sl )
{
if( it.node == DefaultObjectId )
it.node = conf->getLocalNode();
try
{
cout << ui.apiRequest(it.id, query, it.node) << endl;
}
catch( const std::exception& ex )
{
if( !quiet )
cerr << "std::exception: " << ex.what() << endl;
}
catch(...)
{
if( !quiet )
cerr << "Unknown exception.." << endl;
}
cout << endl << endl;
}
return 0;
}
// --------------------------------------------------------------------------------------
void errDoNotReolve( const std::string& oname )
void errDoNotResolve( const std::string& oname )
{
if( verb )
cerr << oname << ": resolve failed.." << endl;
}
// --------------------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
{
if( i < argc && (argv[i])[0] != '-' )
return argv[i];
return 0;
}
// --------------------------------------------------------------------------------------
......@@ -17,6 +17,7 @@ ln -s -f admin.sh getChangedTime
ln -s -f admin.sh getCalibrate
ln -s -f admin.sh help
ln -s -f admin.sh oinfo
ln -s -f admin.sh apiRequest
ln -s -f ../../Utilities/scripts/uniset2-start.sh
ln -s -f ../../Utilities/scripts/uniset2-stop.sh stop.sh
......
/*! \page page_REST_API REST API
В библиотеке предусмотрен REST API. Есть два "уровня" доступа к REST API.
Первый - это встроенный в UniSetActivator http-сервер.
\ref sec_SM_REST_API
Второй уровень. Это функция apiRequest(query) которую можно вызывать у каждого
объекта посредством RPC. Её вызов не требует наличия запущенного http-сервера.
\warning С точки зрения надёжности функционирования системы наличие запущенного
http-сервера, а так же наличие функций \b getInfo(userparam) и \b apiRequest(query)
которые возвращают string является \b ОПАСНЫМ. Т.к. размер запросов и ответов в текущей
реализации не контролируется. И при помощи больших запросов можно вызвать переполнение памяти
или крах процессов. На текущий момент контроль оставлен на разработчика конкретной реализации
getInfo() или apiRequest().
*/
\ No newline at end of file
......@@ -5,7 +5,7 @@ export LD_LIBRARY_PATH="../../lib/.libs;../lib/.libs"
ulimit -Sc 10000000000
./uniset2-start.sh -f ./uniset2-smemory --smemory-id SharedMemory \
--confile test.xml --datfile test.xml --db-logging 1 --ulog-add-levels system,level1 \
--confile test.xml --datfile test.xml --db-logging 1 --ulog-add-levels system,level1,level9 \
--sm-log-add-levels any $* --sm-run-logserver --activator-run-httpserver \
#--pulsar-id DO_C --pulsar-iotype DO --pulsar-msec 100
......
......@@ -143,6 +143,7 @@ class UInterface
//! Информация об объекте
std::string getObjectInfo( const uniset::ObjectId id, const std::string& params, const uniset::ObjectId node ) const;
std::string apiRequest( const uniset::ObjectId id, const std::string& query, const uniset::ObjectId node ) const;
//! Получить список датчиков
IOController_i::ShortMapSeq* getSensors( const uniset::ObjectId id,
......
......@@ -99,8 +99,13 @@ class UniSetObject:
return uniset::ObjectType("UniSetObject");
}
const std::string getStrType();
virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override;
// обёртка для вызова HTTP API через RPC
virtual uniset::SimpleInfo* apiRequest( const char* query ) override;
//! поместить сообщение в очередь
virtual void push( const uniset::TransportMessage& msg ) override;
......
......@@ -17,8 +17,9 @@
import json
import urllib2
import urllib
UHTTP_API_VERSION = 'v01'
UHTTP_API_VERSION = 'v0'
class UHTTPError:
......@@ -38,7 +39,13 @@ class UniSetHTTPService:
self.aviver = self.settings['api']
def request(self, query, method='GET', data=None):
"""Послать запрос и получить ответ."""
'''
Послать запрос и получить ответ.
:param query: запрос /xxx?params..
:param method: метод запроса.
:param data: данные для POST запросов
:return: распарсенный json
'''
url = self.settings.get('url') + "/api/" + self.apiver + query
headers = {}
......@@ -52,17 +59,16 @@ class UniSetHTTPService:
return json.loads(resp.read())
except urllib2.URLError, e:
if hasattr(e, 'reason'):
err = 'We failed to reach a server. Reason: ', e.reason
err = 'We failed to reach a server. Reason: %s' % e.reason
raise UHTTPError(err)
elif hasattr(e, 'code'):
err = 'The server couldn\'t fulfill the request. Error code: ', e.code
err = 'The server couldn\'t fulfill the request. Error code: %s' % e.code
raise UHTTPError(err)
raise UHTTPError('Unknown error')
class SharedMemoryAPI(UniSetHTTPService):
"""Работа с SharedMemory."""
def __init__(self, _settings):
UniSetHTTPService.__init__(self, _settings)
......@@ -73,7 +79,11 @@ class SharedMemoryAPI(UniSetHTTPService):
return UniSetHTTPService.request(self, '/' + self.settings['smID'] + '/' + query)
def consumers(self, sens=''):
"""Получить список заказчиков"""
'''
Получить список заказчиков
:param sens: для указанных датчиков
:return: список..
'''
query = '/consumers'
if sens != '':
query += '?%s' % sens
......@@ -81,14 +91,19 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query)[self.settings['smID']]['consumers']
def get(self, sensors='', shortInfo=True):
"""Получить список заказчиков"""
'''
Получить список заказчиков
:param sensors: для указанных датчиков (по умолчанию для всех)
:param shortInfo: выдать только основную информацию по каждому датчику
:return: список..
'''
query = '/get'
params = None
if sensors != '':
params = '?%s' % sensors
if shortInfo:
if params != None:
if params is not None:
params += '&shortInfo'
else:
params = '?shortInfo'
......@@ -99,17 +114,22 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query)[self.settings['smID']]['sensors']
def sensors(self, offset=None, limit=None):
"""Получить список датчиков"""
'''
Получить список датчиков
:param offset: начальное смещение в списке датчиков
:param limit: сколько датиков выдать в ответе
:return: список..
'''
query = '/sensors'
params = None
if offset:
params = '?offset=%d' % offset
if limit:
if params != None:
params += '&limit=%d'%limit
if params is not None:
params += '&limit=%d' % limit
else:
params = '?limit=%d'%limit
params = '?limit=%d' % limit
if params:
query += params
......@@ -117,9 +137,10 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query)
def lost(self):
"""Получить список 'пропавших' заказчиков"""
'''
Получить список 'пропавших' заказчиков
:return: список
'''
return self.request('/lost')[self.settings['smID']]
def help(self):
......
......@@ -206,6 +206,27 @@ throw(UException)
}
}
//---------------------------------------------------------------------------
string UConnector::apiRequest( long id, const string& query, long node ) throw(UException)
{
if( !conf || !ui )
throw USysError();
if( id == UTypes::DefaultID )
throw UException("(apiRequest): Unknown ID..");
if( node == UTypes::DefaultID )
node = conf->getLocalNode();
try
{
return ui->apiRequest(id, query, node);
}
catch( std::exception& ex )
{
throw UException("(apiRequest): error: " + std::string(ex.what()) );
}
}
//---------------------------------------------------------------------------
void UConnector::activate_objects() throw(UException)
{
try
......@@ -219,10 +240,20 @@ void UConnector::activate_objects() throw(UException)
}
}
//---------------------------------------------------------------------------
long UConnector::getObjectID(const string& name )
long UConnector::getObjectID( const string& name )
{
if( conf )
return conf->getObjectID(name);
{
long id = conf->getObjectID(name);
if( id == UTypes::DefaultID )
id = conf->getControllerID(name);
if( id == UTypes::DefaultID )
id = conf->getServiceID(name);
return id;
}
return UTypes::DefaultID;
}
......
......@@ -28,8 +28,8 @@
class UConnector
{
public:
UConnector( int argc, char** argv, const std::string& xmlfile )throw(UException);
UConnector( UTypes::Params* p, const std::string& xmlfile )throw(UException);
UConnector( int argc, char** argv, const std::string& xmlfile ) throw(UException);
UConnector( UTypes::Params* p, const std::string& xmlfile ) throw(UException);
~UConnector();
inline std::string getUIType()
......@@ -39,7 +39,7 @@ class UConnector
std::string getConfFileName();
long getValue( long id, long node )throw(UException);
void setValue( long id, long val, long node, long supplier = UTypes::DefaultSupplerID )throw(UException);
void setValue( long id, long val, long node, long supplier = UTypes::DefaultSupplerID ) throw(UException);
UTypes::ShortIOInfo getTimeChange( long id, long node = UTypes::DefaultID );
long getSensorID( const std::string& name );
......@@ -50,7 +50,8 @@ class UConnector
std::string getName( long id );
std::string getTextName( long id );
std::string getObjectInfo( long id , const std::string& params, long node = UTypes::DefaultID )throw(UException);
std::string getObjectInfo( long id, const std::string& params, long node = UTypes::DefaultID ) throw(UException);
std::string apiRequest( long id, const std::string& query, long node = UTypes::DefaultID ) throw(UException);
void activate_objects() throw(UException);
......
......@@ -5016,6 +5016,187 @@ fail:
}
SWIGINTERN PyObject *_wrap_UConnector_apiRequest__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
UConnector *arg1 = (UConnector *) 0 ;
long arg2 ;
std::string *arg3 = 0 ;
long arg4 ;
void *argp1 = 0 ;
int res1 = 0 ;
long val2 ;
int ecode2 = 0 ;
int res3 = SWIG_OLDOBJ ;
long val4 ;
int ecode4 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
PyObject * obj3 = 0 ;
std::string result;
if (!PyArg_ParseTuple(args,(char *)"OOOO:UConnector_apiRequest",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_UConnector, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "UConnector_apiRequest" "', argument " "1"" of type '" "UConnector *""'");
}
arg1 = reinterpret_cast< UConnector * >(argp1);
ecode2 = SWIG_AsVal_long(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "UConnector_apiRequest" "', argument " "2"" of type '" "long""'");
}
arg2 = static_cast< long >(val2);
{
std::string *ptr = (std::string *)0;
res3 = SWIG_AsPtr_std_string(obj2, &ptr);
if (!SWIG_IsOK(res3)) {
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "UConnector_apiRequest" "', argument " "3"" of type '" "std::string const &""'");
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "UConnector_apiRequest" "', argument " "3"" of type '" "std::string const &""'");
}
arg3 = ptr;
}
ecode4 = SWIG_AsVal_long(obj3, &val4);
if (!SWIG_IsOK(ecode4)) {
SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "UConnector_apiRequest" "', argument " "4"" of type '" "long""'");
}
arg4 = static_cast< long >(val4);
try {
result = (arg1)->apiRequest(arg2,(std::string const &)*arg3,arg4);
}
catch(UException &_e) {
SWIG_Python_Raise(SWIG_NewPointerObj((new UException(static_cast< const UException& >(_e))),SWIGTYPE_p_UException,SWIG_POINTER_OWN), "UException", SWIGTYPE_p_UException); SWIG_fail;
}
resultobj = SWIG_From_std_string(static_cast< std::string >(result));
if (SWIG_IsNewObj(res3)) delete arg3;
return resultobj;
fail:
if (SWIG_IsNewObj(res3)) delete arg3;
return NULL;
}
SWIGINTERN PyObject *_wrap_UConnector_apiRequest__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
UConnector *arg1 = (UConnector *) 0 ;
long arg2 ;
std::string *arg3 = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
long val2 ;
int ecode2 = 0 ;
int res3 = SWIG_OLDOBJ ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
std::string result;
if (!PyArg_ParseTuple(args,(char *)"OOO:UConnector_apiRequest",&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_UConnector, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "UConnector_apiRequest" "', argument " "1"" of type '" "UConnector *""'");
}
arg1 = reinterpret_cast< UConnector * >(argp1);
ecode2 = SWIG_AsVal_long(obj1, &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "UConnector_apiRequest" "', argument " "2"" of type '" "long""'");
}
arg2 = static_cast< long >(val2);
{
std::string *ptr = (std::string *)0;
res3 = SWIG_AsPtr_std_string(obj2, &ptr);
if (!SWIG_IsOK(res3)) {
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "UConnector_apiRequest" "', argument " "3"" of type '" "std::string const &""'");
}
if (!ptr) {
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "UConnector_apiRequest" "', argument " "3"" of type '" "std::string const &""'");
}
arg3 = ptr;
}
try {
result = (arg1)->apiRequest(arg2,(std::string const &)*arg3);
}
catch(UException &_e) {
SWIG_Python_Raise(SWIG_NewPointerObj((new UException(static_cast< const UException& >(_e))),SWIGTYPE_p_UException,SWIG_POINTER_OWN), "UException", SWIGTYPE_p_UException); SWIG_fail;
}
resultobj = SWIG_From_std_string(static_cast< std::string >(result));
if (SWIG_IsNewObj(res3)) delete arg3;
return resultobj;
fail:
if (SWIG_IsNewObj(res3)) delete arg3;
return NULL;
}
SWIGINTERN PyObject *_wrap_UConnector_apiRequest(PyObject *self, PyObject *args) {
Py_ssize_t argc;
PyObject *argv[5] = {
0
};
Py_ssize_t ii;
if (!PyTuple_Check(args)) SWIG_fail;
argc = args ? PyObject_Length(args) : 0;
for (ii = 0; (ii < 4) && (ii < argc); ii++) {
argv[ii] = PyTuple_GET_ITEM(args,ii);
}
if (argc == 3) {
int _v;
void *vptr = 0;
int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_UConnector, 0);
_v = SWIG_CheckState(res);
if (_v) {
{
int res = SWIG_AsVal_long(argv[1], NULL);
_v = SWIG_CheckState(res);
}
if (_v) {
int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
_v = SWIG_CheckState(res);
if (_v) {
return _wrap_UConnector_apiRequest__SWIG_1(self, args);
}
}
}
}
if (argc == 4) {
int _v;
void *vptr = 0;
int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_UConnector, 0);
_v = SWIG_CheckState(res);
if (_v) {
{
int res = SWIG_AsVal_long(argv[1], NULL);
_v = SWIG_CheckState(res);
}
if (_v) {
int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
_v = SWIG_CheckState(res);
if (_v) {
{
int res = SWIG_AsVal_long(argv[3], NULL);
_v = SWIG_CheckState(res);
}
if (_v) {
return _wrap_UConnector_apiRequest__SWIG_0(self, args);
}
}
}
}
}
fail:
SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'UConnector_apiRequest'.\n"
" Possible C/C++ prototypes are:\n"
" UConnector::apiRequest(long,std::string const &,long)\n"
" UConnector::apiRequest(long,std::string const &)\n");
return 0;
}
SWIGINTERN PyObject *_wrap_UConnector_activate_objects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
UConnector *arg1 = (UConnector *) 0 ;
......@@ -5087,6 +5268,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"UConnector_getName", _wrap_UConnector_getName, METH_VARARGS, NULL},
{ (char *)"UConnector_getTextName", _wrap_UConnector_getTextName, METH_VARARGS, NULL},
{ (char *)"UConnector_getObjectInfo", _wrap_UConnector_getObjectInfo, METH_VARARGS, NULL},
{ (char *)"UConnector_apiRequest", _wrap_UConnector_apiRequest, METH_VARARGS, NULL},
{ (char *)"UConnector_activate_objects", _wrap_UConnector_activate_objects, METH_VARARGS, NULL},
{ (char *)"UConnector_swigregister", UConnector_swigregister, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL }
......
......@@ -188,6 +188,9 @@ class UConnector:
def getObjectInfo(self, *args):
return _pyUConnector.UConnector_getObjectInfo(self, *args)
def apiRequest(self, *args):
return _pyUConnector.UConnector_apiRequest(self, *args)
def activate_objects(self):
return _pyUConnector.UConnector_activate_objects(self)
UConnector_swigregister = _pyUConnector.UConnector_swigregister
......
......@@ -47,7 +47,9 @@ if __name__ == "__main__":
#obj1 = UProxyObject("TestProc")
#obj2 = UProxyObject("TestProc1")
print "Info: %s"%uc1.getObjectInfo( uc1.getObjectID("TestProc1"),"")
# print "Info: %s"%uc1.getObjectInfo("TestProc1","")
print "apiRequest: %s"%uc1.apiRequest(uc1.getObjectID("SharedMemory"),"get?10")
# tc = uc1.getTimeChange(2)
# print "TimeChange: %s sup=%d"%(tc.value,tc.supplier)
......
......@@ -1186,6 +1186,84 @@ std::string UInterface::getObjectInfo( const ObjectId id, const std::string& par
throw uniset::TimeOut(set_err("UI(getInfo): Timeout", id, node));
}
// ------------------------------------------------------------------------------------------------------------
string UInterface::apiRequest(const ObjectId id, const string& query, const ObjectId node) const
{
if( id == uniset::DefaultObjectId )
throw uniset::ORepFailed("UI(apiRequest): Unknown id=uniset::DefaultObjectId");
if( node == uniset::DefaultObjectId )
{
ostringstream err;
err << "UI(apiRequest): id='" << id << "' error: node=uniset::DefaultObjectId";
throw uniset::ORepFailed(err.str());
}
try
{
CORBA::Object_var oref;
try
{
oref = rcache.resolve(id, node);
}
catch( const uniset::NameNotFound& ) {}
for (size_t i = 0; i < uconf->getRepeatCount(); i++)
{
try
{
if( CORBA::is_nil(oref) )
oref = resolve( id, node );
UniSetObject_i_var u = UniSetObject_i::_narrow(oref);
SimpleInfo_var i = u->apiRequest(query.c_str());
return std::string(i->info);
}
catch( const CORBA::TRANSIENT& ) {}
catch( const CORBA::OBJECT_NOT_EXIST& ) {}
catch( const CORBA::SystemException& ex ) {}
msleep(uconf->getRepeatTimeout());
oref = CORBA::Object::_nil();
}
}
catch( const uniset::TimeOut& ) {}
catch( const IOController_i::NameNotFound& ex)
{
rcache.erase(id, node);
uwarn << "UI(apiRequest): " << ex.err << endl;
}
catch( const IOController_i::IOBadParam& ex )
{
rcache.erase(id, node);
throw uniset::IOBadParam("UI(apiRequest): " + string(ex.err));
}
catch( const uniset::ORepFailed& )
{
rcache.erase(id, node);
uwarn << set_err("UI(apiRequest): resolve failed ", id, node) << endl;
}
catch( const CORBA::NO_IMPLEMENT& )
{
rcache.erase(id, node);
uwarn << set_err("UI(apiRequest): method no implement", id, node) << endl;
}
catch( const CORBA::OBJECT_NOT_EXIST& e )
{
rcache.erase(id, node);
uwarn << set_err("UI(apiRequest): object not exist", id, node) << endl;
}
catch( const CORBA::COMM_FAILURE& e )
{
}
catch( const CORBA::SystemException& ex)
{
}
rcache.erase(id, node);
throw uniset::TimeOut(set_err("UI(apiRequest): Timeout", id, node));
}
// ------------------------------------------------------------------------------------------------------------
uniset::ObjectPtr UInterface::CacheOfResolve::resolve( const uniset::ObjectId id, const uniset::ObjectId node ) const
throw(uniset::NameNotFound)
{
......
......@@ -354,6 +354,11 @@ string UniSetObject::getName() const
return myname;
}
// ------------------------------------------------------------------------------------------
const string UniSetObject::getStrType()
{
return CORBA::string_dup(getType());
}
// ------------------------------------------------------------------------------------------
void UniSetObject::termWaiting()
{
if( tmr )
......@@ -394,7 +399,7 @@ Poco::JSON::Object::Ptr UniSetObject::httpGet( const Poco::URI::QueryParameters&
jdata->set("lostMessages", getCountOfLostMessages());
jdata->set("maxSizeOfMessageQueue", getMaxSizeOfMessageQueue());
jdata->set("isActive", isActive());
jdata->set("objectType", getType());
jdata->set("objectType", getStrType());
return jret;
}
// ------------------------------------------------------------------------------------------
......@@ -797,6 +802,93 @@ uniset::SimpleInfo* UniSetObject::getInfo( const char* userparam )
return res; // ._retn();
}
// ------------------------------------------------------------------------------------------
SimpleInfo* UniSetObject::apiRequest( const char* request )
{
#ifdef DISABLE_REST_API
return getInfo(query);
#else
SimpleInfo* ret = new SimpleInfo();
ostringstream err;
try
{
Poco::URI uri(request);
if( ulog()->is_level9() )
ulog()->level9() << myname << "(apiRequest): request: " << request << endl;
ostringstream out;
std::string query = "";
// Пока не будем требовать обязательно использовать формат /api/vesion/query..
// но если указан, то проверяем..
std::vector<std::string> seg;
uri.getPathSegments(seg);
if( seg.size() > 0 && seg[0] == "api" )
{
// проверка: /api/version/query[?params]..
if( seg.size() < 2 || seg[1] != UHttp::UHTTP_API_VERSION )
{
Poco::JSON::Object jdata;
jdata.set("error", Poco::Net::HTTPServerResponse::getReasonForStatus(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST));
jdata.set("ecode", (int)Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
jdata.set("message", "BAD REQUEST STRUCTURE");
jdata.stringify(out);
ret->info = out.str().c_str(); // CORBA::string_dup(..)
return ret;
}
if( seg.size() > 2 )
query = seg[2];
}
else if( seg.size() == 1 )
query = seg[0];
// обработка запроса..
if( query == "help" )
{
// запрос вида: /help?params
auto reply = httpHelp(uri.getQueryParameters());
reply->stringify(out);
}
else if( !query.empty() )
{
// запрос вида: /cmd?params
auto reply = httpRequest(query, uri.getQueryParameters());
reply->stringify(out);
}
else
{
// запрос без команды /?params
auto reply = httpGet(uri.getQueryParameters());
reply->stringify(out);
}
ret->info = out.str().c_str(); // CORBA::string_dup(..)
return ret;
}
catch( Poco::SyntaxException& ex )
{
err << ex.displayText();
}
catch( std::exception& ex )
{
err << ex.what();
}
Poco::JSON::Object jdata;
jdata.set("error", err.str());
jdata.set("ecode", Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
ostringstream out;
jdata.stringify(out);
ret->info = out.str().c_str(); // CORBA::string_dup(..)
return ret;
#endif
}
// ------------------------------------------------------------------------------------------
ostream& operator<<(ostream& os, UniSetObject& obj )
{
SimpleInfo_var si = obj.getInfo();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment