#include "ApiController.h" #include #include #include #include #include #include #include using drogon::HttpResponse; using drogon::HttpResponsePtr; using drogon::k503ServiceUnavailable; namespace { HttpResponsePtr jsonResponse(Json::Value body, drogon::HttpStatusCode status = drogon::k200OK) { auto response = HttpResponse::newHttpJsonResponse(std::move(body)); response->setStatusCode(status); return response; } Json::Value mysqlReadyBody(bool ready) { Json::Value body; body["status"] = ready ? "ready" : "not_ready"; body["dependencies"]["mysql"] = ready; return body; } std::string openApiSpecPath() { const auto &config = drogon::app().getCustomConfig()["openapi"]; return config.get("spec_path", "build/openapi/visione.openapi.json").asString(); } } void ApiController::health( const drogon::HttpRequestPtr &, std::function &&callback) { Json::Value body; body["status"] = "ok"; body["service"] = "visione-backend"; callback(jsonResponse(std::move(body))); } void ApiController::ready( const drogon::HttpRequestPtr &, std::function &&callback) { auto responseCallback = std::make_shared< std::function>(std::move(callback)); try { auto dbClient = drogon::app().getDbClient(); dbClient->execSqlAsync( "SELECT 1", [responseCallback](const drogon::orm::Result &) { (*responseCallback)(jsonResponse(mysqlReadyBody(true))); }, [responseCallback](const drogon::orm::DrogonDbException &error) { auto body = mysqlReadyBody(false); body["errors"]["mysql"] = error.base().what(); (*responseCallback)( jsonResponse(std::move(body), k503ServiceUnavailable)); }); } catch (const std::exception &error) { auto body = mysqlReadyBody(false); body["errors"]["mysql"] = error.what(); (*responseCallback)( jsonResponse(std::move(body), k503ServiceUnavailable)); } } void ApiController::openApi( const drogon::HttpRequestPtr &, std::function &&callback) { const auto path = openApiSpecPath(); std::ifstream file(path, std::ios::binary); if (!file) { Json::Value body; body["error"] = "openapi_spec_not_generated"; body["message"] = "Run cmake --build build or the openapi target."; body["path"] = path; callback(jsonResponse(std::move(body), drogon::k404NotFound)); return; } std::ostringstream buffer; buffer << file.rdbuf(); auto response = HttpResponse::newHttpResponse(); response->setStatusCode(drogon::k200OK); response->setContentTypeCode(drogon::CT_APPLICATION_JSON); response->setBody(buffer.str()); callback(response); } void ApiController::docs( const drogon::HttpRequestPtr &, std::function &&callback) { static const std::string html = R"( Visione API Docs
)"; auto response = HttpResponse::newHttpResponse(); response->setStatusCode(drogon::k200OK); response->setContentTypeCode(drogon::CT_TEXT_HTML); response->setBody(html); callback(response); }