Commit d373cbe2 authored by Pavel Vainerman's avatar Pavel Vainerman

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

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