aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2019-09-06 18:04:40 +0200
committerneodarz <neodarz@neodarz.net>2019-09-06 18:04:40 +0200
commit1b922f7319f821fe3daf302a8c68131aaa94f586 (patch)
treedebf82b507174f158b9cb4e030b3f82d31c44a64
parent3185dd695d58bb96672d4f33c4528bf8b361707f (diff)
downloadumosapicpp-1b922f7319f821fe3daf302a8c68131aaa94f586.tar.xz
umosapicpp-1b922f7319f821fe3daf302a8c68131aaa94f586.zip
Change code to use Restbed
-rw-r--r--CMakeLists.txt33
-rw-r--r--README.md16
-rw-r--r--api/umosapi.cpp480
-rw-r--r--api/umosapi.h105
-rw-r--r--db/uobject.cpp4
-rw-r--r--main.cpp33
6 files changed, 525 insertions, 146 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index db27ade..3b03a34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,9 +6,6 @@ find_package(libbsoncxx REQUIRED)
include_directories(${LIBMONGOCXX_INCLUDE_DIR})
include_directories(${LIBBSONCXX_INCLUDE_DIR})
-find_package(Pistache REQUIRED)
-include_directories(${Pistache_INCLUDE_DIR})
-
find_package(nlohmann_json REQUIRED)
include_directories(${JSON_INCLUDE_DIR})
@@ -40,6 +37,30 @@ or
/usr/local/lib")
endif(NOT JSONC_FOUND)
+find_path(RESTBED_INCLUDE_DIRS restbed
+ HINTS
+ /usr/include/corvusoft/
+ /usr/local/corvusoft/
+)
+find_library(RESTBED_LIBRARIES restbed
+ HINTS
+ /usr/lib/
+ /usr/local/lib
+)
+
+find_package_handle_standard_args(restbed DEFAULT_MSG RESTBED_INCLUDE_DIRS RESTBED_LIBRARIES)
+
+if (NOT RESTBED_FOUND)
+message(FATAL_ERROR "restbed lib not found! Please check if headers files are in
+/usr/include/restbed/
+or
+/usr/local/include/restbed/
+Also please check that libs files ares in
+/usr/lib/
+or
+/usr/local/lib")
+endif(NOT RESTBED_FOUND)
+
add_executable(umosapi main.cpp config.cpp api/umosapi.cpp db/mongo_access.cpp db/uobject.cpp api/umosapi.h config.h db/mongo_access.h db/uobject.h shared.h)
@@ -49,10 +70,10 @@ target_include_directories(umosapi PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
target_link_libraries(umosapi PUBLIC ${LIBBSONCXX_LIBRARIES})
target_link_libraries(umosapi PUBLIC ${LIBMONGOCXX_LIBRARIES})
-target_link_libraries(umosapi PUBLIC ${Pistache_LIBRARIES}/libpistache.so)
-target_include_directories(umosapi PUBLIC ${Pistache_INCLUDE_DIRS})
-
target_link_libraries(umosapi PUBLIC ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(umosapi PUBLIC ${JSONC_INCLUDE_DIRS})
target_link_libraries(umosapi PUBLIC ${JSONC_LIBRARIES})
+
+target_include_directories(umosapi PUBLIC ${RESTBED_INCLUDE_DIRS})
+target_link_libraries(umosapi PUBLIC ${RESTBED_LIBRARIES})
diff --git a/README.md b/README.md
index 83a54e8..beee8d9 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,15 @@
# UMoSApi
This is a second implementation in C++ of the [Python](https://git.neodarz.net/pro/umosapi.git/about/)
-version of Unity Mongo Save Api. This is a simple API for save Unity object in
-Mongo database.
+version of Unity Mongo Save Api principally for speed issue. This is a simple
+API for save Unity object in Mongo database.
+
+In fact it was initially made for an Unity project but because of the
+simplicity of the API you can use with whatever you want. ;)
+
+/!\ WARNING: For the moment there is no authentifaction system! So don't use it
+over the internet or in an environment where unknow user can connect and also
+make sure your network is correctly securised.
# Install
@@ -10,7 +17,7 @@ Mongo database.
Install:
-- Pistache
+- Restbed
- json-c
- nlohmann/json
- mongocxx
@@ -19,7 +26,8 @@ Install:
Because json-c is more fast than nlohmann/json when I do the test, json-c lib
is only used for convert bson to json and vice versa. The nlohmann/json is
-only used for simplicty when loading config file.
+only used for simplicty when loading config file and generate swagger.json
+file.
# Build
diff --git a/api/umosapi.cpp b/api/umosapi.cpp
index 83965a3..af58b37 100644
--- a/api/umosapi.cpp
+++ b/api/umosapi.cpp
@@ -17,6 +17,12 @@
#include "../db/mongo_access.h"
#include "../db/uobject.h"
+#include <regex>
+#include <sstream>
+#include <iomanip>
+#include <fstream>
+#include <streambuf>
+
mongo_access mongo;
@@ -30,133 +36,395 @@ using bsoncxx::builder::stream::open_document;
using json = nlohmann::json;
using namespace std;
-using namespace Pistache;
+using namespace restbed;
-namespace Generic {
- void handleReady(const Rest::Request&, Http::ResponseWriter response) {
- response.send(Http::Code::Ok, "1");
- }
-}
+UmosapiService::UmosapiService() {}
-UmosapiService::UmosapiService(Address addr)
- : httpEndpoint(std::make_shared<Http::Endpoint>(addr))
- , desc("Unity Mongo Save API", "0.1")
-{ }
+void UmosapiService::init() {
-void UmosapiService::init(size_t thr = 2) {
auto uri = mongocxx::uri{config["mongoURI"]};
mongo.configure(std::move(uri));
- auto opts = Http::Endpoint::options()
- .threads(thr);
- httpEndpoint->init(opts);
- createDescription();
-}
-
-void UmosapiService::start(std::string swaggerui) {
- router.initFromDescription(desc);
-
- Rest::Swagger swagger(desc);
- swagger
- .uiPath("/doc")
- .uiDirectory(swaggerui)
- .apiPath("/api")
- .serializer(&Rest::Serializer::rapidJson)
- .install(router);
-
- httpEndpoint->setHandler(router.handler());
- httpEndpoint->serve();
-}
-
-void UmosapiService::createDescription() {
- desc
- .info()
- .license("Apache", "https://neodarz.net");
-
- auto backendErrorResponse =
- desc.response(Http::Code::Internal_Server_Error, "Backend is dead, it's the end of the world");
-
- desc
- .schemes(Rest::Scheme::Http)
- .basePath("/v1")
- .produces(MIME(Application, Json))
- .consumes(MIME(Application, Json));
-
- desc
- .route(desc.get("/ready"))
- .bind(&Generic::handleReady)
- .response(Http::Code::Ok, "Api started")
- .response(backendErrorResponse);
-
- auto versionPath = desc.path("/v1");
-
- versionPath
- .route(desc.get("/:mcollection"))
- .bind(&UmosapiService::UmosapiService::retrieveAll, this)
- .produces(MIME(Application, Json))
- .parameter<Rest::Type::String>("mcollection", "Name of the collection where the uobjects are located")
- .response(Http::Code::Ok, "List of uobjects")
- .response(backendErrorResponse);
-
- versionPath
- .route(desc.post("/:mcollection"))
- .bind(&UmosapiService::UmosapiService::addUObject, this)
- .produces(MIME(Application, Json))
- .parameter<Rest::Type::String>("mcollection", "Name of the collection where the uobjects are located")
- .response(Http::Code::Ok, "Uobject created")
- .response(backendErrorResponse);
-
- versionPath
- .route(desc.del("/:mcollection/:oid"))
- .bind(&UmosapiService::UmosapiService::deleteUObject, this)
- .produces(MIME(Application, Json))
- .parameter<Rest::Type::String>("mcollection", "Name of the collection where the uobjects are located")
- .parameter<Rest::Type::String>("oid", "MongoDB oid of the uobject")
- .response(Http::Code::Ok, "Uobject deleted")
- .response(backendErrorResponse);
-
- versionPath
- .route(desc.get("/:mcollection/:key/:value"))
- .bind(&UmosapiService::UmosapiService::searchUObjectByKeyValue, this)
- .produces(MIME(Application, Json))
- .parameter<Rest::Type::String>("mcollection", "Name of the collection where the uobjects are located")
- .parameter<Rest::Type::String>("key", "Key of uobject to search, ex.: kil or total.kill")
- .parameter<Rest::Type::String>("value", "Value of uobject to search, ex.: 12")
- .response(Http::Code::Ok, "Uobject found")
- .response(backendErrorResponse);
-}
-
-void UmosapiService::retrieveAll(const Rest::Request& request, Http::ResponseWriter response) {
- auto jsonObjects = json_object_new_array();
- auto json_string = uobject::retrieveAll(request.param(":mcollection").as<string>(), jsonObjects);
- json_object_put(jsonObjects);
+ createResource();
+ ofstream swagger_json;
+ swagger_json.open(config["swaggerui"] + "/swagger.json");
+ swagger_json << _swagger.dump();
+ swagger_json.close();
+}
- response.send(Http::Code::Ok, json_string, MIME(Application, Json));
+void UmosapiService::start(int port, int thr) {
+ auto settings = make_shared< Settings >();
+ settings->set_port( port );
+ settings->set_worker_limit( thr );
+ settings->set_default_header("Connection", "close");
+ _service.start(settings);
}
-void UmosapiService::addUObject(const Rest::Request& request, Http::ResponseWriter response) {
- auto jsonObject = json_object_new_object();
+void service_error_handler( const int, const exception& e, const shared_ptr< Session > session )
+{
+ std::string message = "Backend Service is dead: ";
+ message += e.what();
+ if ( session->is_open( ) )
+ session->close( 500, message, { { "Content-Length", ::to_string(message.length()) } } );
+ fprintf( stderr, "ERROR: %s.\n", message.c_str() );
+}
- auto json_string = uobject::add(request.param(":mcollection").as<string>(), jsonObject, request.body().c_str());
+void resource_error_handler( const int, const exception& e, const shared_ptr< Session > session )
+{
+ std::string message = "Backend Resource is dead: ";
+ message += e.what();
+ if ( session->is_open( ) )
+ session->close( 500, message, { { "Content-Length", ::to_string(message.length()) } } );
+ fprintf( stderr, "ERROR: %s.\n", message.c_str() );
+}
- response.send(Http::Code::Ok, json_string, MIME(Application, Json));
- json_object_put(jsonObject);
+void faulty_method_handler( const shared_ptr< Session > )
+{
+ throw SERVICE_UNAVAILABLE;
+}
+
+void is_ready(const shared_ptr<Session> session)
+{
+ session->close( OK, "1", { { "Content-Length", "1"}});
+}
+
+/*
+ * Add new route in service
+ * service: the service pointer
+ * route: path of the route
+ * http_word: word http who defin REST request
+ * callback: function to call when the route is requested
+ * error_callback: error to show if everything is broken
+ * tags: array of tags
+ */
+void UmosapiService::desc(std::string route, std::string http_word, const std::function< void ( const std::shared_ptr< Session > ) >& callback, const std::function< void(int, const std::exception&, std::shared_ptr<restbed::Session>) >& error_callback, tag tags[]) {
+ auto resource = make_shared< Resource > ();
+ resource->set_path(route);
+ resource->set_method_handler(http_word, callback);
+ resource->set_error_handler( error_callback );
+
+ _service.publish(resource);
+}
+
+void UmosapiService::description(std::string description) {
+ _swagger["info"]["description"] = description;
+}
+
+void UmosapiService::title(std::string title) {
+ _swagger["info"]["title"] = title;
+}
+
+void UmosapiService::version(std::string version) {
+ _swagger["info"]["version"] = version;
+}
+
+void UmosapiService::basePath(std::string basePath) {
+ _swagger["swagger"] = "2.0";
+ _swagger["basePath"] = basePath;
+}
+
+void UmosapiService::host(std::string host) {
+ _swagger["host"] = host;
+}
+
+void UmosapiService::atag(std::string name, std::string description) {
+ struct tag the_tag;
+ the_tag.name = name;
+ the_tag.description = description;
+
+ _tags.push_back(the_tag);
+ _swagger["tags"].push_back({ {"name",the_tag.name},{"description", the_tag.description} });
+
+}
+
+void UmosapiService::scheme(std::string scheme) {
+ _swagger["schemes"].push_back(scheme);
+}
+
+void UmosapiService::set_path(std::string route) {
+ _resource = make_shared< Resource > ();
+ _resource->set_path(route);
+ std::regex parameter(":.*?}");
+ std::regex base_path("^/v2");
+ auto tmp_route = std::regex_replace (route,parameter,"}");
+ auto final_route = std::regex_replace (tmp_route,base_path,"");
+ _path = Path{final_route};
+ _swagger["paths"][final_route] = {};
+}
+
+void UmosapiService::set_method_handler(std::string http_word, const std::function< void ( const std::shared_ptr< Session > ) >& callback) {
+ _resource->set_method_handler(http_word, callback);
+ std::locale loc;
+ for (auto& c : http_word) {
+ c = tolower(c);
+ }
+ _path.words.push_back(HttpWord{http_word});
+ _swagger["paths"][_path.name][http_word]["description"] = "";
+ _swagger["paths"][_path.name][http_word]["operationId"] = "";
+ _swagger["paths"][_path.name][http_word]["summary"] = "";
+}
+
+void UmosapiService::set_error_handler(const std::function< void(int, const std::exception&, std::shared_ptr<restbed::Session>) >& error_callback) {
+ _resource->set_error_handler( error_callback );
+}
+
+void UmosapiService::publish() {
+ for (auto& http_word: _path.words) {
+ auto responses = _swagger["paths"][_path.name][http_word.name]["responses"];
+ if (responses.find("200") == responses.end()) {
+ _swagger["paths"][_path.name][http_word.name]["responses"]["200"]["description"] = "All is fine.";
+ }
+ }
+ _service.publish(_resource);
+}
+
+void UmosapiService::definition(std::string name, std::string type) {
+ _definition = Definition{name, type};
+ _definitions.defs.push_back(_definition);
+ _swagger["definitions"][name]["type"] = type;
+}
+
+void UmosapiService::propertie(std::string name, std::string format, std::string type, std::string required) {
+ _definition.props.push_back(Propertie{name, format, type, required});
+ _swagger["definitions"][_definition.name]["properties"][name]["format"] = format;
+ _swagger["definitions"][_definition.name]["properties"][name]["type"] = type;
+ if (required == "true") {
+ _swagger["definitions"][_definition.name]["required"].push_back(name);
+ }
+}
+
+void UmosapiService::consume(std::string consume) {
+ _swagger["paths"][_path.name][_path.words.back().name]["consumes"].push_back(consume);
+}
+
+void UmosapiService::produce(std::string produce) {
+ _swagger["paths"][_path.name][_path.words.back().name]["produces"].push_back(produce);
+}
+
+void UmosapiService::parameter(std::string name, std::string description, std::string schema = "") {
+ json parameter;
+ parameter["name"] = name;
+ parameter["description"] = description;
+ parameter["required"] = true;
+ if (schema == "") {
+ parameter["type"] = "string";
+ parameter["in"] = "path";
+ } else {
+ parameter["in"] = "body";
+ for (auto& def: _definitions.defs) {
+ if (def.name == schema ) {
+ std::string schema_path = "#/definitions/";
+ parameter["schema"]["$ref"] = schema_path.append(schema);
+ }
+ }
+ }
+ _swagger["paths"][_path.name][_path.words.back().name]["parameters"].push_back(parameter);
+}
+
+void UmosapiService::response(std::string http_code, std::string description, std::string definition) {
+ std::string schema = "#/definitions/";
+ _swagger["paths"][_path.name][_path.words.back().name]["responses"][http_code]["description"] = description;
+ _swagger["paths"][_path.name][_path.words.back().name]["responses"][http_code]["schema"]["items"]["$ref"] = schema.append(definition);
+ _swagger["paths"][_path.name][_path.words.back().name]["responses"][http_code]["schema"]["type"] = "array";
+}
+
+void UmosapiService::swagger(std::string ui_path, std::string swagger_dir, std::string api_path) {
+ _resource = make_shared< Resource > ();
+ _resource->set_path(ui_path);
+ _resource->set_method_handler("GET", swaggerEndpoint);
+ _service.publish(_resource);
+
+ _resource = make_shared< Resource > ();
+ _resource->set_path(ui_path + "/{filename: .*}");
+ _resource->set_method_handler("GET", swaggerEndpointResources);
+ _service.publish(_resource);
+
+ _resource = make_shared< Resource > ();
+ _resource->set_path(api_path);
+ _resource->set_method_handler("GET", swaggerEndpointApi);
+ _service.publish(_resource);
+}
+
+
+void UmosapiService::createResource() {
+ basePath("/v2");
+ description("Umosapi rest api");
+ version("0.1");
+ title("UMOSAPI");
+ host("127.0.0.1:"+config["port"]);
+
+ swagger("/doc", config["swaggerui"], "/api");
+
+ atag("uobject", "Everything about your UObjec");
+
+ scheme("http");
+ scheme("https");
+
+ definition("UObject", "object");
+ propertie("id", "int64", "integer", "true");
+ propertie("value", "string", "object", "true");
+
+ definition("UObjectSended", "object");
+
+ set_path("/v2/ready");
+ set_method_handler("GET", is_ready);
+ produce("application/json");
+ publish();
+
+ set_path("/v2/{mcollection: .*}");
+ set_method_handler("GET", retrieveAll);
+ produce("application/json");
+ parameter("mcollection", "Name of the collection where the uobject are located");
+ set_error_handler(resource_error_handler);
+ set_method_handler("POST", addUObject);
+ consume("application/json");
+ parameter("mcollection", "Name of the collection where the uobject are located");
+ parameter("body", "UObject to add", "UObjectSended");
+ set_error_handler(resource_error_handler);
+ publish();
+
+ set_path("/v2/{mcollection: .*}/{oid: .*}");
+ set_method_handler("DELETE", deleteUObject);
+ produce("application/json");
+ parameter("mcollection", "Name of the collection where the uobject are located" );
+ parameter("oid", "MongoDB oid of the uobject");
+ set_error_handler(resource_error_handler);
+ publish();
+
+ set_path("/v2/{mcollection: .*}/{key: .*}/{value: .*}");
+ set_method_handler("GET", searchUObjectByKeyValue);
+ produce("application/json");
+ parameter("mcollection", "Name of the collection where the uobject are located");
+ parameter("key", "Key of uobject to search, ex: kill or total.kill");
+ parameter("value", "Value of uobject to search, ex: 42");
+ set_error_handler(resource_error_handler);
+ publish();
+
+ _service.set_error_handler( service_error_handler );
+}
+
+void UmosapiService::retrieveAll( const shared_ptr<Session> session ){
+ auto jsonObjects = json_object_new_array();
+ const auto& request = session->get_request( );
+ auto json_string = uobject::retrieveAll(request->get_path_parameter( "mcollection" ), jsonObjects);
+ json_object_put(jsonObjects);
+
+ session->close( OK, json_string, {
+ { "Content-Length", ::to_string(json_string.length()) },
+ { "Content-Type", "application/json" }
+ });
+}
+
+void UmosapiService::addUObject( const shared_ptr<Session> session ){
+ const auto request = session->get_request();
+
+ size_t content_length = request->get_header( "Content-Length", 0 );
+
+ session->fetch( content_length, [ request ]( const shared_ptr< Session > session, const Bytes & body )
+ {
+ auto jsonObject = json_object_new_object();
+ char bodyData[body.size()+1];
+ memset(bodyData, 0, sizeof(bodyData));
+ snprintf(bodyData, sizeof(bodyData), "%.*s", ( int ) body.size( ), body.data());
+ auto json_string = uobject::add(request->get_path_parameter("mcollection"), jsonObject, bodyData);
+ session->close( OK, json_string, {
+ { "Content-Length", ::to_string(json_string.length()) },
+ { "Content-Type", "application/json" }
+ });
+ json_object_put(jsonObject);
+ } );
}
-void UmosapiService::deleteUObject(const Rest::Request& request, Http::ResponseWriter response) {
+void UmosapiService::deleteUObject( const shared_ptr<Session> session ){
auto jsonObject = json_object_new_object();
+ const auto request = session->get_request();
- auto json_string = uobject::remove(request.param(":mcollection").as<string>(), request.param(":oid").as<string>(), jsonObject);
+ auto json_string = uobject::remove(request->get_path_parameter("mcollection"), request->get_path_parameter("oid"), jsonObject);
- response.send(Http::Code::Ok, json_string, MIME(Application, Json));
+ session->close( OK, json_string, {
+ { "Content-Length", ::to_string(json_string.length()) },
+ { "Content-Type", "application/json" }
+ });
json_object_put(jsonObject);
}
-void UmosapiService::searchUObjectByKeyValue(const Rest::Request& request, Http::ResponseWriter response) {
+void UmosapiService::searchUObjectByKeyValue( const shared_ptr<Session> session ){
auto jsonObject = json_object_new_array();
+ const auto request = session->get_request();
- auto json_string = uobject::searchKeyValue(request.param(":mcollection").as<string>(), request.param(":key").as<string>(), request.param(":value").as<string>(), jsonObject);
+ auto json_string = uobject::searchKeyValue(request->get_path_parameter("mcollection"), request->get_path_parameter("key"), request->get_path_parameter("value"), jsonObject);
- response.send(Http::Code::Ok, json_string, MIME(Application, Json));
+ session->close( OK, json_string, {
+ { "Content-Length", ::to_string(json_string.length()) },
+ { "Content-Type", "application/json" }
+ });
json_object_put(jsonObject);
}
+
+void UmosapiService::swaggerEndpoint( const shared_ptr<Session> session ){
+ const auto request = session->get_request();
+
+ ifstream stream(config["swaggerui"] + "/index.html", ifstream::in );
+
+ if ( stream.is_open() ) {
+ const string body = string( istreambuf_iterator< char >(stream), istreambuf_iterator< char>());
+
+ const multimap< string, string> headers {
+ { "Content-Type", "text/html" },
+ { "Content-Length", ::to_string( body.length() ) }
+ };
+ session->close(OK, body, headers);
+ } else {
+ session->close( NOT_FOUND );
+ }
+}
+
+void UmosapiService::swaggerEndpointResources( const shared_ptr< Session > session )
+{
+ const auto request = session->get_request( );
+ const string filename = request->get_path_parameter( "filename" );
+
+ ifstream stream( config["swaggerui"] + "/" + filename, ifstream::in );
+
+ if ( stream.is_open( ) )
+ {
+ const string body = string( istreambuf_iterator< char >( stream ), istreambuf_iterator< char >( ) );
+
+ const multimap< string, string > headers
+ {
+ { "Content-Length", ::to_string( body.length( ) ) }
+ };
+
+ session->close( OK, body, headers );
+ }
+ else
+ {
+ session->close( NOT_FOUND );
+ }
+}
+
+void UmosapiService::swaggerEndpointApi( const shared_ptr< Session > session )
+{
+ const auto request = session->get_request( );
+ const string filename = request->get_path_parameter( "filename" );
+ const string path = request->get_path();
+
+ ifstream stream( config["swaggerui"] + "/swagger.json", ifstream::in );
+
+ if ( stream.is_open( ) )
+ {
+ const string body = string( istreambuf_iterator< char >( stream ), istreambuf_iterator< char >( ) );
+
+ const multimap< string, string > headers
+ {
+ { "Content-Type", "application/json" },
+ { "Content-Length", ::to_string( body.length( ) ) }
+ };
+
+ session->close( OK, body, headers );
+ }
+ else
+ {
+ session->close( NOT_FOUND );
+ }
+}
diff --git a/api/umosapi.h b/api/umosapi.h
index 20c6d7b..a1765d7 100644
--- a/api/umosapi.h
+++ b/api/umosapi.h
@@ -1,37 +1,108 @@
#ifndef UmosapiService_H_
#define UmosapiService_H_
-#include <pistache/http.h>
-#include <pistache/description.h>
-#include <pistache/endpoint.h>
+//#include <pistache/http.h>
+//#include <pistache/description.h>
+//#include <pistache/endpoint.h>
-#include <pistache/serializer/rapidjson.h>
+#include <restbed>
-using namespace Pistache;
+//#include <pistache/serializer/rapidjson.h>
+
+#include <nlohmann/json.hpp>
+
+using namespace restbed;
+using namespace std;
+
+using json = nlohmann::json;
+
+struct tag {
+ std::string name;
+ std::string description;
+};
+
+struct Propertie {
+
+ std::string name;
+ std::string format;
+ std::string type;
+ std::string required;
+};
+
+struct Definition {
+
+ std::string name;
+ std::string type;
+ std::vector<Propertie> props;
+};
+
+struct Definitions {
+ std::vector<Definition> defs;
+};
+
+struct HttpWord {
+ std::string name;
+};
+
+struct Path {
+ std::string name;
+ std::vector<HttpWord> words;
+};
+
+struct Paths {
+ std::vector<Path> paths;
+};
class UmosapiService {
public:
- UmosapiService(Address addr);
+ UmosapiService();
virtual ~UmosapiService() {};
- void init(size_t thr);
+ void init();
- void start(std::string swaggerui);
+ void start(int, int);
+ Service _service;
+ json _swagger;
+ vector<tag> _tags;
private:
- void createDescription();
-
- void retrieveAll(const Rest::Request& request, Http::ResponseWriter response);
+ void desc(std::string route, std::string http_word, const std::function< void ( const std::shared_ptr< Session > ) >& callback, const std::function< void(int, const std::exception&, std::shared_ptr<restbed::Session>) >& error_callback, tag tags[]);
+ void createResource();
- void addUObject(const Rest::Request& request, Http::ResponseWriter response);
+ static void retrieveAll( const shared_ptr<Session> session );
+ static void addUObject( const shared_ptr<Session> session );
+ static void deleteUObject( const shared_ptr<Session> session );
+ static void searchUObjectByKeyValue( const shared_ptr<Session> session );
+ static void swaggerEndpoint( const shared_ptr<Session> session );
+ static void swaggerEndpointResources( const shared_ptr<Session> session );
+ static void swaggerEndpointApi( const shared_ptr<Session> session );
- void deleteUObject(const Rest::Request& request, Http::ResponseWriter response);
+ shared_ptr< Resource> _resource;
+ Definition _definition;
+ Definitions _definitions;
+ Path _path;
+ Paths _paths;
+ void set_path();
+ void set_path(std::string route);
+ void set_method_handler(std::string http_word, const std::function< void ( const std::shared_ptr< Session > ) >& callback);
+ void set_error_handler(const std::function< void(int, const std::exception&, std::shared_ptr<restbed::Session>) >& error_callback);
+ void produce(std::string);
+ void consume(std::string);
+ void parameter(std::string, std::string, std::string);
+ void response(std::string err_code, std::string description, std::string schema);
+ void publish();
+ void basePath(std::string basePath);
+ void description(std::string description);
+ void title(std::string title);
+ void version(std::string version);
+ void host(std::string host);
+ void atag(std::string name, std::string description);
+ void scheme(std::string scheme);
- void searchUObjectByKeyValue(const Rest::Request& request, Http::ResponseWriter response);
+ void definition(std::string name, std::string type);
+ void propertie(std::string name, std::string format, std::string type, std::string required);
+ void swagger(std::string ui_path, std::string swagger_dir, std::string api_path);
- std::shared_ptr<Http::Endpoint> httpEndpoint;
- Rest::Description desc;
- Rest::Router router;
};
#endif
diff --git a/db/uobject.cpp b/db/uobject.cpp
index 6401307..25b13e6 100644
--- a/db/uobject.cpp
+++ b/db/uobject.cpp
@@ -103,8 +103,10 @@ std::string uobject::remove(std::string collection, std::string oid, struct json
json_object_object_add(json_id, "$oid", json_oid);
json_object_object_add(jsonObject, "_id", json_id);
json_object_object_add(jsonObject, "datas", {});
+ return json_object_to_json_string_ext(jsonObject, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
+ } else {
+ return "0";
}
- return json_object_to_json_string_ext(jsonObject, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
}
std::string uobject::searchKeyValue(std::string collection, std::string key, std::string value, struct json_object* jsonArray) {
diff --git a/main.cpp b/main.cpp
index c0cdb0d..05a6232 100644
--- a/main.cpp
+++ b/main.cpp
@@ -8,10 +8,11 @@
#include "config.h"
#include "api/umosapi.h"
+#include "service.hpp"
+
std::map<std::string, std::string> config;
using namespace std;
-using namespace Pistache;
int main(int argc, char *argv[]) {
@@ -26,16 +27,16 @@ int main(int argc, char *argv[]) {
config_path.append("/.config/umosapi/config.txt");
bool showHelp = false;
- int config_port = 9080;
+ config["port"] = "9080";
int thr = 2;
auto cli = clara::detail::Help(showHelp)
| clara::detail::Opt( config_path, "config" )["-c"]["--config"]("Config file path. Default `~/.config/umosapi/config.txt`.")
- | clara::detail::Opt( config_port, "port" )["-p"]["--port"]("Port to listen. Default: `9080`.")
+ | clara::detail::Opt( config["port"], "port" )["-p"]["--port"]("Port to listen. Default: `9080`.")
| clara::detail::Opt( thr, "treads" )["-t"]["--threads"]("Number of threads. Default: `2`.");
auto result = cli.parse( clara::detail::Args( argc, argv ) );
if( !result )
{
- std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
+ std::cerr << "ERROR: Error in command line: " << result.errorMessage() << std::endl;
std::cerr << cli << std::endl;
exit(1);
}
@@ -45,27 +46,35 @@ int main(int argc, char *argv[]) {
exit(1);
}
- Address addr(Ipv4::any(), Port(config_port));
+ //Address addr(Ipv4::any(), Port(config["port"]));
- cout << "Using " << hardware_concurrency() << " cores";
+ cout << "INFO: Using " << std::thread::hardware_concurrency() << " cores";
cout << " - " << thr << " threads" << endl;
- cout << "Listen on 0.0.0.0:" << config_port << endl;
+ cout << "INFO: Listen on 0.0.0.0:" << config["port"] << endl;
- cout << "Using config file '" << config_path << "'" << endl;
+ cout << "INFO: Using config file '" << config_path << "'" << endl;
if (!std::filesystem::exists(config_path)) {
- cout << "Error fatal : config file '" << config_path << "' not found" << endl;
- cout << "config.txt is search here: ~/.config/umosapi/config.txt" << endl;
+ cout << "ERROR: Error fatal : config file '" << config_path << "' not found" << endl;
+ cout << "ERROR: config.txt is search here: ~/.config/umosapi/config.txt" << endl;
exit (EXIT_FAILURE);
}
load_config(config_path);
- cout << "Using swaggerui " << config["swaggerui"] << " path" << endl;
- cout << "Using mongoURI " << config["mongoURI"] << endl;
+ //cout << "Using swaggerui " << config["swaggerui"] << " path" << endl;
+ cout << "INFO: No support for swagger for the moment" << endl;
+ cout << "INFO: Using mongoURI " << config["mongoURI"] << endl;
+ /*
UmosapiService umosapi(addr);
umosapi.init(thr);
umosapi.start(config["swaggerui"]);
+ */
+
+ UmosapiService umosapi;
+ umosapi.init();
+ umosapi.start(std::stoi(config["port"]), thr);
+
}