Commit 69a42967 authored by Pavel Vainerman's avatar Pavel Vainerman

[http-resolver]: added to UInterface

parent 3d2b8079
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
<DocDir name="./"/> <DocDir name="./"/>
<LockDir name="/tmp/"/> <LockDir name="/tmp/"/>
<HttpResolver name="HttpResolver"/> <HttpResolver name="HttpResolver"/>
<LocalIOR name="1"/>
<Services> <Services>
<LocalTimeService AskLifeTimeSEC="10" MaxCountTimers="100" name="TimeService"/> <LocalTimeService AskLifeTimeSEC="10" MaxCountTimers="100" name="TimeService"/>
<LocalInfoServer dbrepeat="1" name="InfoServer"> <LocalInfoServer dbrepeat="1" name="InfoServer">
......
...@@ -36,267 +36,265 @@ using namespace uniset; ...@@ -36,267 +36,265 @@ using namespace uniset;
using namespace std; using namespace std;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
HttpResolver::HttpResolver( const string& name, int argc, const char* const* argv, const string& prefix ): HttpResolver::HttpResolver( const string& name, int argc, const char* const* argv, const string& prefix ):
myname(name) myname(name)
{ {
rlog = make_shared<DebugStream>(); rlog = make_shared<DebugStream>();
auto logLevels = uniset::getArgParam("--" + prefix + "log-add-levels", argc, argv, ""); auto logLevels = uniset::getArgParam("--" + prefix + "log-add-levels", argc, argv, "");
if( !logLevels.empty() ) if( !logLevels.empty() )
rlog->addLevel( Debug::value(logLevels) ); rlog->addLevel( Debug::value(logLevels) );
std::string config = uniset::getArgParam("--confile", argc, argv, "configure.xml"); std::string config = uniset::getArgParam("--confile", argc, argv, "configure.xml");
if( config.empty() ) if( config.empty() )
throw SystemError("Unknown config file"); throw SystemError("Unknown config file");
std::shared_ptr<UniXML> xml; std::shared_ptr<UniXML> xml;
cout << myname << "(init): init from " << config << endl; cout << myname << "(init): init from " << config << endl;
xml = make_shared<UniXML>(); xml = make_shared<UniXML>();
try try
{ {
xml->open(config); xml->open(config);
} }
catch( std::exception& ex ) catch( std::exception& ex )
{ {
throw ex; throw ex;
} }
xmlNode* cnode = xml->findNode(xml->getFirstNode(), "HttpResolver", name); xmlNode* cnode = xml->findNode(xml->getFirstNode(), "HttpResolver", name);
if( !cnode ) if( !cnode )
{ {
ostringstream err; ostringstream err;
err << name << "(init): Not found confnode <HttpResolver name='" << name << "'...>"; err << name << "(init): Not found confnode <HttpResolver name='" << name << "'...>";
rcrit << err.str() << endl; rcrit << err.str() << endl;
throw uniset::SystemError(err.str()); throw uniset::SystemError(err.str());
} }
UniXML::iterator it(cnode); UniXML::iterator it(cnode);
UniXML::iterator dirIt = xml->findNode(xml->getFirstNode(), "LockDir"); UniXML::iterator dirIt = xml->findNode(xml->getFirstNode(), "LockDir");
if( !dirIt ) if( !dirIt )
{ {
ostringstream err; ostringstream err;
err << name << "(init): Not found confnode <LockDir name='..'/>"; err << name << "(init): Not found confnode <LockDir name='..'/>";
rcrit << err.str() << endl; rcrit << err.str() << endl;
throw uniset::SystemError(err.str()); throw uniset::SystemError(err.str());
} }
iorfile = make_shared<IORFile>(dirIt.getProp("name")); iorfile = make_shared<IORFile>(dirIt.getProp("name"));
rinfo << myname << "(init): iot directory: " << dirIt.getProp("name") << endl; rinfo << myname << "(init): iot directory: " << dirIt.getProp("name") << endl;
httpHost = uniset::getArgParam("--" + prefix + "httpserver-host", argc, argv, "localhost"); httpHost = uniset::getArgParam("--" + prefix + "httpserver-host", argc, argv, "localhost");
httpPort = uniset::getArgInt("--" + prefix + "httpserver-port", argc, argv, "8008"); httpPort = uniset::getArgInt("--" + prefix + "httpserver-port", argc, argv, "8008");
httpCORS_allow = uniset::getArgParam("--" + prefix + "httpserver-cors-allow", argc, argv, httpCORS_allow); httpCORS_allow = uniset::getArgParam("--" + prefix + "httpserver-cors-allow", argc, argv, httpCORS_allow);
httpReplyAddr = uniset::getArgParam("--" + prefix + "httpserver-reply-addr", argc, argv, "");
rinfo << myname << "(init): http server parameters " << httpHost << ":" << httpPort << endl;
rinfo << myname << "(init): http server parameters " << httpHost << ":" << httpPort << endl; Poco::Net::SocketAddress sa(httpHost, httpPort);
Poco::Net::SocketAddress sa(httpHost, httpPort);
try
try {
{ Poco::Net::HTTPServerParams* httpParams = new Poco::Net::HTTPServerParams;
Poco::Net::HTTPServerParams* httpParams = new Poco::Net::HTTPServerParams;
int maxQ = uniset::getArgPInt("--" + prefix + "httpserver-max-queued", argc, argv, it.getProp("httpMaxQueued"), 100);
int maxQ = uniset::getArgPInt("--" + prefix + "httpserver-max-queued", argc, argv, it.getProp("httpMaxQueued"), 100); int maxT = uniset::getArgPInt("--" + prefix + "httpserver-max-threads", argc, argv, it.getProp("httpMaxThreads"), 3);
int maxT = uniset::getArgPInt("--" + prefix + "httpserver-max-threads", argc, argv, it.getProp("httpMaxThreads"), 3);
httpParams->setMaxQueued(maxQ);
httpParams->setMaxQueued(maxQ); httpParams->setMaxThreads(maxT);
httpParams->setMaxThreads(maxT); httpserv = std::make_shared<Poco::Net::HTTPServer>(new HttpResolverRequestHandlerFactory(this), Poco::Net::ServerSocket(sa), httpParams );
httpserv = std::make_shared<Poco::Net::HTTPServer>(new HttpResolverRequestHandlerFactory(this), Poco::Net::ServerSocket(sa), httpParams ); }
} catch( std::exception& ex )
catch( std::exception& ex ) {
{ std::stringstream err;
std::stringstream err; err << myname << "(init): " << httpHost << ":" << httpPort << " ERROR: " << ex.what();
err << myname << "(init): " << httpHost << ":" << httpPort << " ERROR: " << ex.what(); throw uniset::SystemError(err.str());
throw uniset::SystemError(err.str()); }
}
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
HttpResolver::~HttpResolver() HttpResolver::~HttpResolver()
{ {
if( httpserv ) if( httpserv )
httpserv->stop(); httpserv->stop();
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
std::shared_ptr<HttpResolver> HttpResolver::init_resolver( int argc, const char* const* argv, const std::string& prefix ) std::shared_ptr<HttpResolver> HttpResolver::init_resolver( int argc, const char* const* argv, const std::string& prefix )
{ {
string name = uniset::getArgParam("--" + prefix + "name", argc, argv, "HttpResolver"); string name = uniset::getArgParam("--" + prefix + "name", argc, argv, "HttpResolver");
if( name.empty() ) if( name.empty() )
{ {
cerr << "(HttpResolver): Unknown name. Use --" << prefix << "name" << endl; cerr << "(HttpResolver): Unknown name. Use --" << prefix << "name" << endl;
return nullptr; return nullptr;
} }
return make_shared<HttpResolver>(name, argc, argv, prefix); return make_shared<HttpResolver>(name, argc, argv, prefix);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HttpResolver::help_print() void HttpResolver::help_print()
{ {
cout << "Default: prefix='logdb'" << endl; cout << "Default: prefix='logdb'" << endl;
cout << "--prefix-single-confile conf.xml - Отдельный конфигурационный файл (не требующий структуры uniset)" << endl; cout << "--prefix-single-confile conf.xml - Отдельный конфигурационный файл (не требующий структуры uniset)" << endl;
cout << "--prefix-name name - Имя. Для поиска настроечной секции в configure.xml" << endl; cout << "--prefix-name name - Имя. Для поиска настроечной секции в configure.xml" << endl;
cout << "http: " << endl; cout << "http: " << endl;
cout << "--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost" << endl; cout << "--prefix-httpserver-host ip - IP на котором слушает http сервер. По умолчанию: localhost" << endl;
cout << "--prefix-httpserver-port num - Порт на котором принимать запросы. По умолчанию: 8080" << endl; cout << "--prefix-httpserver-port num - Порт на котором принимать запросы. По умолчанию: 8080" << endl;
cout << "--prefix-httpserver-max-queued num - Размер очереди запросов к http серверу. По умолчанию: 100" << endl; cout << "--prefix-httpserver-max-queued num - Размер очереди запросов к http серверу. По умолчанию: 100" << endl;
cout << "--prefix-httpserver-max-threads num - Разрешённое количество потоков для http-сервера. По умолчанию: 3" << endl; cout << "--prefix-httpserver-max-threads num - Разрешённое количество потоков для http-сервера. По умолчанию: 3" << endl;
cout << "--prefix-httpserver-cors-allow addr - (CORS): Access-Control-Allow-Origin. Default: *" << endl; cout << "--prefix-httpserver-cors-allow addr - (CORS): Access-Control-Allow-Origin. Default: *" << endl;
cout << "--prefix-httpserver-reply-addr host[:port] - Адрес отдаваемый клиенту для подключения. По умолчанию адрес узла где запущен logdb" << endl;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HttpResolver::run() void HttpResolver::run()
{ {
if( httpserv ) if( httpserv )
httpserv->start(); httpserv->start();
pause(); pause();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class HttpResolverRequestHandler: class HttpResolverRequestHandler:
public Poco::Net::HTTPRequestHandler public Poco::Net::HTTPRequestHandler
{ {
public: public:
HttpResolverRequestHandler( HttpResolver* r ): resolver(r) {} HttpResolverRequestHandler( HttpResolver* r ): resolver(r) {}
virtual void handleRequest( Poco::Net::HTTPServerRequest& request, virtual void handleRequest( Poco::Net::HTTPServerRequest& request,
Poco::Net::HTTPServerResponse& response ) override Poco::Net::HTTPServerResponse& response ) override
{ {
resolver->handleRequest(request, response); resolver->handleRequest(request, response);
} }
private: private:
HttpResolver* resolver; HttpResolver* resolver;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Poco::Net::HTTPRequestHandler* HttpResolver::HttpResolverRequestHandlerFactory::createRequestHandler( const Poco::Net::HTTPServerRequest& req ) Poco::Net::HTTPRequestHandler* HttpResolver::HttpResolverRequestHandlerFactory::createRequestHandler( const Poco::Net::HTTPServerRequest& req )
{ {
return new HttpResolverRequestHandler(resolver); return new HttpResolverRequestHandler(resolver);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void HttpResolver::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) void HttpResolver::handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp )
{ {
using Poco::Net::HTTPResponse; using Poco::Net::HTTPResponse;
std::ostream& out = resp.send(); std::ostream& out = resp.send();
resp.setContentType("text/json"); resp.setContentType("text/json");
resp.set("Access-Control-Allow-Methods", "GET"); resp.set("Access-Control-Allow-Methods", "GET");
resp.set("Access-Control-Allow-Request-Method", "*"); resp.set("Access-Control-Allow-Request-Method", "*");
resp.set("Access-Control-Allow-Origin", httpCORS_allow /* req.get("Origin") */); resp.set("Access-Control-Allow-Origin", httpCORS_allow /* req.get("Origin") */);
try try
{ {
// В этой версии API поддерживается только GET // В этой версии API поддерживается только GET
if( req.getMethod() != "GET" ) if( req.getMethod() != "GET" )
{ {
auto jdata = respError(resp, HTTPResponse::HTTP_BAD_REQUEST, "method must be 'GET'"); auto jdata = respError(resp, HTTPResponse::HTTP_BAD_REQUEST, "method must be 'GET'");
jdata->stringify(out); jdata->stringify(out);
out.flush(); out.flush();
return; return;
} }
Poco::URI uri(req.getURI()); Poco::URI uri(req.getURI());
rlog3 << req.getHost() << ": query: " << uri.getQuery() << endl; rlog3 << req.getHost() << ": query: " << uri.getQuery() << endl;
std::vector<std::string> seg; std::vector<std::string> seg;
uri.getPathSegments(seg); uri.getPathSegments(seg);
// example: http://host:port/api/version/resolve/[json|text] // example: http://host:port/api/version/resolve/[json|text]
if( seg.size() < 4 if( seg.size() < 4
|| seg[0] != "api" || seg[0] != "api"
|| seg[1] != HTTP_RESOLVER_API_VERSION || seg[1] != HTTP_RESOLVER_API_VERSION
|| seg[2].empty() || seg[2].empty()
|| seg[2] != "resolve") || seg[2] != "resolve")
{ {
ostringstream err; ostringstream err;
err << "Bad request structure. Must be /api/" << HTTP_RESOLVER_API_VERSION << "/resolve/[json|text|help]?name"; err << "Bad request structure. Must be /api/" << HTTP_RESOLVER_API_VERSION << "/resolve/[json|text|help]?name";
auto jdata = respError(resp, HTTPResponse::HTTP_BAD_REQUEST, err.str()); auto jdata = respError(resp, HTTPResponse::HTTP_BAD_REQUEST, err.str());
jdata->stringify(out); jdata->stringify(out);
out.flush(); out.flush();
return; return;
} }
auto qp = uri.getQueryParameters(); auto qp = uri.getQueryParameters();
resp.setStatus(HTTPResponse::HTTP_OK); resp.setStatus(HTTPResponse::HTTP_OK);
string cmd = seg[3]; string cmd = seg[3];
if( cmd == "help" ) if( cmd == "help" )
{ {
using uniset::json::help::item; using uniset::json::help::item;
uniset::json::help::object myhelp("help"); uniset::json::help::object myhelp("help");
myhelp.emplace(item("help", "this help")); myhelp.emplace(item("help", "this help"));
myhelp.emplace(item("resolve?name", "resolve name")); myhelp.emplace(item("resolve?name", "resolve name"));
// myhelp.emplace(item("apidocs", "https://github.com/Etersoft/uniset2")); // myhelp.emplace(item("apidocs", "https://github.com/Etersoft/uniset2"));
item l("resolve?name", "resolve name"); item l("resolve?name", "resolve name");
l.param("format=json|text", "response format"); l.param("format=json|text", "response format");
myhelp.add(l); myhelp.add(l);
myhelp.get()->stringify(out); myhelp.get()->stringify(out);
} }
else if( cmd == "json" ) else if( cmd == "json" )
{ {
auto json = httpJsonResolve(uri.getQuery(), qp); auto json = httpJsonResolve(uri.getQuery(), qp);
json->stringify(out); json->stringify(out);
} }
else if( cmd == "text" ) else if( cmd == "text" )
{ {
resp.setContentType("text/plain"); resp.setContentType("text/plain");
auto txt = httpTextResolve(uri.getQuery(), qp); auto txt = httpTextResolve(uri.getQuery(), qp);
out << txt; out << txt;
} }
} }
catch( std::exception& ex ) catch( std::exception& ex )
{ {
auto jdata = respError(resp, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR, ex.what()); auto jdata = respError(resp, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR, ex.what());
jdata->stringify(out); jdata->stringify(out);
} }
out.flush(); out.flush();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Poco::JSON::Object::Ptr HttpResolver::respError( Poco::Net::HTTPServerResponse& resp, Poco::JSON::Object::Ptr HttpResolver::respError( Poco::Net::HTTPServerResponse& resp,
Poco::Net::HTTPResponse::HTTPStatus estatus, Poco::Net::HTTPResponse::HTTPStatus estatus,
const string& message ) const string& message )
{ {
resp.setStatus(estatus); resp.setStatus(estatus);
resp.setContentType("text/json"); resp.setContentType("text/json");
Poco::JSON::Object::Ptr jdata = new Poco::JSON::Object(); Poco::JSON::Object::Ptr jdata = new Poco::JSON::Object();
jdata->set("error", resp.getReasonForStatus(resp.getStatus())); jdata->set("error", resp.getReasonForStatus(resp.getStatus()));
jdata->set("ecode", (int)resp.getStatus()); jdata->set("ecode", (int)resp.getStatus());
jdata->set("message", message); jdata->set("message", message);
return jdata; return jdata;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Poco::JSON::Object::Ptr HttpResolver::httpJsonResolve( const std::string& query, const Poco::URI::QueryParameters& p ) Poco::JSON::Object::Ptr HttpResolver::httpJsonResolve( const std::string& query, const Poco::URI::QueryParameters& p )
{ {
auto iorstr = httpTextResolve(query, p); auto iorstr = httpTextResolve(query, p);
Poco::JSON::Object::Ptr jdata = new Poco::JSON::Object(); Poco::JSON::Object::Ptr jdata = new Poco::JSON::Object();
jdata->set("ior", iorstr); jdata->set("ior", iorstr);
return jdata; return jdata;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
std::string HttpResolver::httpTextResolve( const std::string& query, const Poco::URI::QueryParameters& p ) std::string HttpResolver::httpTextResolve( const std::string& query, const Poco::URI::QueryParameters& p )
{ {
if( query.empty() ) if( query.empty() )
{ {
uwarn << myname << "undefined parameters for resolve" << endl; uwarn << myname << "undefined parameters for resolve" << endl;
return ""; return "";
} }
if( uniset::is_digit(query) ) if( uniset::is_digit(query) )
{ {
uinfo << myname << " resolve " << query << endl; uinfo << myname << " resolve " << query << endl;
return iorfile->getIOR( uniset::uni_atoi(query) ); return iorfile->getIOR( uniset::uni_atoi(query) );
} }
uwarn << myname << "unknown parameter type '" << query << "'" << endl; uwarn << myname << "unknown parameter type '" << query << "'" << endl;
return ""; return "";
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -32,74 +32,74 @@ const std::string HTTP_RESOLVER_API_VERSION = "v01"; ...@@ -32,74 +32,74 @@ const std::string HTTP_RESOLVER_API_VERSION = "v01";
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
namespace uniset namespace uniset
{ {
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
/*! /*!
\page page_HttpResolver Http-cервис для получения CORBA-ссылок на объекты (HttpResolver) \page page_HttpResolver Http-cервис для получения CORBA-ссылок на объекты (HttpResolver)
- \ref sec_HttpResolver_Comm - \ref sec_HttpResolver_Comm
\section sec_HttpResolver_Comm Общее описание работы HttpResolver \section sec_HttpResolver_Comm Общее описание работы HttpResolver
HttpResolver это сервис, который отдаёт CORBA-ссылки (в виде строки) HttpResolver это сервис, который отдаёт CORBA-ссылки (в виде строки)
на объекты запущенные на данном узле в режиме LocalIOR. Т.е. когда ссылки на объекты запущенные на данном узле в режиме LocalIOR. Т.е. когда ссылки
публикуются в файлах. публикуются в файлах.
*/ */
class HttpResolver: class HttpResolver:
public Poco::Net::HTTPRequestHandler public Poco::Net::HTTPRequestHandler
{ {
public: public:
HttpResolver( const std::string& name, int argc, const char* const* argv, const std::string& prefix ); HttpResolver( const std::string& name, int argc, const char* const* argv, const std::string& prefix );
virtual ~HttpResolver(); virtual ~HttpResolver();
/*! глобальная функция для инициализации объекта */ /*! глобальная функция для инициализации объекта */
static std::shared_ptr<HttpResolver> init_resolver( int argc, const char* const* argv, const std::string& prefix = "httpresolver-" ); static std::shared_ptr<HttpResolver> init_resolver( int argc, const char* const* argv, const std::string& prefix = "httpresolver-" );
/*! глобальная функция для вывода help-а */ /*! глобальная функция для вывода help-а */
static void help_print(); static void help_print();
inline std::shared_ptr<DebugStream> log() inline std::shared_ptr<DebugStream> log()
{ {
return rlog; return rlog;
} }
virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override; virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
void run(); void run();
protected: protected:
Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message ); Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message );
Poco::JSON::Object::Ptr httpGetRequest( const std::string& cmd, const Poco::URI::QueryParameters& p ); Poco::JSON::Object::Ptr httpGetRequest( const std::string& cmd, const Poco::URI::QueryParameters& p );
Poco::JSON::Object::Ptr httpJsonResolve( const std::string& query, const Poco::URI::QueryParameters& p ); Poco::JSON::Object::Ptr httpJsonResolve( const std::string& query, const Poco::URI::QueryParameters& p );
std::string httpTextResolve( const std::string& query, const Poco::URI::QueryParameters& p ); std::string httpTextResolve( const std::string& query, const Poco::URI::QueryParameters& p );
std::shared_ptr<Poco::Net::HTTPServer> httpserv; std::shared_ptr<Poco::Net::HTTPServer> httpserv;
std::string httpHost = { "" }; std::string httpHost = { "" };
int httpPort = { 0 }; int httpPort = { 0 };
std::string httpCORS_allow = { "*" }; std::string httpCORS_allow = { "*" };
std::string httpReplyAddr = { "" }; std::string httpReplyAddr = { "" };
std::shared_ptr<DebugStream> rlog; std::shared_ptr<DebugStream> rlog;
std::string myname; std::string myname;
std::shared_ptr<IORFile> iorfile; std::shared_ptr<IORFile> iorfile;
class HttpResolverRequestHandlerFactory: class HttpResolverRequestHandlerFactory:
public Poco::Net::HTTPRequestHandlerFactory public Poco::Net::HTTPRequestHandlerFactory
{ {
public: public:
HttpResolverRequestHandlerFactory( HttpResolver* r ): resolver(r) {} HttpResolverRequestHandlerFactory( HttpResolver* r ): resolver(r) {}
virtual ~HttpResolverRequestHandlerFactory() {} virtual ~HttpResolverRequestHandlerFactory() {}
virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override; virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override;
private: private:
HttpResolver* resolver; HttpResolver* resolver;
}; };
private: private:
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // end of namespace uniset } // end of namespace uniset
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
#endif #endif
...@@ -6,33 +6,33 @@ using namespace std; ...@@ -6,33 +6,33 @@ using namespace std;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
// std::ios::sync_with_stdio(false); // std::ios::sync_with_stdio(false);
try try
{ {
if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) ) if( argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) )
{ {
cout << "--confile filename - configuration file. Default: configure.xml" << endl; cout << "--confile filename - configuration file. Default: configure.xml" << endl;
HttpResolver::help_print(); HttpResolver::help_print();
return 0; return 0;
} }
auto resolver = HttpResolver::init_resolver(argc, argv); auto resolver = HttpResolver::init_resolver(argc, argv);
if( !resolver ) if( !resolver )
return 1; return 1;
resolver->run(); resolver->run();
return 0; return 0;
} }
catch( const std::exception& ex ) catch( const std::exception& ex )
{ {
cerr << "(HttpResolver::main): " << ex.what() << endl; cerr << "(HttpResolver::main): " << ex.what() << endl;
} }
catch(...) catch(...)
{ {
cerr << "(HttpResolver::main): catch ..." << endl; cerr << "(HttpResolver::main): catch ..." << endl;
} }
return 1; return 1;
} }
...@@ -121,6 +121,7 @@ namespace uniset ...@@ -121,6 +121,7 @@ namespace uniset
const std::string getConfFileName() const noexcept; const std::string getConfFileName() const noexcept;
std::string getImagesDir() const noexcept; std::string getImagesDir() const noexcept;
std::string getNodeIp( uniset::ObjectId node );
timeout_t getHeartBeatTime() const noexcept; timeout_t getHeartBeatTime() const noexcept;
timeout_t getNCReadyTimeout() const noexcept; timeout_t getNCReadyTimeout() const noexcept;
...@@ -136,6 +137,7 @@ namespace uniset ...@@ -136,6 +137,7 @@ namespace uniset
bool isLocalIOR() const noexcept; bool isLocalIOR() const noexcept;
bool isTransientIOR() const noexcept; bool isTransientIOR() const noexcept;
size_t getHttpResovlerPort() const noexcept;
/*! получить значение указанного параметра, или значение по умолчанию */ /*! получить значение указанного параметра, или значение по умолчанию */
std::string getArgParam(const std::string& name, const std::string& defval = "") const noexcept; std::string getArgParam(const std::string& name, const std::string& defval = "") const noexcept;
...@@ -202,6 +204,8 @@ namespace uniset ...@@ -202,6 +204,8 @@ namespace uniset
timeout_t repeatTimeout = { 50 }; /*!< пауза между попытками [мс] */ timeout_t repeatTimeout = { 50 }; /*!< пауза между попытками [мс] */
size_t httpResolverPort = { 8008 };
uniset::ListOfNode lnodes; uniset::ListOfNode lnodes;
// repository // repository
......
...@@ -33,19 +33,19 @@ namespace uniset ...@@ -33,19 +33,19 @@ namespace uniset
{ {
public: public:
IORFile( const std::string& iordir ); IORFile( const std::string& iordir );
~IORFile(); ~IORFile();
std::string getIOR( const ObjectId id ); std::string getIOR( const ObjectId id );
void setIOR( const ObjectId id, const std::string& sior ); void setIOR( const ObjectId id, const std::string& sior );
void unlinkIOR( const ObjectId id ); void unlinkIOR( const ObjectId id );
std::string getFileName( const ObjectId id ); std::string getFileName( const ObjectId id );
private: private:
std::string iordir; std::string iordir;
}; };
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
} // end of namespace } // end of namespace
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
#endif #endif
#ifndef DISABLE_REST_API
/*
* Copyright (c) 2020 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program 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
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -------------------------------------------------------------------------
#ifndef UHttpClient_H_
#define UHttpClient_H_
// -------------------------------------------------------------------------
#include <string>
#include <Poco/Net/HTTPClientSession.h>
#include "DebugStream.h"
// -------------------------------------------------------------------------
namespace uniset
{
namespace UHttp
{
class UHttpClient
{
public:
UHttpClient();
virtual ~UHttpClient();
// http://site.com/query?params
// \return ""
std::string get( const std::string& host, int port, const std::string& request );
protected:
Poco::Net::HTTPClientSession session;
private:
};
}
}
// -------------------------------------------------------------------------
#endif // UHttpClient_H_
// -------------------------------------------------------------------------
#endif
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#include "IOController_i.hh" #include "IOController_i.hh"
#include "MessageType.h" #include "MessageType.h"
#include "Configuration.h" #include "Configuration.h"
#ifndef DISABLE_REST_API
#include "UHttpClient.h"
#endif
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
namespace uniset namespace uniset
{ {
...@@ -301,6 +304,7 @@ namespace uniset ...@@ -301,6 +304,7 @@ namespace uniset
protected: protected:
std::string set_err(const std::string& pre, const uniset::ObjectId id, const uniset::ObjectId node) const; std::string set_err(const std::string& pre, const uniset::ObjectId id, const uniset::ObjectId node) const;
std::string httpResolve( const uniset::ObjectId id, const uniset::ObjectId node ) const;
private: private:
void init(); void init();
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# This file is part of the UniSet library # # This file is part of the UniSet library #
############################################################################ ############################################################################
noinst_LTLIBRARIES = libHttp.la noinst_LTLIBRARIES = libHttp.la
libHttp_la_SOURCES = UHttpRequestHandler.cc UHttpServer.cc libHttp_la_SOURCES = UHttpRequestHandler.cc UHttpServer.cc UHttpClient.cc
libHttp_la_CXXFLAGS = $(POCO_CFLAGS) libHttp_la_CXXFLAGS = $(POCO_CFLAGS)
libHttp_la_LIBADD = $(POCO_LIBS) libHttp_la_LIBADD = $(POCO_LIBS)
......
#ifndef DISABLE_REST_API
/*
* Copyright (c) 2020 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program 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
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -------------------------------------------------------------------------
#include <sstream>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include "UHttpClient.h"
#include "Exceptions.h"
// -------------------------------------------------------------------------
using namespace Poco::Net;
// -------------------------------------------------------------------------
namespace uniset
{
using namespace UHttp;
// -------------------------------------------------------------------------
UHttpClient::UHttpClient()
{
}
// -------------------------------------------------------------------------
UHttpClient::~UHttpClient()
{
}
// -------------------------------------------------------------------------
std::string UHttpClient::get( const std::string& host, int port, const std::string& query )
{
session.setHost(host);
session.setPort(port);
HTTPRequest request(HTTPRequest::HTTP_GET, query, HTTPMessage::HTTP_1_1);
session.sendRequest(request);
HTTPResponse response;
std::istream& rs = session.receiveResponse(response);
if( response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK )
return "";
std::stringstream ret;
Poco::StreamCopier::copyStream(rs, ret);
return ret.str();
}
// -------------------------------------------------------------------------
} // end of namespace uniset
// -------------------------------------------------------------------------
#endif // #ifndef DISABLE_REST_API
...@@ -305,6 +305,7 @@ namespace uniset ...@@ -305,6 +305,7 @@ namespace uniset
// transientIOR // transientIOR
int tior = getArgInt("--transientIOR"); int tior = getArgInt("--transientIOR");
if( tior ) if( tior )
transientIOR = tior; transientIOR = tior;
...@@ -602,6 +603,10 @@ namespace uniset ...@@ -602,6 +603,10 @@ namespace uniset
else if( name == "LocalIOR" ) else if( name == "LocalIOR" )
{ {
localIOR = it.getIntProp("name"); localIOR = it.getIntProp("name");
httpResolverPort = it.getIntProp("httpResolverPort");
if( httpResolverPort <= 0 )
httpResolverPort = 8008;
} }
else if( name == "TransientIOR" ) else if( name == "TransientIOR" )
{ {
...@@ -1113,7 +1118,7 @@ namespace uniset ...@@ -1113,7 +1118,7 @@ namespace uniset
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
std::pair<string,xmlNode*> Configuration::getRepSectionName( const string& sec ) std::pair<string, xmlNode*> Configuration::getRepSectionName( const string& sec )
{ {
xmlNode* secnode = unixml->findNode(unixml->getFirstNode(), sec); xmlNode* secnode = unixml->findNode(unixml->getFirstNode(), sec);
...@@ -1323,6 +1328,20 @@ namespace uniset ...@@ -1323,6 +1328,20 @@ namespace uniset
return transientIOR; return transientIOR;
} }
size_t Configuration::getHttpResovlerPort() const noexcept
{
return httpResolverPort;
}
std::string Configuration::getNodeIp( uniset::ObjectId node )
{
UniXML::iterator nIt = getXMLObjectNode(node);
if( !nIt )
return "";
return nIt.getProp("ip");
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
xmlNode* Configuration::getXMLSensorsSection() noexcept xmlNode* Configuration::getXMLSensorsSection() noexcept
{ {
......
...@@ -874,9 +874,9 @@ namespace uniset ...@@ -874,9 +874,9 @@ namespace uniset
} }
// ------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------
uniset::ObjectPtr UInterface::resolve( const uniset::ObjectId rid , const uniset::ObjectId node ) const uniset::ObjectPtr UInterface::resolve( const uniset::ObjectId rid, const uniset::ObjectId node ) const
{ {
if ( rid == uniset::DefaultObjectId ) if( rid == uniset::DefaultObjectId )
throw uniset::ResolveNameError("UI(resolve): ID=uniset::DefaultObjectId"); throw uniset::ResolveNameError("UI(resolve): ID=uniset::DefaultObjectId");
if( node == uniset::DefaultObjectId ) if( node == uniset::DefaultObjectId )
...@@ -896,7 +896,12 @@ namespace uniset ...@@ -896,7 +896,12 @@ namespace uniset
if( CORBA::is_nil(orb) ) if( CORBA::is_nil(orb) )
orb = uconf->getORB(); orb = uconf->getORB();
string sior(uconf->iorfile->getIOR(rid)); string sior;
if( node == uconf->getLocalNode() )
sior = uconf->iorfile->getIOR(rid);
else
sior = httpResolve(rid, node);
if( !sior.empty() ) if( !sior.empty() )
{ {
...@@ -904,13 +909,11 @@ namespace uniset ...@@ -904,13 +909,11 @@ namespace uniset
rcache.cache(rid, node, nso); // заносим в кэш rcache.cache(rid, node, nso); // заносим в кэш
return nso._retn(); return nso._retn();
} }
else
{ uwarn << "not found IOR-file for " << uconf->oind->getNameById(rid)
// если NameService недоступен то, << " node=" << uconf->oind->getNameById(node)
// сразу выдаём ошибку << endl;
uwarn << "not found IOR-file for " << uconf->oind->getNameById(rid) << endl; throw uniset::ResolveNameError();
throw uniset::ResolveNameError();
}
} }
if( node != uconf->getLocalNode() ) if( node != uconf->getLocalNode() )
...@@ -1019,6 +1022,36 @@ namespace uniset ...@@ -1019,6 +1022,36 @@ namespace uniset
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
std::string UInterface::httpResolve( const uniset::ObjectId id, const uniset::ObjectId node ) const
{
#ifndef DISABLE_REST_API
size_t port = uconf->getHttpResovlerPort();
if( port == 0 )
return "";
const std::string host = uconf->getNodeIp(node);
if( host.empty() )
return "";
string ret;
const string query = "api/v01/resolve/text?" + std::to_string(id);
for( size_t i = 0; i < uconf->getRepeatCount(); i++ )
{
ret = resolver.get(host, port, query);
if( !ret.empty() )
return ret;
msleep(uconf->getRepeatTimeout());
}
#endif
return "";
}
// -------------------------------------------------------------------------------------------
void UInterface::send( const uniset::ObjectId name, const uniset::TransportMessage& msg, const uniset::ObjectId node ) void UInterface::send( const uniset::ObjectId name, const uniset::TransportMessage& msg, const uniset::ObjectId node )
{ {
if ( name == uniset::DefaultObjectId ) if ( name == uniset::DefaultObjectId )
......
...@@ -11,11 +11,11 @@ TEST_CASE("IORFile", "[iorfile][basic]" ) ...@@ -11,11 +11,11 @@ TEST_CASE("IORFile", "[iorfile][basic]" )
{ {
CHECK( uniset_conf() != nullptr ); CHECK( uniset_conf() != nullptr );
ObjectId testID = 1; ObjectId testID = 1;
const std::string iorstr("testIORstring"); const std::string iorstr("testIORstring");
IORFile ior(uniset_conf()->getLockDir()); IORFile ior(uniset_conf()->getLockDir());
ior.setIOR(testID, iorstr); ior.setIOR(testID, iorstr);
REQUIRE( ior.getIOR(testID) == iorstr ); REQUIRE( ior.getIOR(testID) == iorstr );
CHECK( file_exist(ior.getFileName(testID)) ); CHECK( file_exist(ior.getFileName(testID)) );
ior.unlinkIOR(testID); ior.unlinkIOR(testID);
......
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
./extensions/DBServer-SQLite/SQLiteInterface.cc ./extensions/DBServer-SQLite/SQLiteInterface.cc
./extensions/DBServer-SQLite/SQLiteInterface.h ./extensions/DBServer-SQLite/SQLiteInterface.h
./extensions/DBServer-SQLite/test.cc ./extensions/DBServer-SQLite/test.cc
./extensions/HttpResolver/HttpResolver.cc
./extensions/HttpResolver/HttpResolver.h
./extensions/HttpResolver/HttpResolverSugar.h
./extensions/HttpResolver/main.cc
./extensions/HttpResolver/Makefile.am
./extensions/include/Calibration.h ./extensions/include/Calibration.h
./extensions/include/ComediInterface.h ./extensions/include/ComediInterface.h
./extensions/include/DigitalFilter.h ./extensions/include/DigitalFilter.h
...@@ -185,43 +190,6 @@ ...@@ -185,43 +190,6 @@
./extensions/SMViewer/Makefile.am ./extensions/SMViewer/Makefile.am
./extensions/SMViewer/SMViewer.cc ./extensions/SMViewer/SMViewer.cc
./extensions/SMViewer/SMViewer.h ./extensions/SMViewer/SMViewer.h
./extensions/tests1/Makefile.am
./extensions/tests1/MBSlaveTest/Makefile.am
./extensions/tests1/MBSlaveTest/mbslave-test.cc
./extensions/tests1/MBSlaveTest/TestProc.cc
./extensions/tests1/MBSlaveTest/TestProc.h
./extensions/tests1/MBSlaveTest/testproc.src.xml
./extensions/tests1/MQPerfTest/Makefile.am
./extensions/tests1/MQPerfTest/mq-test.cc
./extensions/tests1/MQPerfTest/TestProc.cc
./extensions/tests1/MQPerfTest/TestProc.h
./extensions/tests1/MQPerfTest/testproc.src.xml
./extensions/tests1/r/t.cc
./extensions/tests1/SMemoryTest/LostPassiveTestProc.cc
./extensions/tests1/SMemoryTest/LostPassiveTestProc.h
./extensions/tests1/SMemoryTest/LostTestProc.cc
./extensions/tests1/SMemoryTest/LostTestProc.h
./extensions/tests1/SMemoryTest/losttestproc.src.xml
./extensions/tests1/SMemoryTest/Makefile.am
./extensions/tests1/SMemoryTest/smemory-test.cc
./extensions/tests1/SMemoryTest/sm-lostmessage-test.cc
./extensions/tests1/SMemoryTest/TestProc.cc
./extensions/tests1/SMemoryTest/TestProc.h
./extensions/tests1/SMemoryTest/testproc.src.xml
./extensions/tests1/sm_perf_test2.cc
./extensions/tests1/sm_perf_test.cc
./extensions/tests1/sz.cc
./extensions/tests1/test_calibration.cc
./extensions/tests1/test_digitalfilter.cc
./extensions/tests1/test_iobase.cc
./extensions/tests1/test_iobase_with_sm.cc
./extensions/tests1/test_restapi_uniset.cc
./extensions/tests1/tests.cc
./extensions/tests1/tests_with_conf.cc
./extensions/tests1/tests_with_sm.cc
./extensions/tests1/tests_with_sm.h
./extensions/tests1/test_ui.cc
./extensions/tests1/test_vtypes.cc
./extensions/tests/Makefile.am ./extensions/tests/Makefile.am
./extensions/tests/MBSlaveTest/Makefile.am ./extensions/tests/MBSlaveTest/Makefile.am
./extensions/tests/MBSlaveTest/mbslave-test.cc ./extensions/tests/MBSlaveTest/mbslave-test.cc
...@@ -264,7 +232,6 @@ ...@@ -264,7 +232,6 @@
./extensions/UNetUDP/tests/Makefile.am ./extensions/UNetUDP/tests/Makefile.am
./extensions/UNetUDP/tests/tests_individual_process.cc ./extensions/UNetUDP/tests/tests_individual_process.cc
./extensions/UNetUDP/tests/tests_with_sm.cc ./extensions/UNetUDP/tests/tests_with_sm.cc
./extensions/UNetUDP/tests/test_unetudp1.cc
./extensions/UNetUDP/tests/test_unetudp.cc ./extensions/UNetUDP/tests/test_unetudp.cc
./extensions/UNetUDP/tests/u.cc ./extensions/UNetUDP/tests/u.cc
./extensions/UNetUDP/tests/urecv_perf_test.cc ./extensions/UNetUDP/tests/urecv_perf_test.cc
...@@ -358,6 +325,7 @@ ...@@ -358,6 +325,7 @@
./include/UA.h ./include/UA.h
./include/UDPCore.h ./include/UDPCore.h
./include/UHelpers.h ./include/UHelpers.h
./include/UHttpClient.h
./include/UHttpRequestHandler.h ./include/UHttpRequestHandler.h
./include/UHttpServer.h ./include/UHttpServer.h
./include/UInterface.h ./include/UInterface.h
...@@ -368,6 +336,7 @@ ...@@ -368,6 +336,7 @@
./include/unisetstd.h ./include/unisetstd.h
./include/UniSetTypes.h ./include/UniSetTypes.h
./include/UniXML.h ./include/UniXML.h
./include/UResolver.h
./include/USocket.h ./include/USocket.h
./include/UTCPCore.h ./include/UTCPCore.h
./include/UTCPSocket.h ./include/UTCPSocket.h
...@@ -380,6 +349,7 @@ ...@@ -380,6 +349,7 @@
./src/Communications/ComPort485F.cc ./src/Communications/ComPort485F.cc
./src/Communications/ComPort.cc ./src/Communications/ComPort.cc
./src/Communications/Http/Makefile.am ./src/Communications/Http/Makefile.am
./src/Communications/Http/UHttpClient.cc
./src/Communications/Http/UHttpRequestHandler.cc ./src/Communications/Http/UHttpRequestHandler.cc
./src/Communications/Http/UHttpServer.cc ./src/Communications/Http/UHttpServer.cc
./src/Communications/Makefile.am ./src/Communications/Makefile.am
...@@ -416,6 +386,8 @@ ...@@ -416,6 +386,8 @@
./src/Core/UniSetObject_iSK.cc ./src/Core/UniSetObject_iSK.cc
./src/Core/UniSetTypes.cc ./src/Core/UniSetTypes.cc
./src/Core/UniSetTypes_iSK.cc ./src/Core/UniSetTypes_iSK.cc
./src/Core/UResolver.cc
./src/Core/UResolver_iSK.cc
./src/Log/Debug.cc ./src/Log/Debug.cc
./src/Log/DebugExtBuf.h ./src/Log/DebugExtBuf.h
./src/Log/DebugStream.cc ./src/Log/DebugStream.cc
......
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