From 87b534f7bb9ff8cb66b17526fc9aa021b6c72fca Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sat, 15 Aug 2026 00:22:49 +0300 Subject: [PATCH 01/22] feat(chaotic-openapi): pass RequestContext to generated View::Handle View::Handle now receives server::request::RequestContext as the third parameter, giving handlers access to per-request data (e.g. user auth info set by the auth middleware). The dispatcher falls back to the legacy two-argument Handle via the ViewHasHandleWithContext concept, so existing hand-written views keep working unchanged. --- .../back/cpp/handler/templates/view.cpp.jinja | 5 ++++- .../back/cpp/handler/templates/view.hpp.jinja | 2 +- .../chaotic/openapi/server/handler_base.hpp | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja index 799e79a5b343..e6d561593ea9 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja @@ -2,7 +2,10 @@ namespace {{ spec.cpp_namespace }}::{{ op.cpp_namespace() }} { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + {{ userver }}::server::request::RequestContext& /*context*/) { // Handle request using dependencies from Deps (clients, caches, configs, databases...) return {}; } diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja index e3dee8e446d7..b70817e0eef1 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja @@ -19,7 +19,7 @@ class View final { public: using Deps = {{ userver }}::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, {{ userver }}::server::request::RequestContext& context); /* Uncomment, if you want to define a custom logging for request/response body. * E.g. you want to log several fields, but omit the others (secrets, etc.). diff --git a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp index f365ad76607a..364955aa53c1 100644 --- a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp +++ b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp @@ -55,6 +55,14 @@ concept ViewHasGetResponseForLogging = } -> std::convertible_to; }; +template +concept ViewHasHandleWithContext = + requires(Request&& r, Deps&& d, USERVER_NAMESPACE::server::request::RequestContext& ctx) { + { + V::Handle(std::move(r), std::move(d), ctx) + } -> std::convertible_to; + }; + } // namespace impl /// @brief Base class for generated HTTP handlers. @@ -165,7 +173,13 @@ class BaseHandler final : public USERVER_NAMESPACE::server::handlers::HttpHandle USERVER_NAMESPACE::server::request::RequestContext& context ) const { auto deps = factories_.Get().template Make(); - auto response = View::Handle(std::move(request), std::move(deps)); + auto response = [&] { + if constexpr (impl::ViewHasHandleWithContext) { + return View::Handle(std::move(request), std::move(deps), context); + } else { + return View::Handle(std::move(request), std::move(deps)); + } + }(); auto serialized = SerializeResponse(response, http_request); if constexpr (impl::ViewHasGetResponseForLogging) { context.SetData< From 97ba9b403fac23ec78647bd8f13d82c6bd14d76b Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sat, 15 Aug 2026 00:23:02 +0300 Subject: [PATCH 02/22] chore(chaotic-openapi): update golden tests and views for View::Handle signature Regenerate golden output with the three-argument Handle and migrate hand-written views in integration tests and the chaotic_openapi_service sample. The headersGet view demonstrates reading per-request context data (x-user-id) set by an auth checker. --- .../handlers/handlers/test/testme/post/view.cpp | 5 ++++- .../handlers/handlers/test/testme/post/view.hpp | 2 +- .../src/handlers/simple/formpost/view.cpp | 8 +++++++- .../src/handlers/simple/greetget/view.cpp | 8 +++++++- .../src/handlers/simple/headersget/view.cpp | 12 +++++++++++- .../src/handlers/simple/multipartpost/view.cpp | 8 +++++++- .../src/handlers/simple/multipost/view.cpp | 8 +++++++- .../src/handlers/simple/octetget/view.cpp | 8 +++++++- .../src/handlers/simple/secretget/view.cpp | 8 +++++++- .../handlers/insecure/insecuresecretpost/view.cpp | 6 +++++- 10 files changed, 63 insertions(+), 10 deletions(-) diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp index 9a66d6a1a171..a3e551ff0bec 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp @@ -2,7 +2,10 @@ namespace handlers::test::testme::post { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { +Response View::Handle( +Request&& /*request*/, +Deps&& /*deps*/, +USERVER_NAMESPACE::server::request::RequestContext& /*context*/) { // Handle request using dependencies from Deps (clients, caches, configs, databases...) return {}; } diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp index 0e8b698cdc86..2d3080eb79d3 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp @@ -17,7 +17,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; -static Response Handle(Request&& request, Deps&& deps); +static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); /* Uncomment, if you want to define a custom logging for request/response body. * E.g. you want to log several fields, but omit the others (secrets, etc.). diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp index b3df40619e97..c1542c3b452b 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::formpost { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp index 36fb1495652a..74b0dce7356f 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::greetget { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetResponseForLogging( const Response& /*response*/, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp index b00977a09d0c..00a457d7ff5b 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp @@ -2,7 +2,17 @@ namespace handlers::simple::headersget { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& context +) { + Response200 response; + const auto* user_id = context.GetDataOptional("x-user-id"); + response.X_String = user_id ? *user_id : ""; + response.body = response.X_String; + return response; +} std::string View::GetResponseForLogging( const Response& /*response*/, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp index 4610810ed9da..d99e44ccaafd 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::multipartpost { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp index bd2ced69fa03..483ed5207c5f 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::multipost { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetResponseForLogging( const Response& /*response*/, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp index b121f0a03227..1e20af8c5673 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::octetget { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp index 3918c1c2155f..ecd92dd53f92 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp @@ -2,7 +2,13 @@ namespace handlers::simple::secretget { -Response View::Handle(Request&& /*request*/, Deps&& /*deps*/) { return {}; } +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { + return {}; +} std::string View::GetResponseForLogging( const Response& /*response*/, diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp index 2e0afa40a122..026db6e884c6 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp +++ b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp @@ -7,7 +7,11 @@ namespace handlers::insecure::insecuresecretpost { /// [view-impl] -Response View::Handle(Request&& request, Deps&& /*deps*/) { +Response View::Handle( + Request&& request, + Deps&& /*deps*/, + USERVER_NAMESPACE::server::request::RequestContext& /*context*/ +) { return Response200{.body = {.greeting = fmt::format("Hello, {}!", request.name)}}; } /// [view-impl] From 92174568c162cedf68a4ed85cf3f66cef1398dec Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sat, 15 Aug 2026 00:23:06 +0300 Subject: [PATCH 03/22] docs(chaotic-openapi): document View::Handle RequestContext contract --- chaotic-openapi/AGENTS.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/chaotic-openapi/AGENTS.md b/chaotic-openapi/AGENTS.md index 239ff760ef63..4733d0865e03 100644 --- a/chaotic-openapi/AGENTS.md +++ b/chaotic-openapi/AGENTS.md @@ -32,6 +32,21 @@ that generates the `PEERDIR`/include lists for `ya.make` files. It is never call `main.py`. +## View contract + +For each operation the generator emits a `View` with a hand-written entry point: + +```cpp +static Response Handle(Request&& request, Deps&& deps, userver::server::request::RequestContext& context); +``` + +The third parameter gives the handler access to the per-request context (e.g. data set by +the auth middleware via `server::auth::GetUserAuthInfo(context)` / `context.SetData`). +The runtime dispatcher (`BaseHandler` in `include/userver/chaotic/openapi/server/handler_base.hpp`) +calls the 3-argument overload when present and falls back to the legacy 2-argument +`Handle(Request&&, Deps&&)` otherwise (`impl::ViewHasHandleWithContext`). + + # Tests Tests are implemented at multiple levels: From 3658edaa0ca092cfb6447600d178e21a3cb07ef4 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sat, 15 Aug 2026 01:11:31 +0300 Subject: [PATCH 04/22] fix(chaotic-openapi): fix int_tests --- .../integration_tests/src/handlers/simple/formpost/view.hpp | 2 +- .../integration_tests/src/handlers/simple/greetget/view.hpp | 2 +- .../integration_tests/src/handlers/simple/headersget/view.hpp | 2 +- .../src/handlers/simple/multipartpost/view.hpp | 2 +- .../integration_tests/src/handlers/simple/multipost/view.hpp | 2 +- .../integration_tests/src/handlers/simple/octetget/view.hpp | 2 +- .../integration_tests/src/handlers/simple/secretget/view.hpp | 2 +- .../src/handlers/insecure/insecuresecretpost/view.hpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp index ffa447675964..fb2f7805b9ad 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp index 25b600c8ae14..2a810e55baae 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetResponseForLogging( const Response& response, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp index 7ed98bd5ae34..72b74ccd4e2f 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetResponseForLogging( const Response& response, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp index 96991cc475ee..bd519d7af80a 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp index d4632407af85..abea82389cc7 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetResponseForLogging( const Response& response, diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp index fa5a9258cbe4..6eb586609e4e 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp index 3b736082a5ae..faebe70aa81a 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetResponseForLogging( const Response& response, diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp index 9959bcb23c84..42c1698cc9b8 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp +++ b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp @@ -15,7 +15,7 @@ class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - static Response Handle(Request&& request, Deps&& deps); + static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); static std::string GetResponseForLogging( const Response& response, From 761a6e648fb766556a6b3c52c33bff9261d3152c Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sun, 16 Aug 2026 23:15:15 +0300 Subject: [PATCH 05/22] refactor(chaotic-openapi): require RequestContext in View::Handle --- chaotic-openapi/AGENTS.md | 12 +++++---- .../back/cpp/handler/templates/view.cpp.jinja | 4 +-- .../back/cpp/handler/templates/view.hpp.jinja | 5 ++-- .../chaotic/openapi/server/handler_base.hpp | 26 ++++++++----------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/chaotic-openapi/AGENTS.md b/chaotic-openapi/AGENTS.md index 4733d0865e03..7526cf754f8f 100644 --- a/chaotic-openapi/AGENTS.md +++ b/chaotic-openapi/AGENTS.md @@ -37,14 +37,16 @@ that generates the `PEERDIR`/include lists for `ya.make` files. It is never call For each operation the generator emits a `View` with a hand-written entry point: ```cpp -static Response Handle(Request&& request, Deps&& deps, userver::server::request::RequestContext& context); +using RequestContext = userver::server::request::RequestContext; + +static Response Handle(Request&& request, Deps&& deps, RequestContext& context); ``` The third parameter gives the handler access to the per-request context (e.g. data set by -the auth middleware via `server::auth::GetUserAuthInfo(context)` / `context.SetData`). -The runtime dispatcher (`BaseHandler` in `include/userver/chaotic/openapi/server/handler_base.hpp`) -calls the 3-argument overload when present and falls back to the legacy 2-argument -`Handle(Request&&, Deps&&)` otherwise (`impl::ViewHasHandleWithContext`). +the auth middleware via `userver::server::auth::GetUserAuthInfo(context)` / `context.SetData`). +It is **always** passed by the runtime dispatcher (`BaseHandler` in +`include/userver/chaotic/openapi/server/handler_base.hpp`) — the legacy 2-argument +`Handle(Request&&, Deps&&)` is not supported. # Tests diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja index e6d561593ea9..bf3382af0ef3 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.cpp.jinja @@ -5,7 +5,7 @@ namespace {{ spec.cpp_namespace }}::{{ op.cpp_namespace() }} { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - {{ userver }}::server::request::RequestContext& /*context*/) { + RequestContext& /*context*/) { // Handle request using dependencies from Deps (clients, caches, configs, databases...) return {}; } @@ -35,7 +35,7 @@ std::string View::GetRequestBodyForLogging(const std::string& body) { std::string View::GetResponseForLogging( const Response& response, const std::string& serialized_response, - {{ userver }}::server::request::RequestContext& context) { + RequestContext& context) { (void)response; (void)serialized_response; (void)context; diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja index b70817e0eef1..d09e92476b55 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/view.hpp.jinja @@ -18,8 +18,9 @@ struct HandlerTag; class View final { public: using Deps = {{ userver }}::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = {{ userver }}::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, {{ userver }}::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); /* Uncomment, if you want to define a custom logging for request/response body. * E.g. you want to log several fields, but omit the others (secrets, etc.). @@ -40,7 +41,7 @@ public: static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - {{ userver }}::server::request::RequestContext& context); + RequestContext& context); */ }; diff --git a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp index 364955aa53c1..a9f7a5cc411f 100644 --- a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp +++ b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp @@ -55,14 +55,6 @@ concept ViewHasGetResponseForLogging = } -> std::convertible_to; }; -template -concept ViewHasHandleWithContext = - requires(Request&& r, Deps&& d, USERVER_NAMESPACE::server::request::RequestContext& ctx) { - { - V::Handle(std::move(r), std::move(d), ctx) - } -> std::convertible_to; - }; - } // namespace impl /// @brief Base class for generated HTTP handlers. @@ -150,6 +142,16 @@ class BaseHandler final : public USERVER_NAMESPACE::server::handlers::HttpHandle "View::GetInvalidRequestBodyForLogging requires " "View::GetRequestBodyForLogging(const formats::json::Value&)." ); + static_assert( + requires(Request&& r, Deps&& d, USERVER_NAMESPACE::server::request::RequestContext& ctx) { + { + View::Handle(std::move(r), std::move(d), ctx) + } -> std::convertible_to; + }, + "View::Handle must accept server::request::RequestContext as the third parameter: " + "static Response Handle(Request&& request, Deps&& deps, RequestContext& context). " + "The legacy 2-argument Handle(Request&&, Deps&&) is no longer supported." + ); using Factories = chaotic::openapi::server::dependencies::Factories; using FactoriesContainer = USERVER_NAMESPACE::components::Container; @@ -173,13 +175,7 @@ class BaseHandler final : public USERVER_NAMESPACE::server::handlers::HttpHandle USERVER_NAMESPACE::server::request::RequestContext& context ) const { auto deps = factories_.Get().template Make(); - auto response = [&] { - if constexpr (impl::ViewHasHandleWithContext) { - return View::Handle(std::move(request), std::move(deps), context); - } else { - return View::Handle(std::move(request), std::move(deps)); - } - }(); + auto response = View::Handle(std::move(request), std::move(deps), context); auto serialized = SerializeResponse(response, http_request); if constexpr (impl::ViewHasGetResponseForLogging) { context.SetData< From e4f4baea3286abc53469dd7d4b869a308c6fa1b9 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sun, 16 Aug 2026 23:15:19 +0300 Subject: [PATCH 06/22] chore(chaotic-openapi): update views for RequestContext alias --- .../output/handlers/handlers/test/testme/post/view.cpp | 4 ++-- .../output/handlers/handlers/test/testme/post/view.hpp | 5 +++-- .../integration_tests/src/handlers/simple/formpost/view.cpp | 4 ++-- .../integration_tests/src/handlers/simple/formpost/view.hpp | 5 +++-- .../integration_tests/src/handlers/simple/greetget/view.cpp | 4 ++-- .../integration_tests/src/handlers/simple/greetget/view.hpp | 5 +++-- .../src/handlers/simple/headersget/view.cpp | 4 ++-- .../src/handlers/simple/headersget/view.hpp | 5 +++-- .../src/handlers/simple/multipartpost/view.cpp | 4 ++-- .../src/handlers/simple/multipartpost/view.hpp | 5 +++-- .../integration_tests/src/handlers/simple/multipost/view.cpp | 4 ++-- .../integration_tests/src/handlers/simple/multipost/view.hpp | 5 +++-- .../integration_tests/src/handlers/simple/octetget/view.cpp | 4 ++-- .../integration_tests/src/handlers/simple/octetget/view.hpp | 5 +++-- .../integration_tests/src/handlers/simple/secretget/view.cpp | 4 ++-- .../integration_tests/src/handlers/simple/secretget/view.hpp | 5 +++-- .../src/handlers/insecure/insecuresecretpost/view.cpp | 4 ++-- .../src/handlers/insecure/insecuresecretpost/view.hpp | 5 +++-- 18 files changed, 45 insertions(+), 36 deletions(-) diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp index a3e551ff0bec..6ba3fe227cf5 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp @@ -5,7 +5,7 @@ namespace handlers::test::testme::post { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, -USERVER_NAMESPACE::server::request::RequestContext& /*context*/) { +RequestContext& /*context*/) { // Handle request using dependencies from Deps (clients, caches, configs, databases...) return {}; } @@ -26,7 +26,7 @@ return {}; std::string View::GetResponseForLogging( const Response& response, const std::string& serialized_response, -USERVER_NAMESPACE::server::request::RequestContext& context) { +RequestContext& context) { (void)response; (void)serialized_response; (void)context; diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp index 2d3080eb79d3..a258edcad9c1 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp @@ -16,8 +16,9 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; +using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; -static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); +static Response Handle(Request&& request, Deps&& deps, RequestContext& context); /* Uncomment, if you want to define a custom logging for request/response body. * E.g. you want to log several fields, but omit the others (secrets, etc.). @@ -32,7 +33,7 @@ const USERVER_NAMESPACE::server::http::HttpRequest& request); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, -USERVER_NAMESPACE::server::request::RequestContext& context); +RequestContext& context); */ }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp index c1542c3b452b..c84a8b8228d6 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::formpost { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -15,7 +15,7 @@ std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp index fb2f7805b9ad..894547cb4559 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/formpost/view.hpp @@ -14,15 +14,16 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp index 74b0dce7356f..fab4cd61053a 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::greetget { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -13,7 +13,7 @@ Response View::Handle( std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp index 2a810e55baae..488edbe6c992 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/greetget/view.hpp @@ -14,13 +14,14 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp index 00a457d7ff5b..333bd789b61e 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::headersget { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ) { Response200 response; const auto* user_id = context.GetDataOptional("x-user-id"); @@ -17,7 +17,7 @@ Response View::Handle( std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp index 72b74ccd4e2f..710d491c2dea 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.hpp @@ -14,13 +14,14 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp index d99e44ccaafd..e1ee3a64b5ef 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::multipartpost { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -15,7 +15,7 @@ std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp index bd519d7af80a..ac71a51e6c81 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipartpost/view.hpp @@ -14,15 +14,16 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp index 483ed5207c5f..3808770c3487 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::multipost { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -13,7 +13,7 @@ Response View::Handle( std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp index abea82389cc7..23b03d2fac85 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/multipost/view.hpp @@ -14,13 +14,14 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp index 1e20af8c5673..5ccfb1f648af 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::octetget { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -15,7 +15,7 @@ std::string View::GetRequestBodyForLogging(const std::string& /*body*/) { return std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp index 6eb586609e4e..333cbdf6ee7f 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/octetget/view.hpp @@ -14,15 +14,16 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetRequestBodyForLogging(const std::string& body); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp index ecd92dd53f92..5c6a03d1bc0d 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.cpp @@ -5,7 +5,7 @@ namespace handlers::simple::secretget { Response View::Handle( Request&& /*request*/, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } @@ -13,7 +13,7 @@ Response View::Handle( std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp index faebe70aa81a..cf60e3a37159 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/secretget/view.hpp @@ -14,13 +14,14 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp index 026db6e884c6..0c05d611bb7e 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp +++ b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp @@ -10,7 +10,7 @@ namespace handlers::insecure::insecuresecretpost { Response View::Handle( Request&& request, Deps&& /*deps*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return Response200{.body = {.greeting = fmt::format("Hello, {}!", request.name)}}; } @@ -19,7 +19,7 @@ Response View::Handle( std::string View::GetResponseForLogging( const Response& /*response*/, const std::string& /*serialized_response*/, - USERVER_NAMESPACE::server::request::RequestContext& /*context*/ + RequestContext& /*context*/ ) { return {}; } diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp index 42c1698cc9b8..5f15d02d4eba 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp +++ b/samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.hpp @@ -14,13 +14,14 @@ struct HandlerTag; class View final { public: using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - static Response Handle(Request&& request, Deps&& deps, USERVER_NAMESPACE::server::request::RequestContext& context); + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); static std::string GetResponseForLogging( const Response& response, const std::string& serialized_response, - USERVER_NAMESPACE::server::request::RequestContext& context + RequestContext& context ); }; From 830323ab46a7ea07a0f858d0c1e0019f450baa3c Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sun, 16 Aug 2026 23:15:22 +0300 Subject: [PATCH 07/22] feat(samples): add chaotic_openapi_auth_service sample --- .mapping.json | 10 +++ samples/CMakeLists.txt | 3 + .../CMakeLists.txt | 36 +++++++++ .../handlers/secure/openapi.yaml | 25 +++++++ samples/chaotic_openapi_auth_service/main.cpp | 22 ++++++ .../src/auth_bearer.cpp | 73 +++++++++++++++++++ .../src/auth_bearer.hpp | 23 ++++++ .../src/handlers/secure/greetingget/view.cpp | 24 ++++++ .../src/handlers/secure/greetingget/view.hpp | 20 +++++ .../static_config.yaml | 33 +++++++++ .../testsuite/conftest.py | 3 + .../testsuite/test_auth.py | 14 ++++ 12 files changed, 286 insertions(+) create mode 100644 samples/chaotic_openapi_auth_service/CMakeLists.txt create mode 100644 samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml create mode 100644 samples/chaotic_openapi_auth_service/main.cpp create mode 100644 samples/chaotic_openapi_auth_service/src/auth_bearer.cpp create mode 100644 samples/chaotic_openapi_auth_service/src/auth_bearer.hpp create mode 100644 samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp create mode 100644 samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp create mode 100644 samples/chaotic_openapi_auth_service/static_config.yaml create mode 100644 samples/chaotic_openapi_auth_service/testsuite/conftest.py create mode 100644 samples/chaotic_openapi_auth_service/testsuite/test_auth.py diff --git a/.mapping.json b/.mapping.json index 1aa1b271dfae..d911457874ee 100644 --- a/.mapping.json +++ b/.mapping.json @@ -4457,6 +4457,16 @@ "samples/benchmark_service/static_config.yaml":"taxi/uservices/userver/samples/benchmark_service/static_config.yaml", "samples/benchmark_service/testsuite/conftest.py":"taxi/uservices/userver/samples/benchmark_service/testsuite/conftest.py", "samples/benchmark_service/testsuite/test_benchmark.py":"taxi/uservices/userver/samples/benchmark_service/testsuite/test_benchmark.py", + "samples/chaotic_openapi_auth_service/CMakeLists.txt":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/CMakeLists.txt", + "samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml", + "samples/chaotic_openapi_auth_service/main.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/main.cpp", + "samples/chaotic_openapi_auth_service/src/auth_bearer.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp", + "samples/chaotic_openapi_auth_service/src/auth_bearer.hpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp", + "samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp", + "samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp", + "samples/chaotic_openapi_auth_service/static_config.yaml":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/static_config.yaml", + "samples/chaotic_openapi_auth_service/testsuite/conftest.py":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/testsuite/conftest.py", + "samples/chaotic_openapi_auth_service/testsuite/test_auth.py":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/testsuite/test_auth.py", "samples/chaotic_openapi_service/CMakeLists.txt":"taxi/uservices/userver/samples/chaotic_openapi_service/CMakeLists.txt", "samples/chaotic_openapi_service/clients/test.yaml":"taxi/uservices/userver/samples/chaotic_openapi_service/clients/test.yaml", "samples/chaotic_openapi_service/handlers/insecure/openapi.yaml":"taxi/uservices/userver/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml", diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index d0dfd4b0377b..c6a38a2f117a 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -21,6 +21,9 @@ if(USERVER_FEATURE_CHAOTIC) if(USERVER_FEATURE_CHAOTIC_OPENAPI) add_subdirectory(chaotic_openapi_service) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-chaotic-openapi_service) + + add_subdirectory(chaotic_openapi_auth_service) + add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-chaotic-openapi_auth_service) endif() endif() diff --git a/samples/chaotic_openapi_auth_service/CMakeLists.txt b/samples/chaotic_openapi_auth_service/CMakeLists.txt new file mode 100644 index 000000000000..c3799d8f0df1 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.14) +project(userver-samples-chaotic-openapi_auth_service CXX) + +find_package( + userver + COMPONENTS core chaotic + REQUIRED +) + +add_library(${PROJECT_NAME}_objs OBJECT src/auth_bearer.cpp) +target_link_libraries(${PROJECT_NAME}_objs userver::core) +target_include_directories(${PROJECT_NAME}_objs PUBLIC src) + +add_executable(${PROJECT_NAME} main.cpp) +target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_objs) + +# /// [chaotic-handler] cmake +userver_target_generate_openapi_handlers( + ${PROJECT_NAME}-handler-secure_objs + NAME secure + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/handlers/secure" + SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src" + SCHEMAS "${CMAKE_CURRENT_SOURCE_DIR}/handlers/secure/openapi.yaml" +) +target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}-handler-secure_objs) +# /// [chaotic-handler] + +# /// [generate-config] +userver_generate_config_yaml( + ${PROJECT_NAME} + BASE_CONFIGS "${CMAKE_CURRENT_SOURCE_DIR}/static_config.yaml" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.yaml" +) +# /// [generate-config] + +userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml b/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml new file mode 100644 index 000000000000..ace5e66b7ec0 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml @@ -0,0 +1,25 @@ +openapi: 3.0.0 +info: + title: Secure handler + version: '1.0' +paths: + /secure/greeting: + get: + operationId: greetingGet + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GreetingResponse' +components: + schemas: + GreetingResponse: + type: object + additionalProperties: false + required: + - greeting + properties: + greeting: + type: string \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/main.cpp b/samples/chaotic_openapi_auth_service/main.cpp new file mode 100644 index 000000000000..724977b5b9de --- /dev/null +++ b/samples/chaotic_openapi_auth_service/main.cpp @@ -0,0 +1,22 @@ +#include "auth_bearer.hpp" + +#include +#include +#include +#include + +#include + +int main(int argc, char* argv[]) { + /// [auth checker registration] + server::handlers::auth::RegisterAuthCheckerFactory(); + /// [auth checker registration] + + auto component_list = components::MinimalServerComponentList() + .Append() + /// [register-secure-handlers] + .AppendComponentList(::handlers::secure::ChaoticHandlersList()); + /// [register-secure-handlers] + + return utils::DaemonMain(argc, argv, component_list); +} \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp b/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp new file mode 100644 index 000000000000..4217b36c0735 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp @@ -0,0 +1,73 @@ +#include "auth_bearer.hpp" + +#include +#include + +#include +#include +#include + +namespace samples::auth { + +class AuthCheckerBearer final : public server::handlers::auth::AuthCheckerBase { +public: + using AuthCheckResult = server::handlers::auth::AuthCheckResult; + + [[nodiscard]] AuthCheckResult CheckAuth( + const server::http::HttpRequest& request, + server::request::RequestContext& request_context + ) const override; + + [[nodiscard]] bool SupportsUserAuth() const noexcept override { return true; } +}; + +/// [auth checker definition] +AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( + const server::http::HttpRequest& request, + server::request::RequestContext& request_context +) const { + const auto& auth_value = request.GetHeader(http::headers::kAuthorization); + constexpr std::string_view kBearerPrefix = "Bearer "; + if (auth_value.size() <= kBearerPrefix.size() || + std::string_view{auth_value}.substr(0, kBearerPrefix.size()) != kBearerPrefix) { + return AuthCheckResult{ + AuthCheckResult::Status::kTokenNotFound, + {}, + "Bearer token is required", + server::handlers::HandlerErrorCode::kUnauthorized, + }; + } + + std::uint64_t user_id = 0; + try { + user_id = std::stoull(std::string{auth_value.substr(kBearerPrefix.size())}); + } catch (const std::exception&) { + return AuthCheckResult{ + AuthCheckResult::Status::kInvalidToken, + {}, + "User id in the token must be an integer", + server::handlers::HandlerErrorCode::kUnauthorized, + }; + } + + SetUserAuthInfo( + request_context, + server::auth::UserAuthInfo{ + server::auth::UserId{user_id}, + server::auth::UserEnv::kProd, + server::auth::UserProvider::kYandex, + } + ); + return {}; +} +/// [auth checker definition] + +CheckerFactory::CheckerFactory(const components::ComponentContext&) {} + +server::handlers::auth::AuthCheckerBasePtr CheckerFactory::MakeAuthChecker( + const server::handlers::auth::HandlerAuthConfig& +) const { + return std::make_shared(); +} + +} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp b/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp new file mode 100644 index 000000000000..c771eed410ea --- /dev/null +++ b/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include +#include + +namespace samples::auth { + +/// [auth checker factory decl] +class CheckerFactory final : public server::handlers::auth::AuthCheckerFactoryBase { +public: + static constexpr std::string_view kAuthType = "bearer"; + + explicit CheckerFactory(const components::ComponentContext& context); + + server::handlers::auth::AuthCheckerBasePtr MakeAuthChecker( + const server::handlers::auth::HandlerAuthConfig& auth_config + ) const override; +}; +/// [auth checker factory decl] + +} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp new file mode 100644 index 000000000000..5ec6c671d723 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp @@ -0,0 +1,24 @@ +#include "view.hpp" + +#include + +#include +#include + +namespace handlers::secure::greetingget { + +/// [view-impl-auth] +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + RequestContext& context +) { + const auto& auth_info = USERVER_NAMESPACE::server::auth::GetUserAuthInfo(context); + const auto user_id = auth_info.GetDefaultUserId(); + return Response200{ + .body = {.greeting = fmt::format("Hello, user {}!", USERVER_NAMESPACE::server::auth::ToUInt64(user_id))} + }; +} +/// [view-impl-auth] + +} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp new file mode 100644 index 000000000000..eac6da7fef50 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include + +namespace handlers::secure::greetingget { + +struct HandlerTag; + +class View final { +public: + using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; + + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); +}; + +} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/static_config.yaml b/samples/chaotic_openapi_auth_service/static_config.yaml new file mode 100644 index 000000000000..97a9d31629a9 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/static_config.yaml @@ -0,0 +1,33 @@ +# yaml +components_manager: + task_processors: # Task processor is an executor for coroutine tasks + main-task-processor: # Make a task processor for CPU-bound coroutine tasks. + worker_threads: 4 # Process tasks in 4 threads. + + fs-task-processor: # Make a separate task processor for filesystem bound tasks. + worker_threads: 1 + + default_task_processor: main-task-processor # Task processor in which components start. + + components: # Configuring components that were registered via component_list + server: + listener: # configuring the main listening socket... + port: 8080 # ...to listen on this port and... + task_processor: main-task-processor # ...process incoming requests on this task processor. + + logging: + fs-task-processor: fs-task-processor + loggers: + default: + file_path: '@stderr' + level: debug + overflow_behavior: discard # Drop logs if the system is too busy to write them down. + + testsuite-support: + + # /// [secure-handler-config] + handler-greeting-get: # Generated handler, overrides the config.chaotic.yaml fragment. + auth: # Authorization config for this handler + types: + - bearer # Authorization type that was registered in main() + # /// [secure-handler-config] \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/testsuite/conftest.py b/samples/chaotic_openapi_auth_service/testsuite/conftest.py new file mode 100644 index 000000000000..01715c5de9a2 --- /dev/null +++ b/samples/chaotic_openapi_auth_service/testsuite/conftest.py @@ -0,0 +1,3 @@ +import pytest + +pytest_plugins = ['pytest_userver.plugins.core'] \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/testsuite/test_auth.py b/samples/chaotic_openapi_auth_service/testsuite/test_auth.py new file mode 100644 index 000000000000..89187d1656ab --- /dev/null +++ b/samples/chaotic_openapi_auth_service/testsuite/test_auth.py @@ -0,0 +1,14 @@ +async def test_greeting_requires_auth(service_client): + response = await service_client.get('/secure/greeting') + assert response.status == 401 + + +async def test_greeting_with_bad_token(service_client): + response = await service_client.get('/secure/greeting', headers={'Authorization': 'not a bearer token'}) + assert response.status == 401 + + +async def test_greeting_with_auth(service_client): + response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer 123'}) + assert response.status == 200 + assert response.json()['greeting'] == 'Hello, user 123!' \ No newline at end of file From 770bf8323cf1603f73438f3612d359cabc8f9c8a Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sun, 16 Aug 2026 23:15:25 +0300 Subject: [PATCH 08/22] test(chaotic-openapi): add view renderer unit tests --- .../tests/back/test_handler_view_renderer.py | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 chaotic-openapi/tests/back/test_handler_view_renderer.py diff --git a/chaotic-openapi/tests/back/test_handler_view_renderer.py b/chaotic-openapi/tests/back/test_handler_view_renderer.py new file mode 100644 index 000000000000..391cbe0b978e --- /dev/null +++ b/chaotic-openapi/tests/back/test_handler_view_renderer.py @@ -0,0 +1,82 @@ +"""Tests for the generated handler view stubs (view.hpp / view.cpp).""" + +import pathlib + +from chaotic_openapi.back.cpp.client import renderer as client_renderer +from chaotic_openapi.back.cpp.handler import renderer as handler_renderer +from chaotic_openapi.back.cpp.handler import translator as handler_translator +from chaotic_openapi.back.cpp.handler.types import ServerSpec +from chaotic_openapi.front import parser as front_parser + + +def _translate(schema, *, cpp_namespace='handlers::test') -> ServerSpec: + parser = front_parser.Parser('test') + parser.parse_schema(schema, '', '') + tr = handler_translator.HandlerTranslator( + parser.service(), + cpp_namespace=cpp_namespace, + include_dirs=[], + ) + return tr.spec() + + +def _render_views(spec: ServerSpec): + ctx = client_renderer.Context( + generate_path=pathlib.Path(''), + clang_format_bin='', + uservices_library_tvm_guard_hack=False, + ) + return handler_renderer.render_views(spec, ctx, userver_namespace='USERVER_NAMESPACE') + + +_MINIMAL_SCHEMA = { + 'openapi': '3.0.0', + 'info': {'title': '', 'version': '1.0'}, + 'paths': { + '/testme': { + 'post': { + 'operationId': 'testmePost', + 'parameters': [], + 'requestBody': { + 'content': { + 'application/json': {'schema': {'type': 'integer'}}, + }, + }, + 'responses': {200: {'description': 'OK'}}, + }, + }, + }, +} + + +def _view_outputs(): + spec = _translate(_MINIMAL_SCHEMA) + outputs = _render_views(spec) + return {o.rel_path: o for o in outputs} + + +def test_view_stubs_generated_per_operation(): + by_path = _view_outputs() + assert set(by_path) == {'testmepost/view.hpp', 'testmepost/view.cpp'} + + +def test_view_hpp_contract(): + hpp = _view_outputs()['testmepost/view.hpp'].content + + assert '#include ' in hpp + assert 'using RequestContext = USERVER_NAMESPACE::server::request::RequestContext;' in hpp + assert 'static Response Handle(Request&& request, Deps&& deps, RequestContext& context);' in hpp + assert 'GetResponseForLogging(' in hpp + assert 'RequestContext& context);' in hpp + + # The legacy 2-argument Handle must not be generated anymore. + assert 'Handle(Request&& request, Deps&& deps);' not in hpp + + +def test_view_cpp_stub_contract(): + cpp = _view_outputs()['testmepost/view.cpp'].content + + assert 'Response View::Handle(' in cpp + assert 'RequestContext& /*context*/) {' in cpp + assert 'GetResponseForLogging(' in cpp + assert 'RequestContext& context) {' in cpp \ No newline at end of file From 60e5a090ca06a1b655a668bb9417d678ea679b35 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Sun, 16 Aug 2026 23:15:27 +0300 Subject: [PATCH 09/22] docs(chaotic-openapi): document auth via RequestContext --- scripts/docs/en/userver/chaotic_handlers.md | 38 ++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/scripts/docs/en/userver/chaotic_handlers.md b/scripts/docs/en/userver/chaotic_handlers.md index 58739ac26e38..b420cdab9a26 100644 --- a/scripts/docs/en/userver/chaotic_handlers.md +++ b/scripts/docs/en/userver/chaotic_handlers.md @@ -15,6 +15,8 @@ For each HTTP operation in the schema chaotic produces: * **Request / response types** — C++ structs with JSON parsers and serializers. * **View stub** — a minimal `.hpp`/`.cpp` pair in `SRC_DIR` that you fill in with business logic. Existing view stubs are **never overwritten** on subsequent runs. + `View::Handle` receives the parsed request, the dependencies (`Deps`), and the per-request + `RequestContext` (see @ref scripts/docs/en/userver/chaotic_handlers.md "Authentication and request context" below). * **`config.chaotic.yaml`** — static config fragment for all generated handlers; merged into the service config by `userver_generate_config_yaml()`. @@ -30,7 +32,8 @@ For each HTTP operation in the schema chaotic produces: @snippet samples/chaotic_openapi_service/CMakeLists.txt chaotic-handler **Step 3.** Implement the generated view stub. Chaotic writes a skeleton to -`src/handlers/NAME/OPERATION/view.cpp` on the first run: +`src/handlers/NAME/OPERATION/view.cpp` on the first run. `Handle` always receives the +per-request context as the third argument (an alias `RequestContext` is provided in `View`): @snippet samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp view-impl @@ -45,6 +48,39 @@ Subsequent runs leave `view.cpp` untouched. @snippet samples/chaotic_openapi_service/CMakeLists.txt generate-config +### Authentication and request context + +`View::Handle` always receives `userver::server::request::RequestContext` as its third +argument (the generated `View` provides a short `RequestContext` alias for it, same as `Deps`): + +```cpp +using RequestContext = userver::server::request::RequestContext; + +static Response Handle(Request&& request, Deps&& deps, RequestContext& context); +``` + +The context carries per-request data set by the middlewares of the default pipeline — +most notably the auth info set by the `userver-auth-middleware`. Read it with +`userver::server::auth::GetUserAuthInfo(context)`: + +@snippet samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp view-impl-auth + +A complete example lives in `samples/chaotic_openapi_auth_service`: + +1. Register a custom auth checker factory in `main.cpp`: + +@snippet samples/chaotic_openapi_auth_service/main.cpp auth checker registration + +2. The checker (`src/auth_bearer.cpp`) parses `Authorization: Bearer ` and stores + the user info in the context via `SetUserAuthInfo()`: + +@snippet samples/chaotic_openapi_auth_service/src/auth_bearer.cpp auth checker definition + +3. Enable auth for the generated handler in the static config (`auth: {types: [bearer]}`): + +@snippet samples/chaotic_openapi_auth_service/static_config.yaml secure-handler-config + + ### CMake reference #### `userver_target_generate_openapi_handlers(TARGET)` From b2fc748011482275c546350e5e7249345653305c Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 00:51:11 +0300 Subject: [PATCH 10/22] revert(chaotic-openapi): drop redundant docs, mapping and sample changes --- .mapping.json | 10 --- chaotic-openapi/AGENTS.md | 17 ---- .../tests/back/test_handler_view_renderer.py | 82 ------------------- samples/CMakeLists.txt | 3 - .../CMakeLists.txt | 36 -------- .../handlers/secure/openapi.yaml | 25 ------ samples/chaotic_openapi_auth_service/main.cpp | 22 ----- .../src/auth_bearer.cpp | 73 ----------------- .../src/auth_bearer.hpp | 23 ------ .../src/handlers/secure/greetingget/view.cpp | 24 ------ .../src/handlers/secure/greetingget/view.hpp | 20 ----- .../static_config.yaml | 33 -------- .../testsuite/conftest.py | 3 - .../testsuite/test_auth.py | 14 ---- scripts/docs/en/userver/chaotic_handlers.md | 38 +-------- 15 files changed, 1 insertion(+), 422 deletions(-) delete mode 100644 chaotic-openapi/tests/back/test_handler_view_renderer.py delete mode 100644 samples/chaotic_openapi_auth_service/CMakeLists.txt delete mode 100644 samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml delete mode 100644 samples/chaotic_openapi_auth_service/main.cpp delete mode 100644 samples/chaotic_openapi_auth_service/src/auth_bearer.cpp delete mode 100644 samples/chaotic_openapi_auth_service/src/auth_bearer.hpp delete mode 100644 samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp delete mode 100644 samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp delete mode 100644 samples/chaotic_openapi_auth_service/static_config.yaml delete mode 100644 samples/chaotic_openapi_auth_service/testsuite/conftest.py delete mode 100644 samples/chaotic_openapi_auth_service/testsuite/test_auth.py diff --git a/.mapping.json b/.mapping.json index d911457874ee..1aa1b271dfae 100644 --- a/.mapping.json +++ b/.mapping.json @@ -4457,16 +4457,6 @@ "samples/benchmark_service/static_config.yaml":"taxi/uservices/userver/samples/benchmark_service/static_config.yaml", "samples/benchmark_service/testsuite/conftest.py":"taxi/uservices/userver/samples/benchmark_service/testsuite/conftest.py", "samples/benchmark_service/testsuite/test_benchmark.py":"taxi/uservices/userver/samples/benchmark_service/testsuite/test_benchmark.py", - "samples/chaotic_openapi_auth_service/CMakeLists.txt":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/CMakeLists.txt", - "samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml", - "samples/chaotic_openapi_auth_service/main.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/main.cpp", - "samples/chaotic_openapi_auth_service/src/auth_bearer.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp", - "samples/chaotic_openapi_auth_service/src/auth_bearer.hpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp", - "samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp", - "samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp", - "samples/chaotic_openapi_auth_service/static_config.yaml":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/static_config.yaml", - "samples/chaotic_openapi_auth_service/testsuite/conftest.py":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/testsuite/conftest.py", - "samples/chaotic_openapi_auth_service/testsuite/test_auth.py":"taxi/uservices/userver/samples/chaotic_openapi_auth_service/testsuite/test_auth.py", "samples/chaotic_openapi_service/CMakeLists.txt":"taxi/uservices/userver/samples/chaotic_openapi_service/CMakeLists.txt", "samples/chaotic_openapi_service/clients/test.yaml":"taxi/uservices/userver/samples/chaotic_openapi_service/clients/test.yaml", "samples/chaotic_openapi_service/handlers/insecure/openapi.yaml":"taxi/uservices/userver/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml", diff --git a/chaotic-openapi/AGENTS.md b/chaotic-openapi/AGENTS.md index 7526cf754f8f..239ff760ef63 100644 --- a/chaotic-openapi/AGENTS.md +++ b/chaotic-openapi/AGENTS.md @@ -32,23 +32,6 @@ that generates the `PEERDIR`/include lists for `ya.make` files. It is never call `main.py`. -## View contract - -For each operation the generator emits a `View` with a hand-written entry point: - -```cpp -using RequestContext = userver::server::request::RequestContext; - -static Response Handle(Request&& request, Deps&& deps, RequestContext& context); -``` - -The third parameter gives the handler access to the per-request context (e.g. data set by -the auth middleware via `userver::server::auth::GetUserAuthInfo(context)` / `context.SetData`). -It is **always** passed by the runtime dispatcher (`BaseHandler` in -`include/userver/chaotic/openapi/server/handler_base.hpp`) — the legacy 2-argument -`Handle(Request&&, Deps&&)` is not supported. - - # Tests Tests are implemented at multiple levels: diff --git a/chaotic-openapi/tests/back/test_handler_view_renderer.py b/chaotic-openapi/tests/back/test_handler_view_renderer.py deleted file mode 100644 index 391cbe0b978e..000000000000 --- a/chaotic-openapi/tests/back/test_handler_view_renderer.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Tests for the generated handler view stubs (view.hpp / view.cpp).""" - -import pathlib - -from chaotic_openapi.back.cpp.client import renderer as client_renderer -from chaotic_openapi.back.cpp.handler import renderer as handler_renderer -from chaotic_openapi.back.cpp.handler import translator as handler_translator -from chaotic_openapi.back.cpp.handler.types import ServerSpec -from chaotic_openapi.front import parser as front_parser - - -def _translate(schema, *, cpp_namespace='handlers::test') -> ServerSpec: - parser = front_parser.Parser('test') - parser.parse_schema(schema, '', '') - tr = handler_translator.HandlerTranslator( - parser.service(), - cpp_namespace=cpp_namespace, - include_dirs=[], - ) - return tr.spec() - - -def _render_views(spec: ServerSpec): - ctx = client_renderer.Context( - generate_path=pathlib.Path(''), - clang_format_bin='', - uservices_library_tvm_guard_hack=False, - ) - return handler_renderer.render_views(spec, ctx, userver_namespace='USERVER_NAMESPACE') - - -_MINIMAL_SCHEMA = { - 'openapi': '3.0.0', - 'info': {'title': '', 'version': '1.0'}, - 'paths': { - '/testme': { - 'post': { - 'operationId': 'testmePost', - 'parameters': [], - 'requestBody': { - 'content': { - 'application/json': {'schema': {'type': 'integer'}}, - }, - }, - 'responses': {200: {'description': 'OK'}}, - }, - }, - }, -} - - -def _view_outputs(): - spec = _translate(_MINIMAL_SCHEMA) - outputs = _render_views(spec) - return {o.rel_path: o for o in outputs} - - -def test_view_stubs_generated_per_operation(): - by_path = _view_outputs() - assert set(by_path) == {'testmepost/view.hpp', 'testmepost/view.cpp'} - - -def test_view_hpp_contract(): - hpp = _view_outputs()['testmepost/view.hpp'].content - - assert '#include ' in hpp - assert 'using RequestContext = USERVER_NAMESPACE::server::request::RequestContext;' in hpp - assert 'static Response Handle(Request&& request, Deps&& deps, RequestContext& context);' in hpp - assert 'GetResponseForLogging(' in hpp - assert 'RequestContext& context);' in hpp - - # The legacy 2-argument Handle must not be generated anymore. - assert 'Handle(Request&& request, Deps&& deps);' not in hpp - - -def test_view_cpp_stub_contract(): - cpp = _view_outputs()['testmepost/view.cpp'].content - - assert 'Response View::Handle(' in cpp - assert 'RequestContext& /*context*/) {' in cpp - assert 'GetResponseForLogging(' in cpp - assert 'RequestContext& context) {' in cpp \ No newline at end of file diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index c6a38a2f117a..d0dfd4b0377b 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -21,9 +21,6 @@ if(USERVER_FEATURE_CHAOTIC) if(USERVER_FEATURE_CHAOTIC_OPENAPI) add_subdirectory(chaotic_openapi_service) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-chaotic-openapi_service) - - add_subdirectory(chaotic_openapi_auth_service) - add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-chaotic-openapi_auth_service) endif() endif() diff --git a/samples/chaotic_openapi_auth_service/CMakeLists.txt b/samples/chaotic_openapi_auth_service/CMakeLists.txt deleted file mode 100644 index c3799d8f0df1..000000000000 --- a/samples/chaotic_openapi_auth_service/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(userver-samples-chaotic-openapi_auth_service CXX) - -find_package( - userver - COMPONENTS core chaotic - REQUIRED -) - -add_library(${PROJECT_NAME}_objs OBJECT src/auth_bearer.cpp) -target_link_libraries(${PROJECT_NAME}_objs userver::core) -target_include_directories(${PROJECT_NAME}_objs PUBLIC src) - -add_executable(${PROJECT_NAME} main.cpp) -target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_objs) - -# /// [chaotic-handler] cmake -userver_target_generate_openapi_handlers( - ${PROJECT_NAME}-handler-secure_objs - NAME secure - OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/handlers/secure" - SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src" - SCHEMAS "${CMAKE_CURRENT_SOURCE_DIR}/handlers/secure/openapi.yaml" -) -target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}-handler-secure_objs) -# /// [chaotic-handler] - -# /// [generate-config] -userver_generate_config_yaml( - ${PROJECT_NAME} - BASE_CONFIGS "${CMAKE_CURRENT_SOURCE_DIR}/static_config.yaml" - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config.yaml" -) -# /// [generate-config] - -userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml b/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml deleted file mode 100644 index ace5e66b7ec0..000000000000 --- a/samples/chaotic_openapi_auth_service/handlers/secure/openapi.yaml +++ /dev/null @@ -1,25 +0,0 @@ -openapi: 3.0.0 -info: - title: Secure handler - version: '1.0' -paths: - /secure/greeting: - get: - operationId: greetingGet - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GreetingResponse' -components: - schemas: - GreetingResponse: - type: object - additionalProperties: false - required: - - greeting - properties: - greeting: - type: string \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/main.cpp b/samples/chaotic_openapi_auth_service/main.cpp deleted file mode 100644 index 724977b5b9de..000000000000 --- a/samples/chaotic_openapi_auth_service/main.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "auth_bearer.hpp" - -#include -#include -#include -#include - -#include - -int main(int argc, char* argv[]) { - /// [auth checker registration] - server::handlers::auth::RegisterAuthCheckerFactory(); - /// [auth checker registration] - - auto component_list = components::MinimalServerComponentList() - .Append() - /// [register-secure-handlers] - .AppendComponentList(::handlers::secure::ChaoticHandlersList()); - /// [register-secure-handlers] - - return utils::DaemonMain(argc, argv, component_list); -} \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp b/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp deleted file mode 100644 index 4217b36c0735..000000000000 --- a/samples/chaotic_openapi_auth_service/src/auth_bearer.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "auth_bearer.hpp" - -#include -#include - -#include -#include -#include - -namespace samples::auth { - -class AuthCheckerBearer final : public server::handlers::auth::AuthCheckerBase { -public: - using AuthCheckResult = server::handlers::auth::AuthCheckResult; - - [[nodiscard]] AuthCheckResult CheckAuth( - const server::http::HttpRequest& request, - server::request::RequestContext& request_context - ) const override; - - [[nodiscard]] bool SupportsUserAuth() const noexcept override { return true; } -}; - -/// [auth checker definition] -AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( - const server::http::HttpRequest& request, - server::request::RequestContext& request_context -) const { - const auto& auth_value = request.GetHeader(http::headers::kAuthorization); - constexpr std::string_view kBearerPrefix = "Bearer "; - if (auth_value.size() <= kBearerPrefix.size() || - std::string_view{auth_value}.substr(0, kBearerPrefix.size()) != kBearerPrefix) { - return AuthCheckResult{ - AuthCheckResult::Status::kTokenNotFound, - {}, - "Bearer token is required", - server::handlers::HandlerErrorCode::kUnauthorized, - }; - } - - std::uint64_t user_id = 0; - try { - user_id = std::stoull(std::string{auth_value.substr(kBearerPrefix.size())}); - } catch (const std::exception&) { - return AuthCheckResult{ - AuthCheckResult::Status::kInvalidToken, - {}, - "User id in the token must be an integer", - server::handlers::HandlerErrorCode::kUnauthorized, - }; - } - - SetUserAuthInfo( - request_context, - server::auth::UserAuthInfo{ - server::auth::UserId{user_id}, - server::auth::UserEnv::kProd, - server::auth::UserProvider::kYandex, - } - ); - return {}; -} -/// [auth checker definition] - -CheckerFactory::CheckerFactory(const components::ComponentContext&) {} - -server::handlers::auth::AuthCheckerBasePtr CheckerFactory::MakeAuthChecker( - const server::handlers::auth::HandlerAuthConfig& -) const { - return std::make_shared(); -} - -} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp b/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp deleted file mode 100644 index c771eed410ea..000000000000 --- a/samples/chaotic_openapi_auth_service/src/auth_bearer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace samples::auth { - -/// [auth checker factory decl] -class CheckerFactory final : public server::handlers::auth::AuthCheckerFactoryBase { -public: - static constexpr std::string_view kAuthType = "bearer"; - - explicit CheckerFactory(const components::ComponentContext& context); - - server::handlers::auth::AuthCheckerBasePtr MakeAuthChecker( - const server::handlers::auth::HandlerAuthConfig& auth_config - ) const override; -}; -/// [auth checker factory decl] - -} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp deleted file mode 100644 index 5ec6c671d723..000000000000 --- a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "view.hpp" - -#include - -#include -#include - -namespace handlers::secure::greetingget { - -/// [view-impl-auth] -Response View::Handle( - Request&& /*request*/, - Deps&& /*deps*/, - RequestContext& context -) { - const auto& auth_info = USERVER_NAMESPACE::server::auth::GetUserAuthInfo(context); - const auto user_id = auth_info.GetDefaultUserId(); - return Response200{ - .body = {.greeting = fmt::format("Hello, user {}!", USERVER_NAMESPACE::server::auth::ToUInt64(user_id))} - }; -} -/// [view-impl-auth] - -} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp b/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp deleted file mode 100644 index eac6da7fef50..000000000000 --- a/samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace handlers::secure::greetingget { - -struct HandlerTag; - -class View final { -public: - using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - - static Response Handle(Request&& request, Deps&& deps, RequestContext& context); -}; - -} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/static_config.yaml b/samples/chaotic_openapi_auth_service/static_config.yaml deleted file mode 100644 index 97a9d31629a9..000000000000 --- a/samples/chaotic_openapi_auth_service/static_config.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# yaml -components_manager: - task_processors: # Task processor is an executor for coroutine tasks - main-task-processor: # Make a task processor for CPU-bound coroutine tasks. - worker_threads: 4 # Process tasks in 4 threads. - - fs-task-processor: # Make a separate task processor for filesystem bound tasks. - worker_threads: 1 - - default_task_processor: main-task-processor # Task processor in which components start. - - components: # Configuring components that were registered via component_list - server: - listener: # configuring the main listening socket... - port: 8080 # ...to listen on this port and... - task_processor: main-task-processor # ...process incoming requests on this task processor. - - logging: - fs-task-processor: fs-task-processor - loggers: - default: - file_path: '@stderr' - level: debug - overflow_behavior: discard # Drop logs if the system is too busy to write them down. - - testsuite-support: - - # /// [secure-handler-config] - handler-greeting-get: # Generated handler, overrides the config.chaotic.yaml fragment. - auth: # Authorization config for this handler - types: - - bearer # Authorization type that was registered in main() - # /// [secure-handler-config] \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/testsuite/conftest.py b/samples/chaotic_openapi_auth_service/testsuite/conftest.py deleted file mode 100644 index 01715c5de9a2..000000000000 --- a/samples/chaotic_openapi_auth_service/testsuite/conftest.py +++ /dev/null @@ -1,3 +0,0 @@ -import pytest - -pytest_plugins = ['pytest_userver.plugins.core'] \ No newline at end of file diff --git a/samples/chaotic_openapi_auth_service/testsuite/test_auth.py b/samples/chaotic_openapi_auth_service/testsuite/test_auth.py deleted file mode 100644 index 89187d1656ab..000000000000 --- a/samples/chaotic_openapi_auth_service/testsuite/test_auth.py +++ /dev/null @@ -1,14 +0,0 @@ -async def test_greeting_requires_auth(service_client): - response = await service_client.get('/secure/greeting') - assert response.status == 401 - - -async def test_greeting_with_bad_token(service_client): - response = await service_client.get('/secure/greeting', headers={'Authorization': 'not a bearer token'}) - assert response.status == 401 - - -async def test_greeting_with_auth(service_client): - response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer 123'}) - assert response.status == 200 - assert response.json()['greeting'] == 'Hello, user 123!' \ No newline at end of file diff --git a/scripts/docs/en/userver/chaotic_handlers.md b/scripts/docs/en/userver/chaotic_handlers.md index b420cdab9a26..58739ac26e38 100644 --- a/scripts/docs/en/userver/chaotic_handlers.md +++ b/scripts/docs/en/userver/chaotic_handlers.md @@ -15,8 +15,6 @@ For each HTTP operation in the schema chaotic produces: * **Request / response types** — C++ structs with JSON parsers and serializers. * **View stub** — a minimal `.hpp`/`.cpp` pair in `SRC_DIR` that you fill in with business logic. Existing view stubs are **never overwritten** on subsequent runs. - `View::Handle` receives the parsed request, the dependencies (`Deps`), and the per-request - `RequestContext` (see @ref scripts/docs/en/userver/chaotic_handlers.md "Authentication and request context" below). * **`config.chaotic.yaml`** — static config fragment for all generated handlers; merged into the service config by `userver_generate_config_yaml()`. @@ -32,8 +30,7 @@ For each HTTP operation in the schema chaotic produces: @snippet samples/chaotic_openapi_service/CMakeLists.txt chaotic-handler **Step 3.** Implement the generated view stub. Chaotic writes a skeleton to -`src/handlers/NAME/OPERATION/view.cpp` on the first run. `Handle` always receives the -per-request context as the third argument (an alias `RequestContext` is provided in `View`): +`src/handlers/NAME/OPERATION/view.cpp` on the first run: @snippet samples/chaotic_openapi_service/src/handlers/insecure/insecuresecretpost/view.cpp view-impl @@ -48,39 +45,6 @@ Subsequent runs leave `view.cpp` untouched. @snippet samples/chaotic_openapi_service/CMakeLists.txt generate-config -### Authentication and request context - -`View::Handle` always receives `userver::server::request::RequestContext` as its third -argument (the generated `View` provides a short `RequestContext` alias for it, same as `Deps`): - -```cpp -using RequestContext = userver::server::request::RequestContext; - -static Response Handle(Request&& request, Deps&& deps, RequestContext& context); -``` - -The context carries per-request data set by the middlewares of the default pipeline — -most notably the auth info set by the `userver-auth-middleware`. Read it with -`userver::server::auth::GetUserAuthInfo(context)`: - -@snippet samples/chaotic_openapi_auth_service/src/handlers/secure/greetingget/view.cpp view-impl-auth - -A complete example lives in `samples/chaotic_openapi_auth_service`: - -1. Register a custom auth checker factory in `main.cpp`: - -@snippet samples/chaotic_openapi_auth_service/main.cpp auth checker registration - -2. The checker (`src/auth_bearer.cpp`) parses `Authorization: Bearer ` and stores - the user info in the context via `SetUserAuthInfo()`: - -@snippet samples/chaotic_openapi_auth_service/src/auth_bearer.cpp auth checker definition - -3. Enable auth for the generated handler in the static config (`auth: {types: [bearer]}`): - -@snippet samples/chaotic_openapi_auth_service/static_config.yaml secure-handler-config - - ### CMake reference #### `userver_target_generate_openapi_handlers(TARGET)` From 733f088d656b07d01ea981e6bbbb08a73807bb21 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 11:06:49 +0300 Subject: [PATCH 11/22] fix(chaotic-openapi): update handler logging test for RequestContext in Handle --- .../src/chaotic/openapi/server/handler_logging_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chaotic-openapi/src/chaotic/openapi/server/handler_logging_test.cpp b/chaotic-openapi/src/chaotic/openapi/server/handler_logging_test.cpp index fef0ece7c9b2..0a2b5e5b0981 100644 --- a/chaotic-openapi/src/chaotic/openapi/server/handler_logging_test.cpp +++ b/chaotic-openapi/src/chaotic/openapi/server/handler_logging_test.cpp @@ -22,7 +22,7 @@ using FakeDeps = co_server::dependencies::ForHandler; // ---- MinimalView (no logging methods) ---- struct MinimalView { - static FakeResponse Handle(FakeRequest&&, FakeDeps&&) { return {}; } + static FakeResponse Handle(FakeRequest&&, FakeDeps&&, server::request::RequestContext&) { return {}; } }; static_assert(!co_server::impl::ViewHasGetRequestBodyForLoggingJson); @@ -40,7 +40,7 @@ TEST(HandlerLogging, MinimalViewReturnsNullopt) { // ---- JsonBodyView ---- struct JsonBodyView { - static FakeResponse Handle(FakeRequest&&, FakeDeps&&) { return {}; } + static FakeResponse Handle(FakeRequest&&, FakeDeps&&, server::request::RequestContext&) { return {}; } static std::string GetRequestBodyForLogging(const formats::json::Value& body) { return "k=" + body["k"].As(""); @@ -70,7 +70,7 @@ TEST(HandlerLogging, JsonBodyInvalidThrows) { // ---- StringBodyView ---- struct StringBodyView { - static FakeResponse Handle(FakeRequest&&, FakeDeps&&) { return {}; } + static FakeResponse Handle(FakeRequest&&, FakeDeps&&, server::request::RequestContext&) { return {}; } static std::string GetRequestBodyForLogging(const std::string& body) { return "len=" + std::to_string(body.size()); @@ -94,7 +94,7 @@ TEST(HandlerLogging, StringBody) { // ---- ResponseLoggingView ---- struct ResponseLoggingView { - static FakeResponse Handle(FakeRequest&&, FakeDeps&&) { return {}; } + static FakeResponse Handle(FakeRequest&&, FakeDeps&&, server::request::RequestContext&) { return {}; } static std::string GetResponseForLogging(const FakeResponse&, const std::string& serialized, server::request::RequestContext&) { From 32af41792bd64b961a5c9c74f806796371e5c809 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 11:06:50 +0300 Subject: [PATCH 12/22] feat(samples): demonstrate RequestContext auth in chaotic_openapi_service --- .../chaotic_openapi_service/CMakeLists.txt | 2 +- .../handlers/insecure/openapi.yaml | 11 +++ samples/chaotic_openapi_service/main.cpp | 4 ++ .../src/auth_bearer.cpp | 72 +++++++++++++++++++ .../src/auth_bearer.hpp | 21 ++++++ .../handlers/insecure/greetingget/view.cpp | 22 ++++++ .../handlers/insecure/greetingget/view.hpp | 22 ++++++ samples/chaotic_openapi_service/src/ya.make | 11 +++ .../static_config.user.yaml | 5 ++ .../testsuite/test_auth.py | 14 ++++ 10 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 samples/chaotic_openapi_service/src/auth_bearer.cpp create mode 100644 samples/chaotic_openapi_service/src/auth_bearer.hpp create mode 100644 samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp create mode 100644 samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp create mode 100644 samples/chaotic_openapi_service/testsuite/test_auth.py diff --git a/samples/chaotic_openapi_service/CMakeLists.txt b/samples/chaotic_openapi_service/CMakeLists.txt index 1047bcf2c5e8..f19d7a53a573 100644 --- a/samples/chaotic_openapi_service/CMakeLists.txt +++ b/samples/chaotic_openapi_service/CMakeLists.txt @@ -7,7 +7,7 @@ find_package( REQUIRED ) -add_library(${PROJECT_NAME}_objs OBJECT src/say_hello.hpp src/say_hello.cpp src/hello_handler.hpp src/hello_handler.cpp) +add_library(${PROJECT_NAME}_objs OBJECT src/auth_bearer.hpp src/auth_bearer.cpp src/say_hello.hpp src/say_hello.cpp src/hello_handler.hpp src/hello_handler.cpp) target_link_libraries(${PROJECT_NAME}_objs userver::core) target_include_directories(${PROJECT_NAME}_objs PUBLIC src) diff --git a/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml b/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml index 42965b081ae1..bfc89a822c97 100644 --- a/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml +++ b/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml @@ -28,6 +28,17 @@ paths: application/json: schema: $ref: '#/components/schemas/GreetingResponse' + + /secure/greeting: + get: + operationId: greetingGet + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GreetingResponse' components: schemas: GreetingResponse: diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index 0f5afb7b854a..b331535a9712 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -15,6 +15,8 @@ #include #include +#include "auth_bearer.hpp" + int main(int argc, char* argv[]) { auto component_list = USERVER_NAMESPACE::components::MinimalServerComponentList() @@ -37,5 +39,7 @@ int main(int argc, char* argv[]) { USERVER_NAMESPACE::chaotic::openapi::middlewares::AppendDefaultMiddlewares(component_list); + server::handlers::auth::RegisterAuthCheckerFactory(); + return USERVER_NAMESPACE::utils::DaemonMain(argc, argv, component_list); } diff --git a/samples/chaotic_openapi_service/src/auth_bearer.cpp b/samples/chaotic_openapi_service/src/auth_bearer.cpp new file mode 100644 index 000000000000..af5746d00ff7 --- /dev/null +++ b/samples/chaotic_openapi_service/src/auth_bearer.cpp @@ -0,0 +1,72 @@ +#include "auth_bearer.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace samples::auth { + +class AuthCheckerBearer final : public server::handlers::auth::AuthCheckerBase { +public: + using AuthCheckResult = server::handlers::auth::AuthCheckResult; + + [[nodiscard]] AuthCheckResult CheckAuth( + const server::http::HttpRequest& request, + server::request::RequestContext& request_context + ) const override; + + [[nodiscard]] bool SupportsUserAuth() const noexcept override { return true; } +}; + +AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( + const server::http::HttpRequest& request, + server::request::RequestContext& request_context +) const { + const auto& auth_value = request.GetHeader(http::headers::kAuthorization); + constexpr std::string_view kBearerPrefix = "Bearer "; + if (auth_value.size() <= kBearerPrefix.size() || + std::string_view{auth_value}.substr(0, kBearerPrefix.size()) != kBearerPrefix) { + return AuthCheckResult{ + AuthCheckResult::Status::kTokenNotFound, + {}, + "Bearer token is required", + server::handlers::HandlerErrorCode::kUnauthorized, + }; + } + + std::uint64_t user_id = 0; + try { + user_id = std::stoull(std::string{auth_value.substr(kBearerPrefix.size())}); + } catch (const std::exception&) { + return AuthCheckResult{ + AuthCheckResult::Status::kInvalidToken, + {}, + "User id in the token must be an integer", + server::handlers::HandlerErrorCode::kUnauthorized, + }; + } + + SetUserAuthInfo( + request_context, + server::auth::UserAuthInfo{ + server::auth::UserId{user_id}, + server::auth::UserEnv::kProd, + server::auth::UserProvider::kYandex, + } + ); + return {}; +} + +CheckerFactory::CheckerFactory(const components::ComponentContext&) {} + +server::handlers::auth::AuthCheckerBasePtr CheckerFactory::MakeAuthChecker( + const server::handlers::auth::HandlerAuthConfig& +) const { + return std::make_shared(); +} + +} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/auth_bearer.hpp b/samples/chaotic_openapi_service/src/auth_bearer.hpp new file mode 100644 index 000000000000..6ee02150aca6 --- /dev/null +++ b/samples/chaotic_openapi_service/src/auth_bearer.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include +#include + +namespace samples::auth { + +class CheckerFactory final : public server::handlers::auth::AuthCheckerFactoryBase { +public: + static constexpr std::string_view kAuthType = "bearer"; + + explicit CheckerFactory(const components::ComponentContext& context); + + server::handlers::auth::AuthCheckerBasePtr MakeAuthChecker( + const server::handlers::auth::HandlerAuthConfig& auth_config + ) const override; +}; + +} // namespace samples::auth \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp b/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp new file mode 100644 index 000000000000..60f5e03cbc9a --- /dev/null +++ b/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp @@ -0,0 +1,22 @@ +#include "view.hpp" + +#include + +#include +#include + +namespace handlers::insecure::greetingget { + +Response View::Handle( + Request&& /*request*/, + Deps&& /*deps*/, + RequestContext& context +) { + const auto& auth_info = USERVER_NAMESPACE::server::auth::GetUserAuthInfo(context); + const auto user_id = auth_info.GetDefaultUserId(); + return Response200{ + .body = {.greeting = fmt::format("Hello, user {}!", USERVER_NAMESPACE::server::auth::ToUInt64(user_id))} + }; +} + +} // namespace handlers::insecure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp b/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp new file mode 100644 index 000000000000..29016abfcba7 --- /dev/null +++ b/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace handlers::insecure::greetingget { + +struct HandlerTag; + +class View final { +public: + using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; + + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); +}; + +} // namespace handlers::insecure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/ya.make b/samples/chaotic_openapi_service/src/ya.make index 6448583f61ac..312ea1e0fc22 100644 --- a/samples/chaotic_openapi_service/src/ya.make +++ b/samples/chaotic_openapi_service/src/ya.make @@ -15,9 +15,11 @@ ADDINCL( ) SRCS( + auth_bearer.cpp hello_handler.cpp say_hello.cpp handlers/insecure/insecuresecretpost/view.cpp + handlers/insecure/greetingget/view.cpp ) ADDINCL( @@ -70,6 +72,7 @@ RUN_PROGRAM( ${CHAOTIC_INCLUDES} ${CHAOTIC_OPENAPI_INCLUDES} handlers/insecure/insecuresecretpost/view.hpp + handlers/insecure/greetingget/view.hpp IN_NOPARSE ../handlers/insecure/openapi.yaml OUT @@ -89,6 +92,14 @@ RUN_PROGRAM( src/handlers/insecure/insecuresecretpost/requests.cpp src/handlers/insecure/insecuresecretpost/responses.cpp + include/handlers/insecure/greetingget/handler.hpp + include/handlers/insecure/greetingget/requests.hpp + include/handlers/insecure/greetingget/responses.hpp + + src/handlers/insecure/greetingget/handler.cpp + src/handlers/insecure/greetingget/requests.cpp + src/handlers/insecure/greetingget/responses.cpp + config.chaotic.yaml ) diff --git a/samples/chaotic_openapi_service/static_config.user.yaml b/samples/chaotic_openapi_service/static_config.user.yaml index d7164832cfc0..949121ae7926 100644 --- a/samples/chaotic_openapi_service/static_config.user.yaml +++ b/samples/chaotic_openapi_service/static_config.user.yaml @@ -40,6 +40,11 @@ components_manager: method: GET,POST # It will only reply to GET (HEAD) and POST requests. task_processor: main-task-processor # Run it on CPU bound task processor + handler-greeting-get: # Generated handler, overrides the config.chaotic.yaml fragment. + auth: # Authorization config for this handler + types: + - bearer # Authorization type that was registered in main() + dynamic-config: updates-enabled: true fs-task-processor: fs-task-processor diff --git a/samples/chaotic_openapi_service/testsuite/test_auth.py b/samples/chaotic_openapi_service/testsuite/test_auth.py new file mode 100644 index 000000000000..89187d1656ab --- /dev/null +++ b/samples/chaotic_openapi_service/testsuite/test_auth.py @@ -0,0 +1,14 @@ +async def test_greeting_requires_auth(service_client): + response = await service_client.get('/secure/greeting') + assert response.status == 401 + + +async def test_greeting_with_bad_token(service_client): + response = await service_client.get('/secure/greeting', headers={'Authorization': 'not a bearer token'}) + assert response.status == 401 + + +async def test_greeting_with_auth(service_client): + response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer 123'}) + assert response.status == 200 + assert response.json()['greeting'] == 'Hello, user 123!' \ No newline at end of file From 8a0419551d2049caef06e8741ccdb87cdcf40a27 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 13:25:31 +0300 Subject: [PATCH 13/22] refactor(samples): move greetingGet to a separate secure schema --- .../chaotic_openapi_service/CMakeLists.txt | 9 ++++ .../handlers/insecure/openapi.yaml | 11 ----- .../handlers/secure/openapi.yaml | 25 +++++++++++ samples/chaotic_openapi_service/main.cpp | 4 +- .../{insecure => secure}/greetingget/view.cpp | 6 +-- .../{insecure => secure}/greetingget/view.hpp | 8 ++-- samples/chaotic_openapi_service/src/ya.make | 42 +++++++++++++++---- 7 files changed, 78 insertions(+), 27 deletions(-) create mode 100644 samples/chaotic_openapi_service/handlers/secure/openapi.yaml rename samples/chaotic_openapi_service/src/handlers/{insecure => secure}/greetingget/view.cpp (77%) rename samples/chaotic_openapi_service/src/handlers/{insecure => secure}/greetingget/view.hpp (69%) diff --git a/samples/chaotic_openapi_service/CMakeLists.txt b/samples/chaotic_openapi_service/CMakeLists.txt index f19d7a53a573..093a0dfbfe74 100644 --- a/samples/chaotic_openapi_service/CMakeLists.txt +++ b/samples/chaotic_openapi_service/CMakeLists.txt @@ -34,6 +34,15 @@ userver_target_generate_openapi_handlers( SCHEMAS "${CMAKE_CURRENT_SOURCE_DIR}/handlers/insecure/openapi.yaml" ) target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}-handler-insecure_objs) + +userver_target_generate_openapi_handlers( + ${PROJECT_NAME}-handler-secure_objs + NAME secure + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/handlers/secure" + SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src" + SCHEMAS "${CMAKE_CURRENT_SOURCE_DIR}/handlers/secure/openapi.yaml" +) +target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}-handler-secure_objs) # /// [chaotic-handler] # /// [generate-config] diff --git a/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml b/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml index bfc89a822c97..42965b081ae1 100644 --- a/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml +++ b/samples/chaotic_openapi_service/handlers/insecure/openapi.yaml @@ -28,17 +28,6 @@ paths: application/json: schema: $ref: '#/components/schemas/GreetingResponse' - - /secure/greeting: - get: - operationId: greetingGet - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GreetingResponse' components: schemas: GreetingResponse: diff --git a/samples/chaotic_openapi_service/handlers/secure/openapi.yaml b/samples/chaotic_openapi_service/handlers/secure/openapi.yaml new file mode 100644 index 000000000000..857cb948de20 --- /dev/null +++ b/samples/chaotic_openapi_service/handlers/secure/openapi.yaml @@ -0,0 +1,25 @@ +openapi: 3.0.0 +info: + title: Secure handler + version: '1.0' +paths: + /secure/greeting: + get: + operationId: greetingGet + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GreetingResponse' +components: + schemas: + GreetingResponse: + type: object + additionalProperties: false + required: + - greeting + properties: + greeting: + type: string diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index b331535a9712..a8bf08f28781 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include "auth_bearer.hpp" @@ -34,7 +35,8 @@ int main(int argc, char* argv[]) { .Append<::clients::test::Component>() /// [register-client] /// [register-handlers] - .AppendComponentList(::handlers::insecure::ChaoticHandlersList()); + .AppendComponentList(::handlers::insecure::ChaoticHandlersList()) + .Append<::handlers::secure::greetingget::Handler>(); /// [register-handlers] USERVER_NAMESPACE::chaotic::openapi::middlewares::AppendDefaultMiddlewares(component_list); diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp similarity index 77% rename from samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp rename to samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp index 60f5e03cbc9a..8d3f819468f3 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.cpp +++ b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp @@ -2,10 +2,10 @@ #include -#include +#include #include -namespace handlers::insecure::greetingget { +namespace handlers::secure::greetingget { Response View::Handle( Request&& /*request*/, @@ -19,4 +19,4 @@ Response View::Handle( }; } -} // namespace handlers::insecure::greetingget \ No newline at end of file +} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.hpp similarity index 69% rename from samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp rename to samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.hpp index 29016abfcba7..33419634f407 100644 --- a/samples/chaotic_openapi_service/src/handlers/insecure/greetingget/view.hpp +++ b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.hpp @@ -2,12 +2,12 @@ #include -#include -#include +#include +#include #include #include -namespace handlers::insecure::greetingget { +namespace handlers::secure::greetingget { struct HandlerTag; @@ -19,4 +19,4 @@ class View final { static Response Handle(Request&& request, Deps&& deps, RequestContext& context); }; -} // namespace handlers::insecure::greetingget \ No newline at end of file +} // namespace handlers::secure::greetingget \ No newline at end of file diff --git a/samples/chaotic_openapi_service/src/ya.make b/samples/chaotic_openapi_service/src/ya.make index 312ea1e0fc22..9748d1645224 100644 --- a/samples/chaotic_openapi_service/src/ya.make +++ b/samples/chaotic_openapi_service/src/ya.make @@ -19,7 +19,7 @@ SRCS( hello_handler.cpp say_hello.cpp handlers/insecure/insecuresecretpost/view.cpp - handlers/insecure/greetingget/view.cpp + handlers/secure/greetingget/view.cpp ) ADDINCL( @@ -72,7 +72,6 @@ RUN_PROGRAM( ${CHAOTIC_INCLUDES} ${CHAOTIC_OPENAPI_INCLUDES} handlers/insecure/insecuresecretpost/view.hpp - handlers/insecure/greetingget/view.hpp IN_NOPARSE ../handlers/insecure/openapi.yaml OUT @@ -92,13 +91,38 @@ RUN_PROGRAM( src/handlers/insecure/insecuresecretpost/requests.cpp src/handlers/insecure/insecuresecretpost/responses.cpp - include/handlers/insecure/greetingget/handler.hpp - include/handlers/insecure/greetingget/requests.hpp - include/handlers/insecure/greetingget/responses.hpp + config.chaotic.yaml +) + +RUN_PROGRAM( + taxi/uservices/userver/chaotic-openapi/bin + --name secure + --gen handlers + -o ${BINDIR}/handlers/secure + --clang-format '' + ../handlers/secure/openapi.yaml + OUTPUT_INCLUDES + ${CHAOTIC_INCLUDES} + ${CHAOTIC_OPENAPI_INCLUDES} + handlers/secure/greetingget/view.hpp + IN_NOPARSE + ../handlers/secure/openapi.yaml + OUT + include/handlers/secure/openapi.hpp + include/handlers/secure/openapi_fwd.hpp + include/handlers/secure/openapi_parsers.ipp + include/handlers/secure/openapi_sax_parsers.hpp + + src/handlers/secure/openapi.cpp + + include/handlers/secure/greetingget/handler.hpp + include/handlers/secure/chaotic_handlers_list.hpp + include/handlers/secure/greetingget/requests.hpp + include/handlers/secure/greetingget/responses.hpp - src/handlers/insecure/greetingget/handler.cpp - src/handlers/insecure/greetingget/requests.cpp - src/handlers/insecure/greetingget/responses.cpp + src/handlers/secure/greetingget/handler.cpp + src/handlers/secure/greetingget/requests.cpp + src/handlers/secure/greetingget/responses.cpp config.chaotic.yaml ) @@ -106,10 +130,12 @@ RUN_PROGRAM( RUN_PROGRAM( taxi/uservices/userver/scripts/chaotic ${BINDIR}/config.chaotic.yaml + ${BINDIR}/handlers/secure/config.chaotic.yaml ${CURDIR}/../static_config.yaml -o ./config.yaml IN_NOPARSE ${BINDIR}/config.chaotic.yaml + ${BINDIR}/handlers/secure/config.chaotic.yaml ../static_config.yaml OUT config.yaml From c9964659dd72b8cfc1c6c66b7b6b91cfa7046dfd Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 19:16:21 +0300 Subject: [PATCH 14/22] feat(samples): validate bearer tokens against secdist in chaotic_openapi_service The auth checker no longer accepts an arbitrary numeric bearer token. The token is now an opaque string that is validated against the 'tokens' section of the secdist config, mapping tokens to user ids, similarly to the built-in apikey checker. --- samples/chaotic_openapi_service/main.cpp | 4 ++ .../src/auth_bearer.cpp | 54 +++++++++++++++---- .../src/auth_bearer.hpp | 8 ++- .../static_config.user.yaml | 4 ++ .../testsuite/conftest.py | 13 +++++ .../testsuite/test_auth.py | 9 +++- 6 files changed, 78 insertions(+), 14 deletions(-) diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index a8bf08f28781..156df167894e 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -25,6 +27,8 @@ int main(int argc, char* argv[]) { .Append() .Append() .Append() + .Append() + .Append() .AppendComponentList(USERVER_NAMESPACE::clients::http::ComponentList()) .Append() /// [register-qos] diff --git a/samples/chaotic_openapi_service/src/auth_bearer.cpp b/samples/chaotic_openapi_service/src/auth_bearer.cpp index af5746d00ff7..264407d7409b 100644 --- a/samples/chaotic_openapi_service/src/auth_bearer.cpp +++ b/samples/chaotic_openapi_service/src/auth_bearer.cpp @@ -3,23 +3,54 @@ #include #include #include +#include +#include +#include #include #include #include +#include namespace samples::auth { +namespace { + +// Bearer tokens to user ids mapping from the 'tokens' section of the secdist config. +class AuthTokens final { +public: + explicit AuthTokens(const formats::json::Value& data) { + const auto tokens = data["tokens"]; + if (!tokens.IsObject()) { + return; + } + for (const auto& [token, user_id] : Items(tokens)) { + tokens_.emplace(token, user_id.As()); + } + } + + const std::unordered_map& Get() const { return tokens_; } + +private: + std::unordered_map tokens_; +}; + class AuthCheckerBearer final : public server::handlers::auth::AuthCheckerBase { public: using AuthCheckResult = server::handlers::auth::AuthCheckResult; + explicit AuthCheckerBearer(std::unordered_map tokens) + : tokens_(std::move(tokens)) {} + [[nodiscard]] AuthCheckResult CheckAuth( const server::http::HttpRequest& request, server::request::RequestContext& request_context ) const override; [[nodiscard]] bool SupportsUserAuth() const noexcept override { return true; } + +private: + const std::unordered_map tokens_; }; AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( @@ -28,8 +59,7 @@ AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( ) const { const auto& auth_value = request.GetHeader(http::headers::kAuthorization); constexpr std::string_view kBearerPrefix = "Bearer "; - if (auth_value.size() <= kBearerPrefix.size() || - std::string_view{auth_value}.substr(0, kBearerPrefix.size()) != kBearerPrefix) { + if (!auth_value.starts_with(kBearerPrefix)) { return AuthCheckResult{ AuthCheckResult::Status::kTokenNotFound, {}, @@ -38,14 +68,13 @@ AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( }; } - std::uint64_t user_id = 0; - try { - user_id = std::stoull(std::string{auth_value.substr(kBearerPrefix.size())}); - } catch (const std::exception&) { + const std::string_view token{auth_value.data() + kBearerPrefix.size(), auth_value.size() - kBearerPrefix.size()}; + const auto it = tokens_.find(std::string{token}); + if (it == tokens_.end()) { return AuthCheckResult{ AuthCheckResult::Status::kInvalidToken, {}, - "User id in the token must be an integer", + "Unknown bearer token", server::handlers::HandlerErrorCode::kUnauthorized, }; } @@ -53,7 +82,7 @@ AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( SetUserAuthInfo( request_context, server::auth::UserAuthInfo{ - server::auth::UserId{user_id}, + server::auth::UserId{it->second}, server::auth::UserEnv::kProd, server::auth::UserProvider::kYandex, } @@ -61,12 +90,15 @@ AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( return {}; } -CheckerFactory::CheckerFactory(const components::ComponentContext&) {} +} // namespace + +CheckerFactory::CheckerFactory(const components::ComponentContext& context) + : tokens_(context.FindComponent().Get().Get().Get()) {} server::handlers::auth::AuthCheckerBasePtr CheckerFactory::MakeAuthChecker( const server::handlers::auth::HandlerAuthConfig& ) const { - return std::make_shared(); + return std::make_shared(tokens_); } -} // namespace samples::auth \ No newline at end of file +} // namespace samples::auth diff --git a/samples/chaotic_openapi_service/src/auth_bearer.hpp b/samples/chaotic_openapi_service/src/auth_bearer.hpp index 6ee02150aca6..b0d756213bcc 100644 --- a/samples/chaotic_openapi_service/src/auth_bearer.hpp +++ b/samples/chaotic_openapi_service/src/auth_bearer.hpp @@ -1,6 +1,9 @@ #pragma once +#include +#include #include +#include #include #include @@ -16,6 +19,9 @@ class CheckerFactory final : public server::handlers::auth::AuthCheckerFactoryBa server::handlers::auth::AuthCheckerBasePtr MakeAuthChecker( const server::handlers::auth::HandlerAuthConfig& auth_config ) const override; + +private: + std::unordered_map tokens_; }; -} // namespace samples::auth \ No newline at end of file +} // namespace samples::auth diff --git a/samples/chaotic_openapi_service/static_config.user.yaml b/samples/chaotic_openapi_service/static_config.user.yaml index 949121ae7926..5cb94ccedf87 100644 --- a/samples/chaotic_openapi_service/static_config.user.yaml +++ b/samples/chaotic_openapi_service/static_config.user.yaml @@ -24,6 +24,10 @@ components_manager: dns-client: fs-task-processor: fs-task-processor + default-secdist-provider: # Component that loads secrets from secdist. + config: /etc/chaotic_openapi_service/secdist.json # Values are supposed to be stored in this file + missing-ok: true # ... but if the file is missing it is still ok + environment-secrets-key: SECDIST_CONFIG # ... values will be loaded from this environment value http-client: http-client-core: fs-task-processor: fs-task-processor diff --git a/samples/chaotic_openapi_service/testsuite/conftest.py b/samples/chaotic_openapi_service/testsuite/conftest.py index 55c869b40384..45264beed316 100644 --- a/samples/chaotic_openapi_service/testsuite/conftest.py +++ b/samples/chaotic_openapi_service/testsuite/conftest.py @@ -1,3 +1,5 @@ +import json + import pytest pytest_plugins = ['pytest_userver.plugins.core'] @@ -14,3 +16,14 @@ def do_patch(config_yaml, config_vars): return do_patch # /// [URL] + + +@pytest.fixture(scope='session') +def service_env(): + secdist_config = { + 'tokens': { + 'user-1-token': 123, + }, + } + + return {'SECDIST_CONFIG': json.dumps(secdist_config)} diff --git a/samples/chaotic_openapi_service/testsuite/test_auth.py b/samples/chaotic_openapi_service/testsuite/test_auth.py index 89187d1656ab..22c01cbab894 100644 --- a/samples/chaotic_openapi_service/testsuite/test_auth.py +++ b/samples/chaotic_openapi_service/testsuite/test_auth.py @@ -8,7 +8,12 @@ async def test_greeting_with_bad_token(service_client): assert response.status == 401 +async def test_greeting_with_unknown_token(service_client): + response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer unknown-token'}) + assert response.status == 401 + + async def test_greeting_with_auth(service_client): - response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer 123'}) + response = await service_client.get('/secure/greeting', headers={'Authorization': 'Bearer user-1-token'}) assert response.status == 200 - assert response.json()['greeting'] == 'Hello, user 123!' \ No newline at end of file + assert response.json()['greeting'] == 'Hello, user 123!' From db145ae2c526e4994d2ae03a3774544fa881ed1a Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Mon, 17 Aug 2026 19:16:27 +0300 Subject: [PATCH 15/22] feat(chaotic-openapi): add ChaoticHandlersListWithoutFactories() When several schemas are used in one service, the chaotic-openapi dependency-injection container must be registered only once. The new function returns the handlers component list without the container, so it can be combined with another schema's ChaoticHandlersList(). --- .../templates/chaotic_handlers_list.hpp.jinja | 23 +++++++++++++++---- .../handlers/test/chaotic_handlers_list.hpp | 19 +++++++++++++-- samples/chaotic_openapi_service/main.cpp | 4 ++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja index 8741774cb2b4..8818146d1629 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja @@ -9,6 +9,24 @@ namespace {{ spec.cpp_namespace }} { +/// @brief Returns the component list with all generated handlers, without +/// registering the chaotic-openapi dependency-injection container. +/// +/// Use it when the container is already registered by another schema, e.g. +/// when combining handlers generated from several schemas in one service: +/// @code +/// component_list +/// .AppendComponentList(handlers::insecure::ChaoticHandlersList()) +/// .AppendComponentList(handlers::secure::ChaoticHandlersListWithoutFactories()); +/// @endcode +inline {{ userver }}::components::ComponentList ChaoticHandlersListWithoutFactories() { + return {{ userver }}::components::ComponentList() +{% for op in spec.operations %} + .Append<{{ spec.cpp_namespace }}::{{ op.cpp_namespace() }}::Handler>() +{% endfor %} + ; +} + /// @brief Returns the component list with all generated handlers /// and the chaotic-openapi dependency-injection container. /// @@ -20,10 +38,7 @@ inline {{ userver }}::components::ComponentList ChaoticHandlersList() { return {{ userver }}::components::ComponentList() .Append<{{ userver }}::components::Container< {{ userver }}::chaotic::openapi::server::dependencies::Factories>>() -{% for op in spec.operations %} - .Append<{{ spec.cpp_namespace }}::{{ op.cpp_namespace() }}::Handler>() -{% endfor %} - ; + .AppendComponentList(ChaoticHandlersListWithoutFactories()); } } // namespace {{ spec.cpp_namespace }} diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp index 05e6cc5c9511..d67d4a51ce12 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp @@ -8,6 +8,22 @@ namespace handlers::test { +/// @brief Returns the component list with all generated handlers, without +/// registering the chaotic-openapi dependency-injection container. +/// +/// Use it when the container is already registered by another schema, e.g. +/// when combining handlers generated from several schemas in one service: +/// @code +/// component_list +/// .AppendComponentList(handlers::insecure::ChaoticHandlersList()) +/// .AppendComponentList(handlers::secure::ChaoticHandlersListWithoutFactories()); +/// @endcode +inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersListWithoutFactories() { +return USERVER_NAMESPACE::components::ComponentList() +.Append() +; +} + /// @brief Returns the component list with all generated handlers /// and the chaotic-openapi dependency-injection container. /// @@ -19,8 +35,7 @@ inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersList() { return USERVER_NAMESPACE::components::ComponentList() .Append>() -.Append() -; +.AppendComponentList(ChaoticHandlersListWithoutFactories()); } } // namespace handlers::test diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index 156df167894e..d4afcc8ebf56 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include "auth_bearer.hpp" @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) { /// [register-client] /// [register-handlers] .AppendComponentList(::handlers::insecure::ChaoticHandlersList()) - .Append<::handlers::secure::greetingget::Handler>(); + .AppendComponentList(::handlers::secure::ChaoticHandlersListWithoutFactories()); /// [register-handlers] USERVER_NAMESPACE::chaotic::openapi::middlewares::AppendDefaultMiddlewares(component_list); From e602b54a615101fcf2a82c3b0d450dccbeaec817 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Tue, 18 Aug 2026 14:12:21 +0300 Subject: [PATCH 16/22] ERROR --- .../templates/chaotic_handlers_list.hpp.jinja | 23 ++++--------------- .../handlers/test/chaotic_handlers_list.hpp | 19 ++------------- samples/chaotic_openapi_service/main.cpp | 2 +- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja index 8818146d1629..8741774cb2b4 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja @@ -9,24 +9,6 @@ namespace {{ spec.cpp_namespace }} { -/// @brief Returns the component list with all generated handlers, without -/// registering the chaotic-openapi dependency-injection container. -/// -/// Use it when the container is already registered by another schema, e.g. -/// when combining handlers generated from several schemas in one service: -/// @code -/// component_list -/// .AppendComponentList(handlers::insecure::ChaoticHandlersList()) -/// .AppendComponentList(handlers::secure::ChaoticHandlersListWithoutFactories()); -/// @endcode -inline {{ userver }}::components::ComponentList ChaoticHandlersListWithoutFactories() { - return {{ userver }}::components::ComponentList() -{% for op in spec.operations %} - .Append<{{ spec.cpp_namespace }}::{{ op.cpp_namespace() }}::Handler>() -{% endfor %} - ; -} - /// @brief Returns the component list with all generated handlers /// and the chaotic-openapi dependency-injection container. /// @@ -38,7 +20,10 @@ inline {{ userver }}::components::ComponentList ChaoticHandlersList() { return {{ userver }}::components::ComponentList() .Append<{{ userver }}::components::Container< {{ userver }}::chaotic::openapi::server::dependencies::Factories>>() - .AppendComponentList(ChaoticHandlersListWithoutFactories()); +{% for op in spec.operations %} + .Append<{{ spec.cpp_namespace }}::{{ op.cpp_namespace() }}::Handler>() +{% endfor %} + ; } } // namespace {{ spec.cpp_namespace }} diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp index d67d4a51ce12..05e6cc5c9511 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp @@ -8,22 +8,6 @@ namespace handlers::test { -/// @brief Returns the component list with all generated handlers, without -/// registering the chaotic-openapi dependency-injection container. -/// -/// Use it when the container is already registered by another schema, e.g. -/// when combining handlers generated from several schemas in one service: -/// @code -/// component_list -/// .AppendComponentList(handlers::insecure::ChaoticHandlersList()) -/// .AppendComponentList(handlers::secure::ChaoticHandlersListWithoutFactories()); -/// @endcode -inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersListWithoutFactories() { -return USERVER_NAMESPACE::components::ComponentList() -.Append() -; -} - /// @brief Returns the component list with all generated handlers /// and the chaotic-openapi dependency-injection container. /// @@ -35,7 +19,8 @@ inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersList() { return USERVER_NAMESPACE::components::ComponentList() .Append>() -.AppendComponentList(ChaoticHandlersListWithoutFactories()); +.Append() +; } } // namespace handlers::test diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index d4afcc8ebf56..5fd695be9d15 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) { /// [register-client] /// [register-handlers] .AppendComponentList(::handlers::insecure::ChaoticHandlersList()) - .AppendComponentList(::handlers::secure::ChaoticHandlersListWithoutFactories()); + .AppendComponentList(::handlers::secure::ChaoticHandlersList()); /// [register-handlers] USERVER_NAMESPACE::chaotic::openapi::middlewares::AppendDefaultMiddlewares(component_list); From a6913d906f6dc1a88dc9ae653a6aafd2c0a41689 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Tue, 18 Aug 2026 20:23:24 +0300 Subject: [PATCH 17/22] fix(chopen)/fix ch-openapi factories --- .../back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja | 2 -- samples/chaotic_openapi_service/CMakeLists.txt | 1 + samples/chaotic_openapi_service/main.cpp | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja index 8741774cb2b4..9a3ee9d920e9 100644 --- a/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja +++ b/chaotic-openapi/chaotic_openapi/back/cpp/handler/templates/chaotic_handlers_list.hpp.jinja @@ -18,8 +18,6 @@ namespace {{ spec.cpp_namespace }} { /// @endcode inline {{ userver }}::components::ComponentList ChaoticHandlersList() { return {{ userver }}::components::ComponentList() - .Append<{{ userver }}::components::Container< - {{ userver }}::chaotic::openapi::server::dependencies::Factories>>() {% for op in spec.operations %} .Append<{{ spec.cpp_namespace }}::{{ op.cpp_namespace() }}::Handler>() {% endfor %} diff --git a/samples/chaotic_openapi_service/CMakeLists.txt b/samples/chaotic_openapi_service/CMakeLists.txt index 093a0dfbfe74..143c3acea641 100644 --- a/samples/chaotic_openapi_service/CMakeLists.txt +++ b/samples/chaotic_openapi_service/CMakeLists.txt @@ -54,3 +54,4 @@ userver_generate_config_yaml( # /// [generate-config] userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") +add_dependencies(runtests-${PROJECT_NAME} ${PROJECT_NAME}_config) diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index 5fd695be9d15..914af5aa156f 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -39,6 +40,7 @@ int main(int argc, char* argv[]) { .Append<::clients::test::Component>() /// [register-client] /// [register-handlers] + .Append>() .AppendComponentList(::handlers::insecure::ChaoticHandlersList()) .AppendComponentList(::handlers::secure::ChaoticHandlersList()); /// [register-handlers] From 5f22fad46bb3f72c61bc8fb9c70aa49c9f6889e8 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Tue, 18 Aug 2026 20:54:03 +0300 Subject: [PATCH 18/22] fix: bad config add --- samples/chaotic_openapi_service/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/chaotic_openapi_service/CMakeLists.txt b/samples/chaotic_openapi_service/CMakeLists.txt index 143c3acea641..32b0a0ebf352 100644 --- a/samples/chaotic_openapi_service/CMakeLists.txt +++ b/samples/chaotic_openapi_service/CMakeLists.txt @@ -53,5 +53,4 @@ userver_generate_config_yaml( ) # /// [generate-config] -userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") -add_dependencies(runtests-${PROJECT_NAME} ${PROJECT_NAME}_config) +userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") \ No newline at end of file From 07f8538e21b1060ee1586e5dd8321daa334a786a Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Wed, 19 Aug 2026 01:24:06 +0300 Subject: [PATCH 19/22] fix(chaotic): build config.yaml with the service binary userver_generate_config_yaml() created an ALL custom target, so config.yaml was only produced by a full build. Building just the service binary (the common workflow before running ctest) left config.yaml missing and broke the testsuite. Make the binary depend on the generated config. Regenerate the chaotic-openapi golden output: commit a6913d906 dropped the components::Container append from the template without updating the golden file. --- .../handlers/include/handlers/test/chaotic_handlers_list.hpp | 2 -- cmake/ChaoticGen.cmake | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp index 05e6cc5c9511..22117f198f16 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp @@ -17,8 +17,6 @@ namespace handlers::test { /// @endcode inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersList() { return USERVER_NAMESPACE::components::ComponentList() -.Append>() .Append() ; } diff --git a/cmake/ChaoticGen.cmake b/cmake/ChaoticGen.cmake index 37ffe0a06008..8ef67ba8b177 100644 --- a/cmake/ChaoticGen.cmake +++ b/cmake/ChaoticGen.cmake @@ -477,6 +477,7 @@ function(userver_generate_config_yaml BINARY_TARGET) VERBATIM ) add_custom_target("${BINARY_TARGET}_config" ALL DEPENDS "${PARSE_OUTPUT}") + add_dependencies("${BINARY_TARGET}" "${BINARY_TARGET}_config") endfunction() function(_userver_collect_extra_config_yamls_impl TARGET) From e5879d99cb432782aded6ef00c5d6b59aa1e7ffe Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Thu, 20 Aug 2026 17:14:19 +0300 Subject: [PATCH 20/22] fix(chgen): reformat --- samples/chaotic_openapi_service/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/chaotic_openapi_service/CMakeLists.txt b/samples/chaotic_openapi_service/CMakeLists.txt index 32b0a0ebf352..128797d9f1b6 100644 --- a/samples/chaotic_openapi_service/CMakeLists.txt +++ b/samples/chaotic_openapi_service/CMakeLists.txt @@ -53,4 +53,5 @@ userver_generate_config_yaml( ) # /// [generate-config] -userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") \ No newline at end of file +userver_testsuite_add_simple(CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/config.yaml") + From 886232a0a16290dd452d2756d989c343c88afcdf Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Thu, 20 Aug 2026 17:46:45 +0300 Subject: [PATCH 21/22] fix(chgen): reformat code --- .../handlers/test/testme/post/view.cpp | 9 ++-- .../handlers/test/testme/post/view.hpp | 46 +++++++++---------- .../handlers/test/chaotic_handlers_list.hpp | 4 +- .../chaotic/openapi/server/handler_base.hpp | 3 +- .../src/handlers/simple/headersget/view.cpp | 6 +-- samples/chaotic_openapi_service/main.cpp | 5 +- .../src/auth_bearer.cpp | 8 ++-- .../src/handlers/secure/greetingget/view.cpp | 6 +-- 8 files changed, 36 insertions(+), 51 deletions(-) diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp index 6ba3fe227cf5..c5fae7ba5ea8 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp @@ -2,12 +2,9 @@ namespace handlers::test::testme::post { -Response View::Handle( -Request&& /*request*/, -Deps&& /*deps*/, -RequestContext& /*context*/) { -// Handle request using dependencies from Deps (clients, caches, configs, databases...) -return {}; +Response View::Handle(Request&& /*request*/, Deps&& /*deps*/, RequestContext& /*context*/) { + // Handle request using dependencies from Deps (clients, caches, configs, databases...) + return {}; } /* diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp index a258edcad9c1..92ac44932a8a 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp @@ -2,12 +2,12 @@ #include +#include +#include #include +#include #include #include -#include -#include -#include namespace handlers::test::testme::post { @@ -15,26 +15,26 @@ struct HandlerTag; class View final { public: -using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; -using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - -static Response Handle(Request&& request, Deps&& deps, RequestContext& context); - -/* Uncomment, if you want to define a custom logging for request/response body. -* E.g. you want to log several fields, but omit the others (secrets, etc.). -* -static std::string GetRequestBodyForLogging( -const USERVER_NAMESPACE::formats::json::Value& body); - -// Logger for 'invalid JSON body' request -static std::string GetInvalidRequestBodyForLogging( -const USERVER_NAMESPACE::server::http::HttpRequest& request); - -static std::string GetResponseForLogging( -const Response& response, -const std::string& serialized_response, -RequestContext& context); -*/ + using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; + + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); + + /* Uncomment, if you want to define a custom logging for request/response body. + * E.g. you want to log several fields, but omit the others (secrets, etc.). + * + static std::string GetRequestBodyForLogging( + const USERVER_NAMESPACE::formats::json::Value& body); + + // Logger for 'invalid JSON body' request + static std::string GetInvalidRequestBodyForLogging( + const USERVER_NAMESPACE::server::http::HttpRequest& request); + + static std::string GetResponseForLogging( + const Response& response, + const std::string& serialized_response, + RequestContext& context); + */ }; } // namespace handlers::test::testme::post diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp index 22117f198f16..4cd3ff3035e8 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp @@ -16,9 +16,7 @@ namespace handlers::test { /// component_list.AppendComponentList(handlers::test::ChaoticHandlersList()); /// @endcode inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersList() { -return USERVER_NAMESPACE::components::ComponentList() -.Append() -; + return USERVER_NAMESPACE::components::ComponentList().Append(); } } // namespace handlers::test diff --git a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp index a9f7a5cc411f..d7c4c1e96073 100644 --- a/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp +++ b/chaotic-openapi/include/userver/chaotic/openapi/server/handler_base.hpp @@ -121,8 +121,7 @@ class BaseHandler final : public USERVER_NAMESPACE::server::handlers::HttpHandle const USERVER_NAMESPACE::components::ComponentContext& context ) : USERVER_NAMESPACE::server::handlers::HttpHandlerBase(config, context), - factories_(context.FindComponent()) - {} + factories_(context.FindComponent()) {} ~BaseHandler() override = default; diff --git a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp index 333bd789b61e..566cc16eea06 100644 --- a/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp +++ b/chaotic-openapi/integration_tests/src/handlers/simple/headersget/view.cpp @@ -2,11 +2,7 @@ namespace handlers::simple::headersget { -Response View::Handle( - Request&& /*request*/, - Deps&& /*deps*/, - RequestContext& context -) { +Response View::Handle(Request&& /*request*/, Deps&& /*deps*/, RequestContext& context) { Response200 response; const auto* user_id = context.GetDataOptional("x-user-id"); response.X_String = user_id ? *user_id : ""; diff --git a/samples/chaotic_openapi_service/main.cpp b/samples/chaotic_openapi_service/main.cpp index 914af5aa156f..966330e2d198 100644 --- a/samples/chaotic_openapi_service/main.cpp +++ b/samples/chaotic_openapi_service/main.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include #include #include @@ -40,7 +40,8 @@ int main(int argc, char* argv[]) { .Append<::clients::test::Component>() /// [register-client] /// [register-handlers] - .Append>() + .Append>() .AppendComponentList(::handlers::insecure::ChaoticHandlersList()) .AppendComponentList(::handlers::secure::ChaoticHandlersList()); /// [register-handlers] diff --git a/samples/chaotic_openapi_service/src/auth_bearer.cpp b/samples/chaotic_openapi_service/src/auth_bearer.cpp index 264407d7409b..a98082676b37 100644 --- a/samples/chaotic_openapi_service/src/auth_bearer.cpp +++ b/samples/chaotic_openapi_service/src/auth_bearer.cpp @@ -39,8 +39,7 @@ class AuthCheckerBearer final : public server::handlers::auth::AuthCheckerBase { public: using AuthCheckResult = server::handlers::auth::AuthCheckResult; - explicit AuthCheckerBearer(std::unordered_map tokens) - : tokens_(std::move(tokens)) {} + explicit AuthCheckerBearer(std::unordered_map tokens) : tokens_(std::move(tokens)) {} [[nodiscard]] AuthCheckResult CheckAuth( const server::http::HttpRequest& request, @@ -95,9 +94,8 @@ AuthCheckerBearer::AuthCheckResult AuthCheckerBearer::CheckAuth( CheckerFactory::CheckerFactory(const components::ComponentContext& context) : tokens_(context.FindComponent().Get().Get().Get()) {} -server::handlers::auth::AuthCheckerBasePtr CheckerFactory::MakeAuthChecker( - const server::handlers::auth::HandlerAuthConfig& -) const { +server::handlers::auth::AuthCheckerBasePtr +CheckerFactory::MakeAuthChecker(const server::handlers::auth::HandlerAuthConfig&) const { return std::make_shared(tokens_); } diff --git a/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp index 8d3f819468f3..c7c8a0fa7527 100644 --- a/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp +++ b/samples/chaotic_openapi_service/src/handlers/secure/greetingget/view.cpp @@ -7,11 +7,7 @@ namespace handlers::secure::greetingget { -Response View::Handle( - Request&& /*request*/, - Deps&& /*deps*/, - RequestContext& context -) { +Response View::Handle(Request&& /*request*/, Deps&& /*deps*/, RequestContext& context) { const auto& auth_info = USERVER_NAMESPACE::server::auth::GetUserAuthInfo(context); const auto user_id = auth_info.GetDefaultUserId(); return Response200{ From 460e61012909f8f5577418f9a51b8d8d92651316 Mon Sep 17 00:00:00 2001 From: Michael lemito Date: Fri, 21 Aug 2026 14:29:39 +0300 Subject: [PATCH 22/22] fix(chgen): regenerate golden tests output with formatting --- chaotic-openapi/golden_tests/CMakeLists.txt | 4 +- .../client/include/clients/test/client.hpp | 16 +-- .../include/clients/test/client_fwd.hpp | 2 +- .../include/clients/test/client_impl.hpp | 55 +++++----- .../client/include/clients/test/component.hpp | 24 ++--- .../include/clients/test/exceptions.hpp | 53 ++++----- .../client/include/clients/test/openapi.hpp | 10 +- .../include/clients/test/openapi_fwd.hpp | 7 +- .../include/clients/test/openapi_parsers.ipp | 9 +- .../clients/test/openapi_sax_parsers.hpp | 11 +- .../client/include/clients/test/qos.hpp | 2 +- .../client/include/clients/test/requests.hpp | 25 ++--- .../client/include/clients/test/responses.hpp | 21 ++-- .../client/src/clients/test/client_impl.cpp | 40 ++++--- .../client/src/clients/test/component.cpp | 101 ++++++++---------- .../client/src/clients/test/exceptions.cpp | 15 +-- .../client/src/clients/test/openapi.cpp | 11 +- .../client/src/clients/test/requests.cpp | 34 +++--- .../client/src/clients/test/responses.cpp | 47 ++++---- .../handlers/test/testme/post/view.cpp | 30 +++--- .../handlers/test/testme/post/view.hpp | 45 ++++---- .../handlers/test/chaotic_handlers_list.hpp | 2 +- .../include/handlers/test/openapi.hpp | 10 +- .../include/handlers/test/openapi_fwd.hpp | 7 +- .../include/handlers/test/openapi_parsers.ipp | 9 +- .../handlers/test/openapi_sax_parsers.hpp | 11 +- .../handlers/test/testme/post/handler.hpp | 10 +- .../handlers/test/testme/post/requests.hpp | 16 ++- .../handlers/test/testme/post/responses.hpp | 11 +- .../handlers/src/handlers/test/openapi.cpp | 11 +- .../handlers/test/testme/post/requests.cpp | 24 ++--- .../handlers/test/testme/post/responses.cpp | 30 +++--- 32 files changed, 332 insertions(+), 371 deletions(-) diff --git a/chaotic-openapi/golden_tests/CMakeLists.txt b/chaotic-openapi/golden_tests/CMakeLists.txt index 0ce9100a7713..cf569cf83b76 100644 --- a/chaotic-openapi/golden_tests/CMakeLists.txt +++ b/chaotic-openapi/golden_tests/CMakeLists.txt @@ -9,7 +9,7 @@ userver_target_generate_openapi_client( ${PROJECT_NAME}-chgen-client NAME test OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/src/client" - FORMAT OFF + FORMAT ON SCHEMAS ${SCHEMAS} ) @@ -18,7 +18,7 @@ userver_target_generate_openapi_handlers( NAME test OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/src/handlers" SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/src/handlers" - FORMAT OFF + FORMAT ON SCHEMAS ${SCHEMAS} ) diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/client.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/client.hpp index 287d392fd44e..6f500673eaf0 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/client.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/client.hpp @@ -1,20 +1,22 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once +#include + #include "requests.hpp" #include "responses.hpp" -#include - namespace clients::test { class Client { -public: - /// POST /testme - /// A testing method to call - /// @throw testme::post::Exception + public: + /// POST /testme + /// A testing method to call + /// @throw testme::post::Exception - virtual testme::post::Response TestmePost(const testme::post::Request& request , const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control = {}) = 0; + virtual testme::post::Response TestmePost( + const testme::post::Request& request, + const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control = {}) = 0; virtual ~Client(); }; diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/client_fwd.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/client_fwd.hpp index ae04fca0c853..ad609574ced3 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/client_fwd.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/client_fwd.hpp @@ -5,4 +5,4 @@ namespace clients::test { class Client; -} // namespace clients::test +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/client_impl.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/client_impl.hpp index af6886e2c8e7..ea09376a6910 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/client_impl.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/client_impl.hpp @@ -2,47 +2,50 @@ #pragma once #include - #include #include +#include #include #include -#include - namespace clients::test { class ClientImpl final : public Client { -public: -// API + public: + // API -testme::post::Response TestmePost(const testme::post::Request& request , const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control = {} -) override; + testme::post::Response TestmePost( + const testme::post::Request& request, + const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control = {}) override; -// end of API + // end of API -static constexpr std::string_view kName = "test"; -static constexpr std::string_view kDefaultBaseUrl = "http://example.com"; + static constexpr std::string_view kName = "test"; + static constexpr std::string_view kDefaultBaseUrl = "http://example.com"; -ClientImpl(const USERVER_NAMESPACE::chaotic::openapi::client::Config& config, - USERVER_NAMESPACE::clients::http::Client& http_client); + ClientImpl(const USERVER_NAMESPACE::chaotic::openapi::client::Config& config, + USERVER_NAMESPACE::clients::http::Client& http_client); -static USERVER_NAMESPACE::yaml_config::Schema GetStaticConfigSchema(); + static USERVER_NAMESPACE::yaml_config::Schema GetStaticConfigSchema(); -void RegisterMiddleware(std::shared_ptr middleware) { -middleware_manager_.RegisterMiddleware(middleware); -} + void RegisterMiddleware(std::shared_ptr middleware) { + middleware_manager_.RegisterMiddleware(middleware); + } -void SetCoreMiddlewares(std::optional>> core_middlewares) { -core_middlewares_ = std::move(core_middlewares); -} + void SetCoreMiddlewares( + std::optional>> + core_middlewares) { + core_middlewares_ = std::move(core_middlewares); + } -private: -USERVER_NAMESPACE::chaotic::openapi::client::Config config_; -USERVER_NAMESPACE::clients::http::Client& http_client_; -USERVER_NAMESPACE::chaotic::openapi::MiddlewareManager middleware_manager_; -std::unordered_map> middlewares_; -std::optional>> core_middlewares_; + private: + USERVER_NAMESPACE::chaotic::openapi::client::Config config_; + USERVER_NAMESPACE::clients::http::Client& http_client_; + USERVER_NAMESPACE::chaotic::openapi::MiddlewareManager middleware_manager_; + std::unordered_map> + middlewares_; + std::optional>> + core_middlewares_; }; -} +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/component.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/component.hpp index 53effde5c49b..a7acb74fc194 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/component.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/component.hpp @@ -1,29 +1,29 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once +#include #include #include -#include - namespace clients::test { class Component final : public USERVER_NAMESPACE::components::ComponentBase { -public: - static constexpr std::string_view kName = "test-client"; + public: + static constexpr std::string_view kName = "test-client"; - Component(const USERVER_NAMESPACE::components::ComponentConfig& config, const USERVER_NAMESPACE::components::ComponentContext& context); + Component(const USERVER_NAMESPACE::components::ComponentConfig& config, + const USERVER_NAMESPACE::components::ComponentContext& context); - Client& GetClient(); + Client& GetClient(); - static USERVER_NAMESPACE::yaml_config::Schema GetStaticConfigSchema(); + static USERVER_NAMESPACE::yaml_config::Schema GetStaticConfigSchema(); -private: - ClientImpl client_; + private: + ClientImpl client_; }; } // namespace clients::test -template<> -inline constexpr auto USERVER_NAMESPACE::components::kConfigFileMode<::clients::test::Component> - = USERVER_NAMESPACE::components::ConfigFileMode::kNotRequired; +template <> +inline constexpr auto USERVER_NAMESPACE::components::kConfigFileMode<::clients::test::Component> = + USERVER_NAMESPACE::components::ConfigFileMode::kNotRequired; diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/exceptions.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/exceptions.hpp index d8052c29273a..b5008726d339 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/exceptions.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/exceptions.hpp @@ -6,28 +6,26 @@ namespace clients::test { /// @brief Base class for test client exceptions -class Exception: public USERVER_NAMESPACE::chaotic::openapi::client::Exception { +class Exception : public USERVER_NAMESPACE::chaotic::openapi::client::Exception { public: using USERVER_NAMESPACE::chaotic::openapi::client::Exception::Exception; ~Exception(); }; /// @brief Response with ErrorKind for test client exceptions -class HttpException : public USERVER_NAMESPACE::chaotic::openapi::client::HttpException -{ +class HttpException : public USERVER_NAMESPACE::chaotic::openapi::client::HttpException { public: - explicit HttpException(USERVER_NAMESPACE::clients::http::ErrorKind error_kind); + explicit HttpException(USERVER_NAMESPACE::clients::http::ErrorKind error_kind); }; /// @brief Response with HTTP status code for test client exceptions -class ExceptionWithStatusCode : public USERVER_NAMESPACE::chaotic::openapi::client::ExceptionWithStatusCode -{ +class ExceptionWithStatusCode : public USERVER_NAMESPACE::chaotic::openapi::client::ExceptionWithStatusCode { public: - ExceptionWithStatusCode(int status_code); + ExceptionWithStatusCode(int status_code); }; /// @brief Timeout exception class for test client exceptions -class TimeoutException: public USERVER_NAMESPACE::chaotic::openapi::client::TimeoutException { +class TimeoutException : public USERVER_NAMESPACE::chaotic::openapi::client::TimeoutException { public: using USERVER_NAMESPACE::chaotic::openapi::client::TimeoutException::TimeoutException; ~TimeoutException(); @@ -36,41 +34,32 @@ class TimeoutException: public USERVER_NAMESPACE::chaotic::openapi::client::Time namespace testme::post { /// @brief Base exception class for all client POST operations with URL '/testme' -class Exception: public ::clients::test::Exception { +class Exception : public ::clients::test::Exception { public: - const char* what() const noexcept override; + const char* what() const noexcept override; - static constexpr USERVER_NAMESPACE::utils::zstring_view kHandlerInfo{"POST /testme"}; + static constexpr USERVER_NAMESPACE::utils::zstring_view kHandlerInfo{"POST /testme"}; }; /// @brief Error response with ErrorKind for all client POST operations with URL '/testme' -class HttpException - : public Exception - , public ::clients::test::HttpException -{ - public: - using ::clients::test::HttpException::HttpException; - ~HttpException(); +class HttpException : public Exception, public ::clients::test::HttpException { + public: + using ::clients::test::HttpException::HttpException; + ~HttpException(); }; /// @brief Timeout exception class for all client POST operations with URL '/testme' -class TimeoutException - : public HttpException - , public ::clients::test::TimeoutException -{ - public: - TimeoutException(); - ~TimeoutException(); +class TimeoutException : public HttpException, public ::clients::test::TimeoutException { + public: + TimeoutException(); + ~TimeoutException(); }; /// @brief Error response with HTTP status code for all client POST operations with URL '/testme' -class ExceptionWithStatusCode - : public Exception - , public ::clients::test::ExceptionWithStatusCode -{ - public: - using ::clients::test::ExceptionWithStatusCode::ExceptionWithStatusCode; - ~ExceptionWithStatusCode(); +class ExceptionWithStatusCode : public Exception, public ::clients::test::ExceptionWithStatusCode { + public: + using ::clients::test::ExceptionWithStatusCode::ExceptionWithStatusCode; + ~ExceptionWithStatusCode(); }; } // namespace testme::post diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi.hpp index 1eff69f4bfdc..01c01fc18c32 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi.hpp @@ -1,14 +1,16 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "clients/test/openapi_fwd.hpp" - #include #include - #include -namespace clients {namespace test {namespace testme {namespace post { +#include "clients/test/openapi_fwd.hpp" + +namespace clients { +namespace test { +namespace testme { +namespace post { using Parameter1 = std::vector; diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_fwd.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_fwd.hpp index 81972c8a4194..3a9956cfaec1 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_fwd.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_fwd.hpp @@ -1,9 +1,10 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -namespace clients {namespace test {namespace testme {namespace post { - -} // namespace post +namespace clients { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace clients diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_parsers.ipp b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_parsers.ipp index d409489a4259..f67ad3d8be28 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_parsers.ipp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_parsers.ipp @@ -1,16 +1,17 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "clients/test/openapi.hpp" - #include #include #include #include -namespace clients {namespace test {namespace testme {namespace post { +#include "clients/test/openapi.hpp" -} // namespace post +namespace clients { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace clients diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_sax_parsers.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_sax_parsers.hpp index 99d0911c66a0..f444a24c1666 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_sax_parsers.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/openapi_sax_parsers.hpp @@ -1,17 +1,18 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "clients/test/openapi.hpp" - #include #include +#include #include #include -#include -namespace clients {namespace test {namespace testme {namespace post { +#include "clients/test/openapi.hpp" -} // namespace post +namespace clients { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace clients diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/qos.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/qos.hpp index 5055dc60d306..632dc7ed0137 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/qos.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/qos.hpp @@ -6,6 +6,6 @@ namespace clients::test { inline const USERVER_NAMESPACE::dynamic_config::Key -kQosConfig{"", USERVER_NAMESPACE::dynamic_config::DefaultAsJsonString{"{}"}}; + kQosConfig{"", USERVER_NAMESPACE::dynamic_config::DefaultAsJsonString{"{}"}}; } // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/requests.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/requests.hpp index abaefbc0e17c..9c099753bfca 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/requests.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/requests.hpp @@ -1,28 +1,25 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once +#include +#include #include - #include -#include - -#include namespace clients::test { -namespace testme::post { using Body = int; +namespace testme::post { +using Body = int; struct Request { -std::string -number; -std::vector -array; - - Body body; + std::string number; + std::vector array; + Body body; }; -void SerializeRequest(const Request& request, const std::string& base_url, USERVER_NAMESPACE::clients::http::Request& http_request); -} +void SerializeRequest(const Request& request, const std::string& base_url, + USERVER_NAMESPACE::clients::http::Request& http_request); +} // namespace testme::post -} +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/include/clients/test/responses.hpp b/chaotic-openapi/golden_tests/output/client/include/clients/test/responses.hpp index ac3c0d263f96..0d70d64fabfa 100644 --- a/chaotic-openapi/golden_tests/output/client/include/clients/test/responses.hpp +++ b/chaotic-openapi/golden_tests/output/client/include/clients/test/responses.hpp @@ -1,13 +1,11 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include - #include -#include -#include - #include +#include +#include +#include USERVER_NAMESPACE_BEGIN namespace clients::http { @@ -19,14 +17,13 @@ namespace clients::test { namespace testme::post { - struct Response200{ - std::optionalX_Header; - - }; +struct Response200 { + std::optional X_Header; +}; - using Response =Response200; +using Response = Response200; Response ParseResponse(USERVER_NAMESPACE::clients::http::Response& response); -} +} // namespace testme::post -} +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/client_impl.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/client_impl.cpp index f659fd87e47e..48d6a59bb064 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/client_impl.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/client_impl.cpp @@ -1,40 +1,38 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - -#include #include +#include #include namespace clients::test { -ClientImpl::ClientImpl( - const USERVER_NAMESPACE::chaotic::openapi::client::Config& config, - USERVER_NAMESPACE::clients::http::Client& http_client -) - : config_(config), http_client_(http_client) -{} +ClientImpl::ClientImpl(const USERVER_NAMESPACE::chaotic::openapi::client::Config& config, + USERVER_NAMESPACE::clients::http::Client& http_client) + : config_(config), http_client_(http_client) {} -testme::post::Response ClientImpl::TestmePost(const testme::post::Request& request , const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control -) { -auto r = http_client_.CreateRequest(); -r.SetUrlTemplate("/testme"); +testme::post::Response ClientImpl::TestmePost( + const testme::post::Request& request, + const USERVER_NAMESPACE::chaotic::openapi::client::CommandControl& command_control) { + auto r = http_client_.CreateRequest(); + r.SetUrlTemplate("/testme"); -if (core_middlewares_) { + if (core_middlewares_) { r.SetMiddlewaresList(*core_middlewares_); -} -ApplyConfig(r, command_control, config_); SerializeRequest(request, config_.base_url, r); + } + ApplyConfig(r, command_control, config_); + SerializeRequest(request, config_.base_url, r); -middleware_manager_.ProcessRequest(r); + middleware_manager_.ProcessRequest(r); -std::shared_ptr response; -try { + std::shared_ptr response; + try { response = r.perform(); middleware_manager_.ProcessResponse(*response); -} catch (const USERVER_NAMESPACE::clients::http::TimeoutException& e) { + } catch (const USERVER_NAMESPACE::clients::http::TimeoutException& e) { throw testme::post::TimeoutException(); -} + } -return testme::post::ParseResponse(*response); + return testme::post::ParseResponse(*response); } } // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/component.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/component.cpp index fcf15fdb2527..3ea3562802a4 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/component.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/component.cpp @@ -1,78 +1,71 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - #include #include +#include #include #include #include #include -#include - namespace clients::test { -Component::Component( - const USERVER_NAMESPACE::components::ComponentConfig& config, - const USERVER_NAMESPACE::components::ComponentContext& context -) +Component::Component(const USERVER_NAMESPACE::components::ComponentConfig& config, + const USERVER_NAMESPACE::components::ComponentContext& context) : USERVER_NAMESPACE::components::ComponentBase(config, context), - client_( - USERVER_NAMESPACE::chaotic::openapi::client::ParseConfig(config, ClientImpl::kDefaultBaseUrl), - context.FindComponent().GetHttpClient() - ) -{ - if (config.HasMember("middlewares")) { - const auto& mw_config = config["middlewares"]; + client_(USERVER_NAMESPACE::chaotic::openapi::client::ParseConfig(config, ClientImpl::kDefaultBaseUrl), + context.FindComponent().GetHttpClient()) { + if (config.HasMember("middlewares")) { + const auto& mw_config = config["middlewares"]; - for (const auto& [name, config] : USERVER_NAMESPACE::formats::common::Items(mw_config)) { - auto& factory = context.FindComponent< - USERVER_NAMESPACE::chaotic::openapi::client::MiddlewareFactory>("chaotic-client-middleware-" + name); - auto middleware = factory.Create(config); - client_.RegisterMiddleware(middleware); - } + for (const auto& [name, config] : USERVER_NAMESPACE::formats::common::Items(mw_config)) { + auto& factory = context.FindComponent( + "chaotic-client-middleware-" + name); + auto middleware = factory.Create(config); + client_.RegisterMiddleware(middleware); + } - const auto& names = config["core-middlewares"].As>>(std::nullopt); - std::optional>> core_middlewares; - if (names) { - core_middlewares.emplace(); - for (const auto& name : *names) { - auto& component = context.FindComponent< - USERVER_NAMESPACE::clients::http::middlewares::ComponentBase>(name); - core_middlewares->emplace_back(&component.GetMiddleware()); - } - } - client_.SetCoreMiddlewares(std::move(core_middlewares)); + const auto& names = config["core-middlewares"].As>>(std::nullopt); + std::optional>> + core_middlewares; + if (names) { + core_middlewares.emplace(); + for (const auto& name : *names) { + auto& component = context.FindComponent(name); + core_middlewares->emplace_back(&component.GetMiddleware()); + } } + client_.SetCoreMiddlewares(std::move(core_middlewares)); + } } Client& Component::GetClient() { return client_; } USERVER_NAMESPACE::yaml_config::Schema Component::GetStaticConfigSchema() { - std::string base_schema = R"( -type: object -description: OpenAPI HTTP client with middlewares -additionalProperties: false -properties: - base-url: - type: string - description: Base URL for the API - timeout-ms: - type: integer - description: Request timeout in milliseconds - minimum: 1 - attempts: - type: integer - description: Maximum number of retry attempts - minimum: 1 - middlewares: + std::string base_schema = R"( type: object - description: Middlewares configuration - additionalProperties: true - properties: {} -)"; + description: OpenAPI HTTP client with middlewares + additionalProperties: false + properties: + base-url: + type: string + description: Base URL for the API + timeout-ms: + type: integer + description: Request timeout in milliseconds + minimum: 1 + attempts: + type: integer + description: Maximum number of retry attempts + minimum: 1 + middlewares: + type: object + description: Middlewares configuration + additionalProperties: true + properties: {} + )"; - return USERVER_NAMESPACE::yaml_config::MergeSchemas(base_schema); + return USERVER_NAMESPACE::yaml_config::MergeSchemas(base_schema); } -} +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/exceptions.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/exceptions.cpp index 67050542f69a..1c96c7bab001 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/exceptions.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/exceptions.cpp @@ -1,6 +1,5 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - #include namespace clients::test { @@ -8,26 +7,20 @@ namespace clients::test { Exception::~Exception() = default; HttpException::HttpException(USERVER_NAMESPACE::clients::http::ErrorKind error_kind) - : USERVER_NAMESPACE::chaotic::openapi::client::HttpException(error_kind) -{} + : USERVER_NAMESPACE::chaotic::openapi::client::HttpException(error_kind) {} ExceptionWithStatusCode::ExceptionWithStatusCode(int status_code) - : USERVER_NAMESPACE::chaotic::openapi::client::ExceptionWithStatusCode(status_code) -{} + : USERVER_NAMESPACE::chaotic::openapi::client::ExceptionWithStatusCode(status_code) {} TimeoutException::~TimeoutException() = default; namespace testme::post { -const char* Exception::what() const noexcept { - return kHandlerInfo.c_str(); -} +const char* Exception::what() const noexcept { return kHandlerInfo.c_str(); } HttpException::~HttpException() = default; -TimeoutException::TimeoutException() - : HttpException(USERVER_NAMESPACE::clients::http::ErrorKind::kTimeout) -{} +TimeoutException::TimeoutException() : HttpException(USERVER_NAMESPACE::clients::http::ErrorKind::kTimeout) {} TimeoutException::~TimeoutException() = default; diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/openapi.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/openapi.cpp index 5b4d9f566ab5..ecc26e83c162 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/openapi.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/openapi.cpp @@ -1,15 +1,14 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ -#include "clients/test/openapi.hpp" - #include +#include "clients/test/openapi.hpp" #include "clients/test/openapi_parsers.ipp" - #include "clients/test/openapi_sax_parsers.hpp" -namespace clients {namespace test {namespace testme {namespace post { - -} // namespace post +namespace clients { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace clients diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/requests.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/requests.cpp index 7680e5a2079e..ffa27805b8e3 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/requests.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/requests.cpp @@ -1,38 +1,36 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - +#include #include +#include #include #include -#include #include -#include -#include +#include namespace clients::test { namespace openapi = USERVER_NAMESPACE::chaotic::openapi; -namespace testme::post { static constexpr openapi::Name knumber = "number"; +namespace testme::post { +static constexpr openapi::Name knumber = "number"; static constexpr openapi::Name karray = "array"; -void SerializeRequest(const Request& request, const std::string& base_url, USERVER_NAMESPACE::clients::http::Request& http_request) -{ -openapi::ParameterSinkHttpClient sink( -http_request, -base_url + "/testme" -); +void SerializeRequest(const Request& request, const std::string& base_url, + USERVER_NAMESPACE::clients::http::Request& http_request) { + openapi::ParameterSinkHttpClient sink(http_request, base_url + "/testme"); -openapi::WriteParameter>(request.number, sink); -openapi::WriteParameter>(request.array, sink); + openapi::WriteParameter>( + request.number, sink); + openapi::WriteParameter>( + request.array, sink); -http_request.data(ToString(USERVER_NAMESPACE::formats::json::ValueBuilder(request.body).ExtractValue())); - -sink.Flush(); + http_request.data(ToString(USERVER_NAMESPACE::formats::json::ValueBuilder(request.body).ExtractValue())); + sink.Flush(); } -} // namespace +} // namespace testme::post -} +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/client/src/clients/test/responses.cpp b/chaotic-openapi/golden_tests/output/client/src/clients/test/responses.cpp index 1de95af070b9..df3cc7e81994 100644 --- a/chaotic-openapi/golden_tests/output/client/src/clients/test/responses.cpp +++ b/chaotic-openapi/golden_tests/output/client/src/clients/test/responses.cpp @@ -1,43 +1,38 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - +#include +#include #include #include #include #include #include -#include - -#include namespace clients::test { namespace testme::post { -Response ParseResponse(USERVER_NAMESPACE::clients::http::Response& http_response) -{ -auto status_code = static_cast(http_response.status_code()); -switch (status_code) { - case 200: - { - Response200 r{}; +Response ParseResponse(USERVER_NAMESPACE::clients::http::Response& http_response) { + auto status_code = static_cast(http_response.status_code()); + switch (status_code) { + case 200: { + Response200 r{}; - { - static const USERVER_NAMESPACE::http::headers::PredefinedHeader kHeader("X-Header"); - auto it = http_response.headers().find(kHeader); - if (it != http_response.headers().end()) { - namespace openapi = USERVER_NAMESPACE::chaotic::openapi; - static constexpr openapi::Name kX_Header = "X-Header"; - using Header = openapi::TrivialParameter; - r.X_Header = openapi::ParameterParser::Parse(std::string{it->second}); + { + static const USERVER_NAMESPACE::http::headers::PredefinedHeader kHeader("X-Header"); + auto it = http_response.headers().find(kHeader); + if (it != http_response.headers().end()) { + namespace openapi = USERVER_NAMESPACE::chaotic::openapi; + static constexpr openapi::Name kX_Header = "X-Header"; + using Header = openapi::TrivialParameter; + r.X_Header = openapi::ParameterParser::Parse(std::string{it->second}); + } } - } return r; + } + default: + throw ExceptionWithStatusCode(status_code); } - -default: - throw ExceptionWithStatusCode(status_code); -} -} -} } +} // namespace testme::post +} // namespace clients::test diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp index c5fae7ba5ea8..4d3b9c658a13 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.cpp @@ -3,31 +3,31 @@ namespace handlers::test::testme::post { Response View::Handle(Request&& /*request*/, Deps&& /*deps*/, RequestContext& /*context*/) { - // Handle request using dependencies from Deps (clients, caches, configs, databases...) - return {}; + // Handle request using dependencies from Deps (clients, caches, configs, databases...) + return {}; } /* std::string View::GetRequestBodyForLogging( -const USERVER_NAMESPACE::formats::json::Value& body) { -(void)body; -return {}; + const USERVER_NAMESPACE::formats::json::Value& body) { + (void)body; + return {}; } std::string View::GetInvalidRequestBodyForLogging( -const USERVER_NAMESPACE::server::http::HttpRequest& request) { -(void)request; -return {}; + const USERVER_NAMESPACE::server::http::HttpRequest& request) { + (void)request; + return {}; } std::string View::GetResponseForLogging( -const Response& response, -const std::string& serialized_response, -RequestContext& context) { -(void)response; -(void)serialized_response; -(void)context; -return {}; + const Response& response, + const std::string& serialized_response, + RequestContext& context) { + (void)response; + (void)serialized_response; + (void)context; + return {}; } */ diff --git a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp index 92ac44932a8a..064cf6fb974a 100644 --- a/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/handlers/test/testme/post/view.hpp @@ -1,9 +1,8 @@ #pragma once -#include - #include #include +#include #include #include #include @@ -14,27 +13,27 @@ namespace handlers::test::testme::post { struct HandlerTag; class View final { -public: - using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; - using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; - - static Response Handle(Request&& request, Deps&& deps, RequestContext& context); - - /* Uncomment, if you want to define a custom logging for request/response body. - * E.g. you want to log several fields, but omit the others (secrets, etc.). - * - static std::string GetRequestBodyForLogging( - const USERVER_NAMESPACE::formats::json::Value& body); - - // Logger for 'invalid JSON body' request - static std::string GetInvalidRequestBodyForLogging( - const USERVER_NAMESPACE::server::http::HttpRequest& request); - - static std::string GetResponseForLogging( - const Response& response, - const std::string& serialized_response, - RequestContext& context); - */ + public: + using Deps = USERVER_NAMESPACE::chaotic::openapi::server::dependencies::ForHandler; + using RequestContext = USERVER_NAMESPACE::server::request::RequestContext; + + static Response Handle(Request&& request, Deps&& deps, RequestContext& context); + + /* Uncomment, if you want to define a custom logging for request/response body. + * E.g. you want to log several fields, but omit the others (secrets, etc.). + * + static std::string GetRequestBodyForLogging( + const USERVER_NAMESPACE::formats::json::Value& body); + + // Logger for 'invalid JSON body' request + static std::string GetInvalidRequestBodyForLogging( + const USERVER_NAMESPACE::server::http::HttpRequest& request); + + static std::string GetResponseForLogging( + const Response& response, + const std::string& serialized_response, + RequestContext& context); + */ }; } // namespace handlers::test::testme::post diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp index 4cd3ff3035e8..e22bcff1dc66 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/chaotic_handlers_list.hpp @@ -16,7 +16,7 @@ namespace handlers::test { /// component_list.AppendComponentList(handlers::test::ChaoticHandlersList()); /// @endcode inline USERVER_NAMESPACE::components::ComponentList ChaoticHandlersList() { - return USERVER_NAMESPACE::components::ComponentList().Append(); + return USERVER_NAMESPACE::components::ComponentList().Append(); } } // namespace handlers::test diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi.hpp index 88e92f076632..906ce98ed249 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi.hpp @@ -1,14 +1,16 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "handlers/test/openapi_fwd.hpp" - #include #include - #include -namespace handlers {namespace test {namespace testme {namespace post { +#include "handlers/test/openapi_fwd.hpp" + +namespace handlers { +namespace test { +namespace testme { +namespace post { using Parameter1 = std::vector; diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_fwd.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_fwd.hpp index cffea112db44..fa5676d6b984 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_fwd.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_fwd.hpp @@ -1,9 +1,10 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -namespace handlers {namespace test {namespace testme {namespace post { - -} // namespace post +namespace handlers { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace handlers diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_parsers.ipp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_parsers.ipp index 77d9ce1b1925..df108e57cc5e 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_parsers.ipp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_parsers.ipp @@ -1,16 +1,17 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "handlers/test/openapi.hpp" - #include #include #include #include -namespace handlers {namespace test {namespace testme {namespace post { +#include "handlers/test/openapi.hpp" -} // namespace post +namespace handlers { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace handlers diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_sax_parsers.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_sax_parsers.hpp index 1327f77542df..111ccdfdb2e2 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_sax_parsers.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/openapi_sax_parsers.hpp @@ -1,17 +1,18 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once -#include "handlers/test/openapi.hpp" - #include #include +#include #include #include -#include -namespace handlers {namespace test {namespace testme {namespace post { +#include "handlers/test/openapi.hpp" -} // namespace post +namespace handlers { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace handlers diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/handler.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/handler.hpp index 2ebdaa217645..5324d16f5778 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/handler.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/handler.hpp @@ -4,7 +4,6 @@ #include #include #include - #include namespace handlers::test::testme::post { @@ -16,12 +15,7 @@ namespace impl { inline constexpr std::string_view kHandlerName = "handler-testme-post"; } -using Handler = USERVER_NAMESPACE::chaotic::openapi::server::BaseHandler< -impl::kHandlerName, -void, -Request, -Response, -HandlerTag, -View>; +using Handler = USERVER_NAMESPACE::chaotic::openapi::server::BaseHandler; } // namespace handlers::test::testme::post diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/requests.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/requests.hpp index dcb338727d27..95e003f495b3 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/requests.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/requests.hpp @@ -1,13 +1,12 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #pragma once +#include +#include #include #include #include #include -#include - -#include namespace handlers::test::testme::post { @@ -16,14 +15,13 @@ static constexpr USERVER_NAMESPACE::chaotic::openapi::Name karray = "array"; /// Request parsed from HttpRequest for this operation. struct Request final { - std::string number; - std::vector array; + std::string number; + std::vector array; - int body; + int body; }; -Request ParseRequest( -const USERVER_NAMESPACE::server::http::HttpRequest& http_request, -const USERVER_NAMESPACE::chaotic::openapi::To&); +Request ParseRequest(const USERVER_NAMESPACE::server::http::HttpRequest& http_request, + const USERVER_NAMESPACE::chaotic::openapi::To&); } // namespace handlers::test::testme::post diff --git a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/responses.hpp b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/responses.hpp index 8e9915d91e93..0d31b2eed32b 100644 --- a/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/responses.hpp +++ b/chaotic-openapi/golden_tests/output/handlers/include/handlers/test/testme/post/responses.hpp @@ -2,20 +2,19 @@ #pragma once #include +#include +#include #include -#include - #include #include -#include -#include +#include namespace handlers::test::testme::post { struct Response200 final { -static constexpr int kStatus = 200; + static constexpr int kStatus = 200; - std::optional X_Header; + std::optional X_Header; }; /// All possible responses for this operation. diff --git a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/openapi.cpp b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/openapi.cpp index 4446de2e2821..5fc07e633f8f 100644 --- a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/openapi.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/openapi.cpp @@ -1,15 +1,14 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ -#include "handlers/test/openapi.hpp" - #include +#include "handlers/test/openapi.hpp" #include "handlers/test/openapi_parsers.ipp" - #include "handlers/test/openapi_sax_parsers.hpp" -namespace handlers {namespace test {namespace testme {namespace post { - -} // namespace post +namespace handlers { +namespace test { +namespace testme { +namespace post {} // namespace post } // namespace testme } // namespace test } // namespace handlers diff --git a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/requests.cpp b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/requests.cpp index 01fd1cee1add..d6005d3a3fc1 100644 --- a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/requests.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/requests.cpp @@ -1,26 +1,26 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - #include -#include #include #include +#include namespace handlers::test::testme::post { -Request ParseRequest( -const USERVER_NAMESPACE::server::http::HttpRequest& http_request, -const USERVER_NAMESPACE::chaotic::openapi::To& /*tag*/) { -namespace openapi = USERVER_NAMESPACE::chaotic::openapi; +Request ParseRequest(const USERVER_NAMESPACE::server::http::HttpRequest& http_request, + const USERVER_NAMESPACE::chaotic::openapi::To& /*tag*/) { + namespace openapi = USERVER_NAMESPACE::chaotic::openapi; -Request r{}; - r.number = openapi::ReadParameter>(http_request); - r.array = openapi::ReadParameter>(http_request); + Request r{}; + r.number = openapi::ReadParameter>( + http_request); + r.array = openapi::ReadParameter>( + http_request); - auto json = USERVER_NAMESPACE::formats::json::FromString(http_request.RequestBody()); -r.body = json.As(); + auto json = USERVER_NAMESPACE::formats::json::FromString(http_request.RequestBody()); + r.body = json.As(); -return r; + return r; } } // namespace handlers::test::testme::post diff --git a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/responses.cpp b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/responses.cpp index 73b5a1ed2942..cf2270dc2885 100644 --- a/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/responses.cpp +++ b/chaotic-openapi/golden_tests/output/handlers/src/handlers/test/testme/post/responses.cpp @@ -1,35 +1,33 @@ /* THIS FILE IS AUTOGENERATED, DON'T EDIT! */ #include - -#include -#include -#include #include #include #include +#include +#include +#include namespace handlers::test::testme::post { namespace { std::string SerializeSpecificResponse(const Response200& r, - USERVER_NAMESPACE::server::http::HttpRequest& http_request) { -http_request.GetHttpResponse().SetStatus( -static_cast(200) -); -namespace openapi = USERVER_NAMESPACE::chaotic::openapi; - static constexpr openapi::Name kX_Header = "X-Header"; -openapi::server::ParameterSinkHttpResponse header_sink(http_request.GetHttpResponse()); - if (r.X_Header) { - openapi::WriteParameter>(*r.X_Header, header_sink); - } -return {}; + USERVER_NAMESPACE::server::http::HttpRequest& http_request) { + http_request.GetHttpResponse().SetStatus(static_cast(200)); + namespace openapi = USERVER_NAMESPACE::chaotic::openapi; + static constexpr openapi::Name kX_Header = "X-Header"; + openapi::server::ParameterSinkHttpResponse header_sink(http_request.GetHttpResponse()); + if (r.X_Header) { + openapi::WriteParameter>( + *r.X_Header, header_sink); + } + return {}; } } // namespace std::string SerializeResponse(const Response& response, USERVER_NAMESPACE::server::http::HttpRequest& http_request) { -return SerializeSpecificResponse(response, http_request); + return SerializeSpecificResponse(response, http_request); } } // namespace handlers::test::testme::post