Commit d373cbe2 authored by Pavel Vainerman's avatar Pavel Vainerman

(UHttp): добавил функцию /help, /ObjectName/help для вывода списка доступных команд

parent c3f077a6
...@@ -28,13 +28,18 @@ ...@@ -28,13 +28,18 @@
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/*! \page UHttpServer API /*! \page UHttpServer API
* *
* Формат запроса: /api/version/get/xxx * Формат запроса: /api/version/xxx
*
* Пока поддерживается только метод GET
* Ответ в формате JSON
* *
* Версия API: v01 * Версия API: v01
* /api/version/get/ObjectName - получение информации об объекте ObjectName (json) * /api/version/list - Получение списка доступных объектов
* /api/version/get/list - Получение списка доступных объектов * /api/version/help - Получение списка доступных команд
* /api/version/ObjectName - получение информации об объекте ObjectName
* /api/version/ObjectName/help - получение списка доступных команд для объекта ObjectName
* *
* \todo подумать над /api/version/get/tree - получение "дерева" объектов (древовидный список с учётом подчинения Manager/Objects) * \todo подумать над /api/version/tree - получение "дерева" объектов (древовидный список с учётом подчинения Manager/Objects)
*/ */
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
namespace UniSetTypes namespace UniSetTypes
...@@ -51,7 +56,9 @@ namespace UniSetTypes ...@@ -51,7 +56,9 @@ namespace UniSetTypes
IHttpRequest(){} IHttpRequest(){}
virtual ~IHttpRequest(){} virtual ~IHttpRequest(){}
// throw SystemError
virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) = 0; virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) = 0;
virtual nlohmann::json help( const Poco::URI::QueryParameters& p ) = 0;
}; };
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/*! интерфейс для обработки запросов к объектам */ /*! интерфейс для обработки запросов к объектам */
...@@ -61,8 +68,13 @@ namespace UniSetTypes ...@@ -61,8 +68,13 @@ namespace UniSetTypes
IHttpRequestRegistry(){} IHttpRequestRegistry(){}
virtual ~IHttpRequestRegistry(){} virtual ~IHttpRequestRegistry(){}
// throw SystemError, NameNotFound
virtual nlohmann::json getDataByName( const std::string& name, const Poco::URI::QueryParameters& p ) = 0; virtual nlohmann::json getDataByName( const std::string& name, const Poco::URI::QueryParameters& p ) = 0;
// throw SystemError
virtual nlohmann::json getObjectsList( const Poco::URI::QueryParameters& p ) = 0; virtual nlohmann::json getObjectsList( const Poco::URI::QueryParameters& p ) = 0;
virtual nlohmann::json helpByName( const std::string& name, const Poco::URI::QueryParameters& p ) = 0;
}; };
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -88,6 +88,7 @@ class UniSetActivator: ...@@ -88,6 +88,7 @@ class UniSetActivator:
// Поддрежка REST API (IHttpRequestRegistry) // Поддрежка REST API (IHttpRequestRegistry)
virtual nlohmann::json getDataByName( const std::string& name , const Poco::URI::QueryParameters& p ) override; virtual nlohmann::json getDataByName( const std::string& name , const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json getObjectsList( const Poco::URI::QueryParameters& p ) override; virtual nlohmann::json getObjectsList( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json helpByName( const std::string& name, const Poco::URI::QueryParameters& p ) override;
protected: protected:
......
...@@ -103,6 +103,7 @@ class UniSetObject: ...@@ -103,6 +103,7 @@ class UniSetObject:
// HTTP API // HTTP API
virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) override; virtual nlohmann::json getData( const Poco::URI::QueryParameters& p ) override;
virtual nlohmann::json help( const Poco::URI::QueryParameters& p ) override;
// -------------- вспомогательные -------------- // -------------- вспомогательные --------------
/*! получить ссылку (на себя) */ /*! получить ссылку (на себя) */
......
...@@ -32,9 +32,27 @@ void UHttpRequestHandler::handleRequest( Poco::Net::HTTPServerRequest& req, Poco ...@@ -32,9 +32,27 @@ void UHttpRequestHandler::handleRequest( Poco::Net::HTTPServerRequest& req, Poco
{ {
if( !registry ) if( !registry )
{ {
resp.setStatus(HTTPResponse::HTTP_NOT_FOUND); resp.setStatus(HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
resp.setContentType("text/json"); resp.setContentType("text/json");
std::ostream& out = resp.send(); std::ostream& out = resp.send();
nlohmann::json jdata;
jdata["error"] = resp.getReasonForStatus(resp.getStatus());
jdata["ecode"] = resp.getStatus();
out << jdata.dump();
out.flush();
return;
}
// В этой версии API поддерживается только GET
if( req.getMethod() != "GET" )
{
resp.setStatus(HTTPResponse::HTTP_BAD_REQUEST);
resp.setContentType("text/json");
std::ostream& out = resp.send();
nlohmann::json jdata;
jdata["error"] = resp.getReasonForStatus(resp.getStatus());
jdata["ecode"] = resp.getStatus();
out << jdata.dump();
out.flush(); out.flush();
return; return;
} }
...@@ -47,40 +65,72 @@ void UHttpRequestHandler::handleRequest( Poco::Net::HTTPServerRequest& req, Poco ...@@ -47,40 +65,72 @@ void UHttpRequestHandler::handleRequest( Poco::Net::HTTPServerRequest& req, Poco
std::vector<std::string> seg; std::vector<std::string> seg;
uri.getPathSegments(seg); uri.getPathSegments(seg);
// example: http://host:port/api/version/get/ObjectName // example: http://host:port/api/version/ObjectName
if( seg.size() < 4 if( seg.size() < 3
|| seg[0] != "api"
|| seg[1] != UHTTP_API_VERSION || seg[1] != UHTTP_API_VERSION
|| seg[2] != "get" || seg[2].empty() )
|| seg[3].empty() )
{ {
resp.setStatus(HTTPResponse::HTTP_BAD_REQUEST); resp.setStatus(HTTPResponse::HTTP_BAD_REQUEST);
resp.setContentType("text/json"); resp.setContentType("text/json");
std::ostream& out = resp.send(); std::ostream& out = resp.send();
nlohmann::json jdata; nlohmann::json jdata;
jdata["error"] = "HTTP_BAD_REQUEST"; jdata["error"] = resp.getReasonForStatus(resp.getStatus());
jdata["ecode"] = HTTPResponse::HTTP_BAD_REQUEST; jdata["ecode"] = resp.getStatus();
out << jdata.dump(); out << jdata.dump();
out.flush(); out.flush();
return; return;
} }
const std::string objectName(seg[3]); const std::string objectName(seg[2]);
auto qp = uri.getQueryParameters(); auto qp = uri.getQueryParameters();
resp.setStatus(HTTPResponse::HTTP_OK); resp.setStatus(HTTPResponse::HTTP_OK);
resp.setContentType("text/json"); resp.setContentType("text/json");
std::ostream& out = resp.send(); std::ostream& out = resp.send();
if( objectName == "list" ) try
{
if( objectName == "help" )
{
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"}
};
out << jdata.dump();
}
else if( objectName == "list" )
{ {
auto json = registry->getObjectsList(qp); auto json = registry->getObjectsList(qp);
out << json.dump(); out << json.dump();
} }
else if( seg.size() >=4 && seg[3] == "help" ) // /api/version/ObjectName/help
{
auto json = registry->helpByName(objectName, qp);
out << json.dump();
}
else else
{ {
auto json = registry->getDataByName(objectName, qp); auto json = registry->getDataByName(objectName, qp);
out << json.dump(); out << json.dump();
} }
}
catch( std::exception& ex )
{
ostringstream err;
err << ex.what();
resp.setStatus(HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
resp.setContentType("text/json");
nlohmann::json jdata;
jdata["error"] = err.str();
jdata["ecode"] = resp.getStatus();
out << jdata.dump();
}
out.flush(); out.flush();
} }
......
...@@ -870,13 +870,10 @@ nlohmann::json UniSetActivator::getDataByName( const string& name, const Poco::U ...@@ -870,13 +870,10 @@ nlohmann::json UniSetActivator::getDataByName( const string& name, const Poco::U
if( obj ) if( obj )
return obj->getData(p); return obj->getData(p);
//! \todo Продумать что возвращать если объект не найден
nlohmann::json jdata;
ostringstream err; ostringstream err;
err << "Object '" << name << "' not found"; err << "Object '" << name << "' not found";
jdata["error"] = err.str();
jdata["ecode"] = Poco::Net::HTTPResponse::HTTP_OK; throw UniSetTypes::NameNotFound(err.str());
return jdata;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
nlohmann::json UniSetActivator::getObjectsList( const Poco::URI::QueryParameters& p ) nlohmann::json UniSetActivator::getObjectsList( const Poco::URI::QueryParameters& p )
...@@ -896,6 +893,20 @@ nlohmann::json UniSetActivator::getObjectsList( const Poco::URI::QueryParameters ...@@ -896,6 +893,20 @@ nlohmann::json UniSetActivator::getObjectsList( const Poco::URI::QueryParameters
return jdata; return jdata;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
nlohmann::json UniSetActivator::helpByName( const string& name, const Poco::URI::QueryParameters& p )
{
if( name == myname )
return help(p);
auto obj = deepFindObject(name);
if( obj )
return obj->help(p);
ostringstream err;
err << "Object '" << name << "' not found";
throw UniSetTypes::NameNotFound(err.str());
}
// ------------------------------------------------------------------------------------------
void UniSetActivator::terminated( int signo ) void UniSetActivator::terminated( int signo )
{ {
if( !g_act ) if( !g_act )
......
...@@ -393,6 +393,13 @@ nlohmann::json UniSetObject::getData( const Poco::URI::QueryParameters& p ) ...@@ -393,6 +393,13 @@ nlohmann::json UniSetObject::getData( const Poco::URI::QueryParameters& p )
return jdata; return jdata;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
nlohmann::json UniSetObject::help( const Poco::URI::QueryParameters& p )
{
nlohmann::json jdata;
jdata[myname]["help"] = {};
return jdata;
}
// ------------------------------------------------------------------------------------------
ObjectPtr UniSetObject::getRef() const ObjectPtr UniSetObject::getRef() const
{ {
UniSetTypes::uniset_rwmutex_rlock lock(refmutex); UniSetTypes::uniset_rwmutex_rlock lock(refmutex);
......
...@@ -22,6 +22,17 @@ class UTestSupplier: ...@@ -22,6 +22,17 @@ class UTestSupplier:
j["test"] = 42; j["test"] = 42;
return j; return j;
} }
virtual nlohmann::json help( const Poco::URI::QueryParameters& p ) override
{
nlohmann::json j;
j["test"]["help"] = {
{"cmd1","help for cmd1"},
{"cmd2","help for cmd2"}
};
return j;
}
}; };
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
class UTestRequestRegistry: class UTestRequestRegistry:
...@@ -48,6 +59,17 @@ class UTestRequestRegistry: ...@@ -48,6 +59,17 @@ class UTestRequestRegistry:
return j; return j;
} }
virtual nlohmann::json helpByName( const std::string& name, const Poco::URI::QueryParameters& p ) override
{
nlohmann::json j;
j["TestObject"]["help"] = {
{"cmd1","help for cmd1"},
{"cmd2","help for cmd2"}
};
return j;
}
private: private:
UTestSupplier sup; UTestSupplier sup;
}; };
......
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