6#include <unordered_map>
8#include <userver/components/component_base.hpp>
9#include <userver/components/component_fwd.hpp>
10#include <userver/utils/meta_light.hpp>
11#include <userver/yaml_config/fwd.hpp>
13#include <userver/ugrpc/server/impl/middleware_pipeline_config.hpp>
14#include <userver/ugrpc/server/middlewares/fwd.hpp>
15#include <userver/ugrpc/server/service_base.hpp>
17USERVER_NAMESPACE_BEGIN
33 std::string node_name{};
37struct MiddlewareDependency
final {
38 std::string middleware_name{};
39 std::vector<Connect> befores{};
40 std::vector<Connect> afters{};
42 std::optional<std::string> group{};
45using Dependencies = std::unordered_map<std::string, MiddlewareDependency>;
47class MiddlewarePipeline
final {
49 explicit MiddlewarePipeline(Dependencies&& deps);
51 std::vector<std::string> GetPerServiceMiddlewares(
const MiddlewareServiceConfig& config)
const;
53 const MiddlewareOrderedList& GetOrderedList()
const {
return pipeline_; }
57 MiddlewareOrderedList pipeline_{};
60template <
typename Group>
61std::string BeginOfGroup() {
62 return std::string{Group::kName} +
"#begin";
65template <
typename Group>
66std::string EndOfGroup() {
67 return std::string{Group::kName} +
"#end";
87 MiddlewarePipelineComponent(
const components::ComponentConfig& config,
const components::ComponentContext& context);
93 const impl::MiddlewarePipeline& GetPipeline()
const;
97 impl::MiddlewarePipeline pipeline_;
106class MiddlewareDependencyBuilder
final {
112 MiddlewareDependencyBuilder(
const MiddlewareDependencyBuilder&) =
default;
114 MiddlewareDependencyBuilder(MiddlewareDependencyBuilder&&)
noexcept =
default;
118 template <
typename MiddlewareBefore>
128 template <
typename MiddlewareAfter>
138 template <
typename Group>
139 MiddlewareDependencyBuilder
InGroup() &&;
143 impl::MiddlewareDependency Extract(std::string_view middleware_name) &&;
147 impl::MiddlewareDependency dep_{};
153using IsGroup =
decltype(T::dependency);
156constexpr bool kIsGroup = std::is_same_v<meta::DetectedType<IsGroup, T>,
const MiddlewareDependencyBuilder>;
160template <
typename MiddlewareBefore>
162 if constexpr (impl::kIsGroup<MiddlewareBefore>) {
163 return std::move(*
this).Before(impl::BeginOfGroup<MiddlewareBefore>(), type);
165 return std::move(*
this).Before(MiddlewareBefore::kName, type);
168template <
typename MiddlewareAfter>
170 if constexpr (impl::kIsGroup<MiddlewareAfter>) {
171 return std::move(*
this).After(impl::EndOfGroup<MiddlewareAfter>(), type);
173 return std::move(*
this).After(MiddlewareAfter::kName, type);
176template <
typename Group>
177MiddlewareDependencyBuilder MiddlewareDependencyBuilder::
InGroup() && {
178 dep_.group = Group::kName;
179 dep_.afters.push_back(impl::Connect{impl::BeginOfGroup<Group>(), DependencyType::kStrong});
180 return std::move(*
this).Before(impl::EndOfGroup<Group>(),
DependencyType::kWeak);
186inline constexpr bool components::kHasValidate<ugrpc::server::MiddlewarePipelineComponent> =
true;
189inline constexpr auto components::kConfigFileMode<ugrpc::server::MiddlewarePipelineComponent> =