diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-02-21 07:27:00 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-02-21 07:27:00 +0100 |
| commit | d12498504c279a0a85bbfb024f7903e34dbe07db (patch) | |
| tree | 0df9f3f8bf27470ac211a57bb8e44be0aa2f6138 /src/httpservice.h | |
| parent | 27637ab117d8738236f6ab155300ff6e79e4843b (diff) | |
broken img calc; change dir struct
Diffstat (limited to 'src/httpservice.h')
| -rw-r--r-- | src/httpservice.h | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/httpservice.h b/src/httpservice.h new file mode 100644 index 0000000..a6c3f76 --- /dev/null +++ b/src/httpservice.h @@ -0,0 +1,203 @@ +#pragma once + +#include <pistache/description.h> +#include <pistache/endpoint.h> +#include <pistache/http.h> + +#include <pistache/serializer/rapidjson.h> + +#include "imagealgos.h" + +using namespace Pistache; + +extern uint8_t pgm_image[64 + img_width * img_height * sizeof(uint8_t)]; +extern size_t pgm_image_size; +extern std::mutex pgm_image_mtx; + +class HttpService +{ +public: + HttpService(Address addr) + : httpEndpoint(std::make_shared<Http::Endpoint>(addr)) + , desc("Banking API", "0.1") + { } + + void init(size_t thr = 2) + { + auto opts = Http::Endpoint::options() + .threads(static_cast<int>(thr)); + httpEndpoint->init(opts); + createDescription(); + } + + void start() + { + router.initFromDescription(desc); + + Rest::Swagger swagger(desc); + swagger + .uiPath("/doc") + .uiDirectory("/home/user/swagger-ui/dist") + .apiPath("/banker-api.json") + .serializer(&Rest::Serializer::rapidJson) + .install(router); + + httpEndpoint->setHandler(router.handler()); + httpEndpoint->serve(); + } + +private: + void createDescription() + { + desc + .info() + .license("Apache", "http://www.apache.org/licenses/LICENSE-2.0"); + + auto backendErrorResponse = desc.response(Http::Code::Internal_Server_Error, "An error occured with the backend"); + + 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, "Response to the /ready call") + // .hide(); + + auto versionPath = desc.path("/v1"); + + auto sensorPath = versionPath.path("/sensor"); + + sensorPath + .route(desc.get("/image")) + .bind(&HttpService::image, this) + .produces(MIME(Image, Png)) + .response(Http::Code::Ok, "Image from sensor"); + + // tmp + sensorPath + .route(desc.get("/image2")) + .bind(&HttpService::image, this) + .produces(MIME(Image, Png)) + .response(Http::Code::Ok, "Image from sensor"); + + sensorPath + .route(desc.get("/params"), "Retrive sensor parameters") + .bind(&HttpService::get_sensorParams, this) + .produces(MIME(Application, Plain)) + .response(Http::Code::Ok, "Parameter value") + .response(backendErrorResponse);; + + sensorPath + .route(desc.get("/:param"), "Retrive sensor parameter") + .bind(&HttpService::get_sensorParam, this) + .produces(MIME(Application, Json)) + .parameter<Rest::Type::String>("param", "The name of the parameter to retrieve") + .response(Http::Code::Ok, "Parameter value") + .response(backendErrorResponse);; + + sensorPath + .route(desc.post("/:param"), "Set sensor parameter") + .bind(&HttpService::set_sensorParam, this) + .produces(MIME(Application, Plain)) + .consumes(MIME(Application, Plain)) + .response(Http::Code::Ok, "Setting parameter result"); + + + auto accountsPath = versionPath.path("/accounts"); + + accountsPath + .route(desc.get("/all")) + .bind(&HttpService::retrieveAllAccounts, this) + .produces(MIME(Application, Json), MIME(Application, Xml)) + .response(Http::Code::Ok, "The list of all account"); + + accountsPath + .route(desc.get("/:name"), "Retrieve an account") + .bind(&HttpService::retrieveAccount, this) + .produces(MIME(Application, Json)) + .parameter<Rest::Type::String>("name", "The name of the account to retrieve") + .response(Http::Code::Ok, "The requested account") + .response(backendErrorResponse); + + accountsPath + .route(desc.post("/:name"), "Create an account") + .bind(&HttpService::createAccount, this) + .produces(MIME(Application, Json)) + .consumes(MIME(Application, Json)) + .parameter<Rest::Type::String>("name", "The name of the account to create") + .response(Http::Code::Ok, "The initial state of the account") + .response(backendErrorResponse); + auto accountPath = accountsPath.path("/:name"); + accountPath.parameter<Rest::Type::String>("name", "The name of the account to operate on"); + + accountPath + .route(desc.post("/budget"), "Add budget to the account") + .bind(&HttpService::creditAccount, this) + .produces(MIME(Application, Json)) + .response(Http::Code::Ok, "Budget has been added to the account") + .response(backendErrorResponse); + } + + void retrieveAllAccounts(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, + "No Account", + { Http::Mime::Type::Text, Http::Mime::Subtype::Plain} ); + } + + void retrieveAccount(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, "The bank is closed, come back later"); + } + + void createAccount(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, "The bank is closed, come back later"); + } + + void creditAccount(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, "The bank is closed, come back later"); + } + + void image(const Rest::Request&, Http::ResponseWriter response) + { + // FIXME: image should be valid + std::lock_guard<std::mutex> lg(pgm_image_mtx); + // char data[pgm_image_size]; + // memcpy(data, pgm_image, pgm_image_size); + std::cout << "send bytes: " << pgm_image_size << std::endl; + + auto res = response.send(Http::Code::Ok, + (const char*)pgm_image, pgm_image_size, + Http::Mime::MediaType { "image/pgm" }); + // { Http::Mime::Type::Image, Http::Mime::Subtype::Png }); + + res.then([](ssize_t bytes) + { std::cout << bytes << " bytes have been sent\n"; }, + Async::NoExcept); + } + + void get_sensorParam(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, std::to_string(123)); + } + + void get_sensorParams(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, std::to_string(123)); + } + + void set_sensorParam(const Rest::Request&, Http::ResponseWriter response) + { + response.send(Http::Code::Ok, std::to_string(123)); + } + + std::shared_ptr<Http::Endpoint> httpEndpoint; + Rest::Description desc; + Rest::Router router; +}; |
