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 @@ ...@@ -41,9 +41,13 @@
/*! получение информации от объекта /*! получение информации от объекта
\param userparam - Необязательный пользовательский параметр \param userparam - Необязательный пользовательский параметр
\deprecated { Эта функция может быть удалена, желательно использовать более универсальную apiRequest }
*/ */
uniset::SimpleInfo getInfo( in string userparam ); uniset::SimpleInfo getInfo( in string userparam );
/*! REST API. Формат запроса: /api/version/query_for_object[?param1&param2...] */
uniset::SimpleInfo apiRequest( in string query );
boolean exist(); /*!< проверка существования объекта */ boolean exist(); /*!< проверка существования объекта */
/*! Функция посылки сообщения объекту */ /*! Функция посылки сообщения объекту */
......
...@@ -51,6 +51,7 @@ static struct option longopts[] = ...@@ -51,6 +51,7 @@ static struct option longopts[] =
{ "getCalibrate", required_argument, 0, 'y' }, { "getCalibrate", required_argument, 0, 'y' },
{ "getTimeChange", required_argument, 0, 't' }, { "getTimeChange", required_argument, 0, 't' },
{ "oinfo", required_argument, 0, 'p' }, { "oinfo", required_argument, 0, 'p' },
{ "apiRequest", required_argument, 0, 'a' },
{ "verbose", no_argument, 0, 'v' }, { "verbose", no_argument, 0, 'v' },
{ "quiet", no_argument, 0, 'q' }, { "quiet", no_argument, 0, 'q' },
{ "csv", required_argument, 0, 'z' }, { "csv", required_argument, 0, 'z' },
...@@ -62,7 +63,8 @@ string conffile("configure.xml"); ...@@ -62,7 +63,8 @@ string conffile("configure.xml");
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static bool commandToAll( const string& section, std::shared_ptr<ObjectRepository>& rep, Command cmd ); static bool commandToAll( const string& section, std::shared_ptr<ObjectRepository>& rep, Command cmd );
static void createSections(const std::shared_ptr<Configuration>& c ); 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 omap();
int configure( const string& args, UInterface& ui ); int configure( const string& args, UInterface& ui );
...@@ -74,6 +76,7 @@ int getTimeChange( const string& args, UInterface& ui ); ...@@ -74,6 +76,7 @@ int getTimeChange( const string& args, UInterface& ui );
int getState( const string& args, UInterface& ui ); int getState( const string& args, UInterface& ui );
int getCalibrate( const string& args, UInterface& ui ); int getCalibrate( const string& args, UInterface& ui );
int oinfo(const string& args, UInterface& ui , const string& userparam ); 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 = " " ) static void print_help(int width, const string& cmd, const string& help, const string& tab = " " )
{ {
...@@ -111,6 +114,9 @@ static void usage() ...@@ -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, "-p|--oinfo id1@node1,id2@node2,id3,... [userparam]", "Получить информацию об объектах (SimpleInfo). \n userparam - необязательный параметр передаваемый в getInfo() каждому объекту\n");
print_help(36, "", "userparam - необязательный параметр передаваемый в getInfo() каждому объекту\n"); print_help(36, "", "userparam - необязательный параметр передаваемый в getInfo() каждому объекту\n");
cout << endl; 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(48, "-x|--setValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Выставить значения датчиков\n");
print_help(36, "-g|--getValue id1@node1,id2@node2,id3,id4 ", "Получить значения датчиков.\n"); print_help(36, "-g|--getValue id1@node1,id2@node2,id3,id4 ", "Получить значения датчиков.\n");
cout << endl; cout << endl;
...@@ -145,7 +151,7 @@ int main(int argc, char** argv) ...@@ -145,7 +151,7 @@ int main(int argc, char** argv)
while(1) 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 ) if( opt == -1 )
break; break;
...@@ -236,15 +242,35 @@ int main(int argc, char** argv) ...@@ -236,15 +242,35 @@ int main(int argc, char** argv)
UInterface ui(conf); UInterface ui(conf);
ui.initBackId(uniset::AdminID); ui.initBackId(uniset::AdminID);
std::string userparam = {""}; std::string userparam = { "" };
if( optind < argc ) if( checkArg(optind + 1, argc, argv) )
userparam = argv[optind]; userparam = string(argv[optind + 1]);
return oinfo(optarg, ui, userparam); return oinfo(optarg, ui, userparam);
} }
break; 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 case 'e': //--exist
{ {
// cout<<"(main):received option --exist"<<endl; // cout<<"(main):received option --exist"<<endl;
...@@ -441,7 +467,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository ...@@ -441,7 +467,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{ {
if( CORBA::is_nil(obj) ) if( CORBA::is_nil(obj) )
{ {
errDoNotReolve(ob); errDoNotResolve(ob);
break; break;
} }
...@@ -457,7 +483,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository ...@@ -457,7 +483,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{ {
if(CORBA::is_nil(obj)) if(CORBA::is_nil(obj))
{ {
errDoNotReolve(ob); errDoNotResolve(ob);
break; break;
} }
...@@ -473,7 +499,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository ...@@ -473,7 +499,7 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
{ {
if(CORBA::is_nil(obj)) if(CORBA::is_nil(obj))
{ {
errDoNotReolve(ob); errDoNotResolve(ob);
break; break;
} }
...@@ -1038,11 +1064,53 @@ int oinfo(const string& args, UInterface& ui, const string& userparam ) ...@@ -1038,11 +1064,53 @@ int oinfo(const string& args, UInterface& ui, const string& userparam )
return 0; 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 ) if( verb )
cerr << oname << ": resolve failed.." << endl; 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 ...@@ -17,6 +17,7 @@ ln -s -f admin.sh getChangedTime
ln -s -f admin.sh getCalibrate ln -s -f admin.sh getCalibrate
ln -s -f admin.sh help ln -s -f admin.sh help
ln -s -f admin.sh oinfo 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-start.sh
ln -s -f ../../Utilities/scripts/uniset2-stop.sh stop.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" ...@@ -5,7 +5,7 @@ export LD_LIBRARY_PATH="../../lib/.libs;../lib/.libs"
ulimit -Sc 10000000000 ulimit -Sc 10000000000
./uniset2-start.sh -f ./uniset2-smemory --smemory-id SharedMemory \ ./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 \ --sm-log-add-levels any $* --sm-run-logserver --activator-run-httpserver \
#--pulsar-id DO_C --pulsar-iotype DO --pulsar-msec 100 #--pulsar-id DO_C --pulsar-iotype DO --pulsar-msec 100
......
...@@ -143,6 +143,7 @@ class UInterface ...@@ -143,6 +143,7 @@ class UInterface
//! Информация об объекте //! Информация об объекте
std::string getObjectInfo( const uniset::ObjectId id, const std::string& params, const uniset::ObjectId node ) const; 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, IOController_i::ShortMapSeq* getSensors( const uniset::ObjectId id,
......
...@@ -99,8 +99,13 @@ class UniSetObject: ...@@ -99,8 +99,13 @@ class UniSetObject:
return uniset::ObjectType("UniSetObject"); return uniset::ObjectType("UniSetObject");
} }
const std::string getStrType();
virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override; 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; virtual void push( const uniset::TransportMessage& msg ) override;
......
...@@ -17,8 +17,9 @@ ...@@ -17,8 +17,9 @@
import json import json
import urllib2 import urllib2
import urllib
UHTTP_API_VERSION = 'v01' UHTTP_API_VERSION = 'v0'
class UHTTPError: class UHTTPError:
...@@ -38,7 +39,13 @@ class UniSetHTTPService: ...@@ -38,7 +39,13 @@ class UniSetHTTPService:
self.aviver = self.settings['api'] self.aviver = self.settings['api']
def request(self, query, method='GET', data=None): 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 url = self.settings.get('url') + "/api/" + self.apiver + query
headers = {} headers = {}
...@@ -52,17 +59,16 @@ class UniSetHTTPService: ...@@ -52,17 +59,16 @@ class UniSetHTTPService:
return json.loads(resp.read()) return json.loads(resp.read())
except urllib2.URLError, e: except urllib2.URLError, e:
if hasattr(e, 'reason'): 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) raise UHTTPError(err)
elif hasattr(e, 'code'): 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(err)
raise UHTTPError('Unknown error') raise UHTTPError('Unknown error')
class SharedMemoryAPI(UniSetHTTPService): class SharedMemoryAPI(UniSetHTTPService):
"""Работа с SharedMemory."""
def __init__(self, _settings): def __init__(self, _settings):
UniSetHTTPService.__init__(self, _settings) UniSetHTTPService.__init__(self, _settings)
...@@ -73,7 +79,11 @@ class SharedMemoryAPI(UniSetHTTPService): ...@@ -73,7 +79,11 @@ class SharedMemoryAPI(UniSetHTTPService):
return UniSetHTTPService.request(self, '/' + self.settings['smID'] + '/' + query) return UniSetHTTPService.request(self, '/' + self.settings['smID'] + '/' + query)
def consumers(self, sens=''): def consumers(self, sens=''):
"""Получить список заказчиков""" '''
Получить список заказчиков
:param sens: для указанных датчиков
:return: список..
'''
query = '/consumers' query = '/consumers'
if sens != '': if sens != '':
query += '?%s' % sens query += '?%s' % sens
...@@ -81,14 +91,19 @@ class SharedMemoryAPI(UniSetHTTPService): ...@@ -81,14 +91,19 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query)[self.settings['smID']]['consumers'] return self.request(query)[self.settings['smID']]['consumers']
def get(self, sensors='', shortInfo=True): def get(self, sensors='', shortInfo=True):
"""Получить список заказчиков""" '''
Получить список заказчиков
:param sensors: для указанных датчиков (по умолчанию для всех)
:param shortInfo: выдать только основную информацию по каждому датчику
:return: список..
'''
query = '/get' query = '/get'
params = None params = None
if sensors != '': if sensors != '':
params = '?%s' % sensors params = '?%s' % sensors
if shortInfo: if shortInfo:
if params != None: if params is not None:
params += '&shortInfo' params += '&shortInfo'
else: else:
params = '?shortInfo' params = '?shortInfo'
...@@ -99,17 +114,22 @@ class SharedMemoryAPI(UniSetHTTPService): ...@@ -99,17 +114,22 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query)[self.settings['smID']]['sensors'] return self.request(query)[self.settings['smID']]['sensors']
def sensors(self, offset=None, limit=None): def sensors(self, offset=None, limit=None):
"""Получить список датчиков""" '''
Получить список датчиков
:param offset: начальное смещение в списке датчиков
:param limit: сколько датиков выдать в ответе
:return: список..
'''
query = '/sensors' query = '/sensors'
params = None params = None
if offset: if offset:
params = '?offset=%d' % offset params = '?offset=%d' % offset
if limit: if limit:
if params != None: if params is not None:
params += '&limit=%d'%limit params += '&limit=%d' % limit
else: else:
params = '?limit=%d'%limit params = '?limit=%d' % limit
if params: if params:
query += params query += params
...@@ -117,9 +137,10 @@ class SharedMemoryAPI(UniSetHTTPService): ...@@ -117,9 +137,10 @@ class SharedMemoryAPI(UniSetHTTPService):
return self.request(query) return self.request(query)
def lost(self): def lost(self):
'''
"""Получить список 'пропавших' заказчиков""" Получить список 'пропавших' заказчиков
:return: список
'''
return self.request('/lost')[self.settings['smID']] return self.request('/lost')[self.settings['smID']]
def help(self): def help(self):
......
...@@ -206,6 +206,27 @@ throw(UException) ...@@ -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) void UConnector::activate_objects() throw(UException)
{ {
try try
...@@ -219,10 +240,20 @@ void UConnector::activate_objects() throw(UException) ...@@ -219,10 +240,20 @@ void UConnector::activate_objects() throw(UException)
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
long UConnector::getObjectID(const string& name ) long UConnector::getObjectID( const string& name )
{ {
if( conf ) 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; return UTypes::DefaultID;
} }
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
class UConnector class UConnector
{ {
public: public:
UConnector( int argc, char** argv, 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( UTypes::Params* p, const std::string& xmlfile ) throw(UException);
~UConnector(); ~UConnector();
inline std::string getUIType() inline std::string getUIType()
...@@ -39,7 +39,7 @@ class UConnector ...@@ -39,7 +39,7 @@ class UConnector
std::string getConfFileName(); std::string getConfFileName();
long getValue( long id, long node )throw(UException); 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 ); UTypes::ShortIOInfo getTimeChange( long id, long node = UTypes::DefaultID );
long getSensorID( const std::string& name ); long getSensorID( const std::string& name );
...@@ -50,7 +50,8 @@ class UConnector ...@@ -50,7 +50,8 @@ class UConnector
std::string getName( long id ); std::string getName( long id );
std::string getTextName( 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); void activate_objects() throw(UException);
......
...@@ -5016,6 +5016,187 @@ fail: ...@@ -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) { SWIGINTERN PyObject *_wrap_UConnector_activate_objects(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0; PyObject *resultobj = 0;
UConnector *arg1 = (UConnector *) 0 ; UConnector *arg1 = (UConnector *) 0 ;
...@@ -5087,6 +5268,7 @@ static PyMethodDef SwigMethods[] = { ...@@ -5087,6 +5268,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"UConnector_getName", _wrap_UConnector_getName, METH_VARARGS, NULL}, { (char *)"UConnector_getName", _wrap_UConnector_getName, METH_VARARGS, NULL},
{ (char *)"UConnector_getTextName", _wrap_UConnector_getTextName, METH_VARARGS, NULL}, { (char *)"UConnector_getTextName", _wrap_UConnector_getTextName, METH_VARARGS, NULL},
{ (char *)"UConnector_getObjectInfo", _wrap_UConnector_getObjectInfo, 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_activate_objects", _wrap_UConnector_activate_objects, METH_VARARGS, NULL},
{ (char *)"UConnector_swigregister", UConnector_swigregister, METH_VARARGS, NULL}, { (char *)"UConnector_swigregister", UConnector_swigregister, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL } { NULL, NULL, 0, NULL }
......
...@@ -188,6 +188,9 @@ class UConnector: ...@@ -188,6 +188,9 @@ class UConnector:
def getObjectInfo(self, *args): def getObjectInfo(self, *args):
return _pyUConnector.UConnector_getObjectInfo(self, *args) return _pyUConnector.UConnector_getObjectInfo(self, *args)
def apiRequest(self, *args):
return _pyUConnector.UConnector_apiRequest(self, *args)
def activate_objects(self): def activate_objects(self):
return _pyUConnector.UConnector_activate_objects(self) return _pyUConnector.UConnector_activate_objects(self)
UConnector_swigregister = _pyUConnector.UConnector_swigregister UConnector_swigregister = _pyUConnector.UConnector_swigregister
......
...@@ -47,7 +47,9 @@ if __name__ == "__main__": ...@@ -47,7 +47,9 @@ if __name__ == "__main__":
#obj1 = UProxyObject("TestProc") #obj1 = UProxyObject("TestProc")
#obj2 = UProxyObject("TestProc1") #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) # tc = uc1.getTimeChange(2)
# print "TimeChange: %s sup=%d"%(tc.value,tc.supplier) # print "TimeChange: %s sup=%d"%(tc.value,tc.supplier)
......
...@@ -1186,6 +1186,84 @@ std::string UInterface::getObjectInfo( const ObjectId id, const std::string& par ...@@ -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)); 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 uniset::ObjectPtr UInterface::CacheOfResolve::resolve( const uniset::ObjectId id, const uniset::ObjectId node ) const
throw(uniset::NameNotFound) throw(uniset::NameNotFound)
{ {
......
...@@ -354,6 +354,11 @@ string UniSetObject::getName() const ...@@ -354,6 +354,11 @@ string UniSetObject::getName() const
return myname; return myname;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
const string UniSetObject::getStrType()
{
return CORBA::string_dup(getType());
}
// ------------------------------------------------------------------------------------------
void UniSetObject::termWaiting() void UniSetObject::termWaiting()
{ {
if( tmr ) if( tmr )
...@@ -394,7 +399,7 @@ Poco::JSON::Object::Ptr UniSetObject::httpGet( const Poco::URI::QueryParameters& ...@@ -394,7 +399,7 @@ Poco::JSON::Object::Ptr UniSetObject::httpGet( const Poco::URI::QueryParameters&
jdata->set("lostMessages", getCountOfLostMessages()); jdata->set("lostMessages", getCountOfLostMessages());
jdata->set("maxSizeOfMessageQueue", getMaxSizeOfMessageQueue()); jdata->set("maxSizeOfMessageQueue", getMaxSizeOfMessageQueue());
jdata->set("isActive", isActive()); jdata->set("isActive", isActive());
jdata->set("objectType", getType()); jdata->set("objectType", getStrType());
return jret; return jret;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
...@@ -797,6 +802,93 @@ uniset::SimpleInfo* UniSetObject::getInfo( const char* userparam ) ...@@ -797,6 +802,93 @@ uniset::SimpleInfo* UniSetObject::getInfo( const char* userparam )
return res; // ._retn(); 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 ) ostream& operator<<(ostream& os, UniSetObject& obj )
{ {
SimpleInfo_var si = obj.getInfo(); 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