Commit 03ea5933 authored by Pavel Vainerman's avatar Pavel Vainerman

(UHttp): дореализовал получение списка заказчиков в SM,

отрефакторил формат вывода help
parent f00360d2
......@@ -88,8 +88,8 @@ DB: Сделать регулируемый буфер на INSERT-ы БД, чт
ИДЕИ
-----
1) HTTPServer в UniSetActivator, для обращения к объектам
- ведение статистики по типам сообщений в каждом объекте (и в SM). Чтобы увидеть где происходит потеря пакетов (если происходит).
(т.е. идея в том, что сколько "успешно" послала SM столько должно придти и быть обработано (разные счётчики) в объекте)
==================
......
......@@ -609,121 +609,6 @@ void SharedMemory::logging( SensorMessage& sm )
IONotifyController::logging(sm);
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::request_get(const string& req, const Poco::URI::QueryParameters& p)
{
if( p.empty() )
{
ostringstream err;
err << myname << "(request): 'get'. Unknown ID or Name.";
throw UniSetTypes::SystemError(err.str());
}
auto conf = uniset_conf();
auto slist = UniSetTypes::getSInfoList( p[0].first, conf );
if( slist.empty() )
{
ostringstream err;
err << myname << "(request): 'get'. Unknown ID or Name";
throw UniSetTypes::SystemError(err.str());
}
smlog1 << myname << "(GET): " << p[0].first << " size=" << slist.size() << endl;
nlohmann::json jdata;
for( const auto& s: slist )
{
string sid( std::to_string(s.si.id) );
try
{
jdata[sid]["value"] = getValue(s.si.id);
}
catch( IOController_i::NameNotFound& ex )
{
jdata[sid]["value"] = {};
jdata[sid]["error"] = string(ex.err);
}
catch( std::exception& ex )
{
jdata[sid]["value"] = {};
jdata[sid]["error"] = ex.what();
}
}
return jdata;
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::request_sensors( const string& req, const Poco::URI::QueryParameters& params )
{
nlohmann::json jdata;
size_t num = 0;
size_t offset = 0;
size_t limit = 0;
for( const auto& p: params )
{
if( p.first == "offset" )
offset = uni_atoi(p.second);
else if( p.first == "limit" )
limit = uni_atoi(p.second);
}
size_t endnum = offset + limit;
for( auto it=myioBegin(); it!=myioEnd(); ++it,num++ )
{
if( limit > 0 && num >= endnum )
break;
if( offset > 0 && num < offset )
continue;
// std::shared_ptr<USensorInfo>
auto s = it->second;
string sid( to_string(s->si.id));
{
uniset_rwmutex_rlock lock(s->val_lock);
jdata[sid]["value"] = s->value;
jdata[sid]["real_value"] = s->real_value;
}
jdata[sid]["id"] = sid;
jdata[sid]["type"] = UniSetTypes::iotype2str(s->type);
jdata[sid]["default_val"] = s->default_val;
jdata[sid]["tv_sec"] = s->tv_sec;
jdata[sid]["tv_nsec"] = s->tv_nsec;
jdata[sid]["dbignore"] = s->dbignore;
jdata[sid]["calibration"] = {
{ "cmin",s->ci.minCal},
{ "cmax",s->ci.maxCal},
{ "rmin",s->ci.minRaw},
{ "rmax",s->ci.maxRaw},
{ "precision",s->ci.precision}
};
// ::CORBA::Boolean undefined;
// ::CORBA::Boolean blocked;
// ::CORBA::Long priority;
// IOController_i::SensorInfo d_si = { UniSetTypes::DefaultObjectId, UniSetTypes::DefaultObjectId }; /*!< идентификатор датчика, от которого зависит данный */
// long d_value = { 1 }; /*!< разрешающее работу значение датчика от которого зависит данный */
// long d_off_value = { 0 }; /*!< блокирующее значение */
}
jdata["count"] = num;
return jdata;
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::request_consumers(const string& req, const Poco::URI::QueryParameters& p)
{
//! \todo Не реализовано
nlohmann::json j = {};
return j;
}
// -----------------------------------------------------------------------------
void SharedMemory::buildHistoryList( xmlNode* cnode )
{
sminfo << myname << "(buildHistoryList): ..." << endl;
......@@ -845,49 +730,6 @@ SharedMemory::HistorySlot SharedMemory::signal_history()
return m_historySignal;
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::getData( const Poco::URI::QueryParameters& p )
{
nlohmann::json jdata = IONotifyController::getData(p);
// jdata
return jdata;
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::httpHelp( const Poco::URI::QueryParameters& p )
{
nlohmann::json jdata = IONotifyController::httpHelp(p);
jdata[myname]["help"] = {
{"get","get value for sensor [have parameters]"},
{"sensors","get all sensors. [have parameters]"},
{"consumers","get consumers list"}
};
jdata[myname]["help"]["sensors"]["parameters"] = {
{"nameonly","get only name sensors"},
{"offset=N","get from N record"},
{"limit=M","limit of records"}
};
jdata[myname]["help"]["get"]["parameters"] = {
{"id1,name2,id3","get value for id1,name2,id3 sensors"},
};
return jdata;
}
// -----------------------------------------------------------------------------
nlohmann::json SharedMemory::request(const string& req, const Poco::URI::QueryParameters& p)
{
if( req == "get" )
return request_get(req,p);
if( req == "sensors" )
return request_sensors(req,p);
if( req == "consumers" )
return request_consumers(req,p);
return IONotifyController::request(req,p);
}
// -----------------------------------------------------------------------------
void SharedMemory::saveToHistory()
{
if( hist.empty() )
......
......@@ -300,13 +300,19 @@
\section sec_SM_REST_API SharedMemory HTTP API
/help - Получение списка доступных команд
/ - получение стандартной информации
/get?id1,name2,id3,.. - получение значений указанных датчиков
/sensors?offset=N&limit=M - получение полной информации по списку датчиков.
Не обязательные параметры:
offset - начиная с,
limit - количество в ответе.
/help - Получение списка доступных команд
/ - получение стандартной информации
/get?id1,name2,id3,..&shortInfo - получение значений указанных датчиков
Не обязательные параметры:
shortInfo - выдать короткую информацию о датчике (id,value,real_value и когда менялся)
/sensors?offset=N&limit=M - получение полной информации по списку датчиков.
Не обязательные параметры:
offset - начиная с,
limit - количество в ответе.
/consumers - получить список заказчиков по каждому датчику
*/
class SharedMemory:
public IONotifyController
......@@ -408,11 +414,6 @@ class SharedMemory:
return smlog;
}
// http API
virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json httpHelp( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json request( const std::string& req, const Poco::URI::QueryParameters& p ) override;
protected:
typedef std::list<Restorer_XML::ReaderSlot> ReadSlotList;
ReadSlotList lstRSlot;
......@@ -491,10 +492,6 @@ class SharedMemory:
virtual void dumpOrdersList( const UniSetTypes::ObjectId sid, const IONotifyController::ConsumerListInfo& lst ) override {};
virtual void dumpThresholdList( const UniSetTypes::ObjectId sid, const IONotifyController::ThresholdExtList& lst ) override {}
virtual nlohmann::json request_get( const std::string& req, const Poco::URI::QueryParameters& p );
virtual nlohmann::json request_sensors( const std::string& req, const Poco::URI::QueryParameters& p );
virtual nlohmann::json request_consumers( const std::string& req, const Poco::URI::QueryParameters& p );
bool dblogging = { false };
//! \warning Оптимизация использует userdata! Это опасно, если кто-то ещё захочет
......
......@@ -97,6 +97,11 @@ class IOController:
virtual IOController_i::ShortMapSeq* getSensors() override;
// http API
// virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json httpHelp( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json request( const std::string& req, const Poco::URI::QueryParameters& p ) override;
public:
// предварительное объявление..
......@@ -162,7 +167,11 @@ class IOController:
virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, UniSetTypes::ObjectId sup_id );
long localGetValue( std::shared_ptr<USensorInfo>& usi) ;
protected:
// http API
virtual nlohmann::json request_get( const std::string& req, const Poco::URI::QueryParameters& p );
virtual nlohmann::json request_sensors( const std::string& req, const Poco::URI::QueryParameters& p );
void getSensorInfo( nlohmann::json& jdata, std::shared_ptr<USensorInfo>& s , bool shortInfo = false );
// переопределяем для добавления вызова регистрации датчиков
virtual bool deactivateObject() override;
virtual bool activateObject() override;
......@@ -233,8 +242,8 @@ class IOController:
IOStateList::iterator myiofind( UniSetTypes::ObjectId id );
size_t ioCount();
// --------------------------
private:
private:
friend class NCRestorer;
friend class SMInterface;
......
......@@ -270,6 +270,11 @@ class IONotifyController:
/*! словарь: аналоговый датчик --> список порогов по нему */
typedef std::unordered_map<UniSetTypes::ObjectId, ThresholdsListInfo> AskThresholdMap;
// http API
virtual nlohmann::json httpHelp( const Poco::URI::QueryParameters& p ) override;
nlohmann::json request( const string& req, const Poco::URI::QueryParameters& p );
protected:
IONotifyController();
virtual bool activateObject() override;
......@@ -314,6 +319,9 @@ class IONotifyController:
udataThresholdList = 1
};
// http api
virtual nlohmann::json request_consumers( const std::string& req, const Poco::URI::QueryParameters& p );
private:
friend class NCRestorer;
......
......@@ -96,11 +96,11 @@ void UHttpRequestHandler::handleRequest( Poco::Net::HTTPServerRequest& req, Poco
{
nlohmann::json jdata;
jdata["help"] = {
{"help","this help"},
{"list","list of objects"},
{"ObjectName","'ObjectName' information"},
{"ObjectName/help","help for ObjectName"},
{"apidocs","https://github.com/Etersoft/uniset2"}
{"help", {"desc", "this help"}},
{"list", {"desc", "list of objects"}},
{"ObjectName", {"desc", "'ObjectName' information"}},
{"ObjectName/help", {"desc", "help for ObjectName"}},
{"apidocs", {"desc", "https://github.com/Etersoft/uniset2"}}
};
out << jdata.dump();
......
......@@ -23,6 +23,7 @@
#include <cmath>
#include "UInterface.h"
#include "IOController.h"
#include "ORepHelpers.h"
#include "Debug.h"
// ------------------------------------------------------------------------------------------
using namespace UniSetTypes;
......@@ -839,3 +840,167 @@ UniSetTypes::SimpleInfo* IOController::getInfo( ::CORBA::Long userparam )
return i._retn();
}
// -----------------------------------------------------------------------------
nlohmann::json IOController::httpHelp( const Poco::URI::QueryParameters& p )
{
nlohmann::json jdata = UniSetManager::httpHelp(p);
auto& jhelp = jdata[myname]["help"];
jhelp["get"]["desc"] = "get value for sensor";
jhelp["get"]["params"] = {
{"id1,name2,id3","get value for id1,name2,id3 sensors"},
{"shortInfo","get short information for sensors"}
};
jhelp["sensors"]["desc"] = "get all sensors.";
jhelp["sensors"]["params"] = {
{"nameonly","get only name sensors"},
{"offset=N","get from N record"},
{"limit=M","limit of records"}
};
return jdata;
}
// -----------------------------------------------------------------------------
nlohmann::json IOController::request( const string& req, const Poco::URI::QueryParameters& p )
{
if( req == "get" )
return request_get(req,p);
if( req == "sensors" )
return request_sensors(req,p);
return UniSetManager::request(req,p);
}
// -----------------------------------------------------------------------------
nlohmann::json IOController::request_get( const string& req, const Poco::URI::QueryParameters& p )
{
if( p.empty() )
{
ostringstream err;
err << myname << "(request): 'get'. Unknown ID or Name. Use parameters: get?ID1,name2,ID3,...";
throw UniSetTypes::SystemError(err.str());
}
auto conf = uniset_conf();
auto slist = UniSetTypes::getSInfoList( p[0].first, conf );
if( slist.empty() )
{
ostringstream err;
err << myname << "(request): 'get'. Unknown ID or Name. Use parameters: get?ID1,name2,ID3,...";
throw UniSetTypes::SystemError(err.str());
}
bool shortInfo = false;
if( p.size() > 1 && p[1].first=="shortInfo" )
shortInfo = true;
// ulog1 << myname << "(GET): " << p[0].first << " size=" << slist.size() << endl;
nlohmann::json jdata;
auto& jsens = jdata[myname]["sensors"];
for( const auto& s: slist )
{
try
{
auto sinf = ioList.find(s.si.id);
if( sinf == ioList.end() )
{
string sid( std::to_string(s.si.id) );
jsens[sid]["value"] = {};
jsens[sid]["error"] = "Sensor not found";
continue;
}
getSensorInfo(jsens, sinf->second, shortInfo);
}
catch( IOController_i::NameNotFound& ex )
{
string sid( std::to_string(s.si.id) );
jsens[sid]["value"] = {};
jsens[sid]["error"] = string(ex.err);
}
catch( std::exception& ex )
{
string sid( std::to_string(s.si.id) );
jsens[sid]["value"] = {};
jsens[sid]["error"] = ex.what();
}
}
return std::move(jdata);
}
// -----------------------------------------------------------------------------
void IOController::getSensorInfo( nlohmann::json& jdata, std::shared_ptr<USensorInfo>& s, bool shortInfo )
{
string sid( to_string(s->si.id));
auto& jsens = jdata[sid];
{
uniset_rwmutex_rlock lock(s->val_lock);
jsens["value"] = s->value;
jsens["real_value"] = s->real_value;
}
jsens["id"] = sid;
jsens["name"] = ORepHelpers::getShortName(uniset_conf()->oind->getMapName(s->si.id));
jsens["tv_sec"] = s->tv_sec;
jsens["tv_nsec"] = s->tv_nsec;
if( shortInfo )
return;
jsens["type"] = UniSetTypes::iotype2str(s->type);
jsens["default_val"] = s->default_val;
jsens["dbignore"] = s->dbignore;
jsens["calibration"] = {
{ "cmin",s->ci.minCal},
{ "cmax",s->ci.maxCal},
{ "rmin",s->ci.minRaw},
{ "rmax",s->ci.maxRaw},
{ "precision",s->ci.precision}
};
// ::CORBA::Boolean undefined;
// ::CORBA::Boolean blocked;
// ::CORBA::Long priority;
// IOController_i::SensorInfo d_si = { UniSetTypes::DefaultObjectId, UniSetTypes::DefaultObjectId }; /*!< идентификатор датчика, от которого зависит данный */
// long d_value = { 1 }; /*!< разрешающее работу значение датчика от которого зависит данный */
// long d_off_value = { 0 }; /*!< блокирующее значение */
}
// -----------------------------------------------------------------------------
nlohmann::json IOController::request_sensors( const string& req, const Poco::URI::QueryParameters& params )
{
nlohmann::json jdata;
size_t num = 0;
size_t offset = 0;
size_t limit = 0;
for( const auto& p: params )
{
if( p.first == "offset" )
offset = uni_atoi(p.second);
else if( p.first == "limit" )
limit = uni_atoi(p.second);
}
size_t endnum = offset + limit;
for( auto it=myioBegin(); it!=myioEnd(); ++it,num++ )
{
if( limit > 0 && num >= endnum )
break;
if( offset > 0 && num < offset )
continue;
getSensorInfo(jdata, it->second,false);
}
jdata["count"] = num;
return std::move(jdata);
}
// -----------------------------------------------------------------------------
......@@ -1085,3 +1085,60 @@ IDSeq* IONotifyController::askSensorsSeq( const UniSetTypes::IDSeq& lst,
return badlist.getIDSeq();
}
// -----------------------------------------------------------------------------
nlohmann::json IONotifyController::httpHelp(const Poco::URI::QueryParameters& p)
{
nlohmann::json jdata = IOController::httpHelp(p);
jdata[myname]["help"]["consumers"]["desc"] = "get consumers list";
return std::move(jdata);
}
// -----------------------------------------------------------------------------
nlohmann::json IONotifyController::request( const string& req, const Poco::URI::QueryParameters& p )
{
if( req == "consumers" )
return request_consumers(req,p);
return IOController::request(req,p);
}
// -----------------------------------------------------------------------------
nlohmann::json IONotifyController::request_consumers(const string& req, const Poco::URI::QueryParameters& p)
{
//! \todo Не реализовано
nlohmann::json json;
auto& jdata = json[myname]["consumers"];
auto oind = uniset_conf()->oind;
uniset_rwmutex_rlock lock(askIOMutex);
for( auto&& a : askIOList )
{
auto& i = a.second;
uniset_rwmutex_rlock lock(i.mut);
// отображаем только датчики с "не пустым" списком заказчиков
if( i.clst.empty() )
continue;
string sid( std::to_string(a.first) );
auto& jsens = jdata[sid];
jsens["id"] = a.first;
jsens["sensor_name"] = ORepHelpers::getShortName(oind->getMapName(a.first));
auto& jcons = jsens["consumers"];
for( const auto& c : i.clst )
{
string cid( std::to_string(c.id) );
auto& jconsinfo = jcons[cid];
jconsinfo["id"] = c.id;
jconsinfo["name"] = ORepHelpers::getShortName(oind->getMapName(c.id));
jconsinfo["lostEvents"] = c.lostEvents;
jconsinfo["attempt"] = c.attempt;
}
}
return std::move(json);
}
// -----------------------------------------------------------------------------
......@@ -29,8 +29,9 @@ test_logserver.cc \
test_tcpcheck.cc \
test_utcpsocket.cc \
test_iocontroller_types.cc \
test_debugstream.cc \
test_uhttp.cc
test_debugstream.cc
#test_uhttp.cc
tests_with_conf_LDADD = $(top_builddir)/lib/libUniSet2.la
tests_with_conf_CPPFLAGS = -I$(top_builddir)/include
......
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