diff options
-rw-r--r-- | CMakeLists.txt | 33 | ||||
-rw-r--r-- | README.md | 16 | ||||
-rw-r--r-- | api/umosapi.cpp | 480 | ||||
-rw-r--r-- | api/umosapi.h | 105 | ||||
-rw-r--r-- | db/uobject.cpp | 4 | ||||
-rw-r--r-- | main.cpp | 33 |
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}) @@ -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) { @@ -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); + } |