diff --git a/contrib/golang/router/cluster_specifier/source/BUILD b/contrib/golang/router/cluster_specifier/source/BUILD index c23dd3b9856b2..dc5822ff65179 100644 --- a/contrib/golang/router/cluster_specifier/source/BUILD +++ b/contrib/golang/router/cluster_specifier/source/BUILD @@ -25,7 +25,7 @@ envoy_cc_library( "//envoy/router:cluster_specifier_plugin_interface", "//source/common/common:utility_lib", "//source/common/http:utility_lib", - "//source/common/router:config_lib", + "//source/common/router:delegating_route_lib", "@envoy_api//contrib/envoy/extensions/router/cluster_specifier/golang/v3alpha:pkg_cc_proto", ], ) diff --git a/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.cc b/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.cc index 4adf9a1a34c94..82662773a4501 100644 --- a/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.cc +++ b/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.cc @@ -2,7 +2,7 @@ #include -#include "source/common/router/config_impl.h" +#include "source/common/router/delegating_route_impl.h" namespace Envoy { namespace Router { @@ -46,7 +46,8 @@ ClusterConfig::ClusterConfig(const GolangClusterProto& config) RouteConstSharedPtr GolangClusterSpecifierPlugin::route(RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& header, - const StreamInfo::StreamInfo&) const { + const StreamInfo::StreamInfo&, + uint64_t) const { int buffer_len = 256; std::string buffer; std::string cluster; @@ -77,7 +78,7 @@ RouteConstSharedPtr GolangClusterSpecifierPlugin::route(RouteEntryAndRouteConstS } } - return std::make_shared(std::move(parent), cluster); + return std::make_shared(std::move(parent), std::move(cluster)); } void GolangClusterSpecifierPlugin::log(absl::string_view& msg) const { diff --git a/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.h b/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.h index c1593eb584894..b7a5ce0401559 100644 --- a/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.h +++ b/contrib/golang/router/cluster_specifier/source/golang_cluster_specifier.h @@ -38,7 +38,8 @@ class GolangClusterSpecifierPlugin : public ClusterSpecifierPlugin, RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& header, - const StreamInfo::StreamInfo& stream_info) const override; + const StreamInfo::StreamInfo& stream_info, + uint64_t random) const override; void log(absl::string_view& msg) const; diff --git a/envoy/router/cluster_specifier_plugin.h b/envoy/router/cluster_specifier_plugin.h index 4f4d56df5fe2a..d68f1013b9660 100644 --- a/envoy/router/cluster_specifier_plugin.h +++ b/envoy/router/cluster_specifier_plugin.h @@ -25,11 +25,13 @@ class ClusterSpecifierPlugin { * @param parent related route. * @param headers request headers. * @param stream_info stream info of the downstream request. + * @param random random value for cluster selection. * @return RouteConstSharedPtr final route with specific cluster. */ virtual RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo& stream_info) const PURE; + const StreamInfo::StreamInfo& stream_info, + uint64_t random) const PURE; }; using ClusterSpecifierPluginSharedPtr = std::shared_ptr; diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 78d8c1597c416..92d5e7deec6bd 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -174,7 +174,7 @@ getHeaderParsers(const HeaderParser* global_route_config_header_parser, class NullClusterSpecifierPlugin : public ClusterSpecifierPlugin { public: RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr, const Http::RequestHeaderMap&, - const StreamInfo::StreamInfo&) const override { + const StreamInfo::StreamInfo&, uint64_t) const override { return nullptr; } }; @@ -1390,7 +1390,8 @@ RouteConstSharedPtr RouteEntryImplBase::clusterEntry(const Http::RequestHeaderMa // TODO(wbpcode): make the weighted clusters an implementation of the // cluster specifier plugin. ASSERT(cluster_specifier_plugin_ != nullptr); - return cluster_specifier_plugin_->route(shared_from_this(), headers, stream_info); + return cluster_specifier_plugin_->route(shared_from_this(), headers, stream_info, + random_value); } } return pickWeightedCluster(headers, random_value); diff --git a/source/common/router/header_cluster_specifier.cc b/source/common/router/header_cluster_specifier.cc index 941c2051d7463..195bd9c02f78b 100644 --- a/source/common/router/header_cluster_specifier.cc +++ b/source/common/router/header_cluster_specifier.cc @@ -10,7 +10,8 @@ HeaderClusterSpecifierPlugin::HeaderClusterSpecifierPlugin(absl::string_view clu RouteConstSharedPtr HeaderClusterSpecifierPlugin::route(RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo&) const { + const StreamInfo::StreamInfo&, + uint64_t) const { const auto entry = headers.get(cluster_header_); absl::string_view cluster_name; diff --git a/source/common/router/header_cluster_specifier.h b/source/common/router/header_cluster_specifier.h index 731536e227b08..eee6451808386 100644 --- a/source/common/router/header_cluster_specifier.h +++ b/source/common/router/header_cluster_specifier.h @@ -11,7 +11,8 @@ class HeaderClusterSpecifierPlugin : public ClusterSpecifierPlugin { RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo& stream_info) const override; + const StreamInfo::StreamInfo& stream_info, + uint64_t random) const override; private: const Http::LowerCaseString cluster_header_; diff --git a/source/extensions/router/cluster_specifiers/lua/BUILD b/source/extensions/router/cluster_specifiers/lua/BUILD index 1f7801325c281..12915b89dbb70 100644 --- a/source/extensions/router/cluster_specifiers/lua/BUILD +++ b/source/extensions/router/cluster_specifiers/lua/BUILD @@ -24,6 +24,7 @@ envoy_cc_library( "//source/common/common:utility_lib", "//source/common/http:utility_lib", "//source/common/router:config_lib", + "//source/common/router:delegating_route_lib", "//source/common/runtime:runtime_features_lib", "//source/extensions/filters/common/lua:lua_lib", "//source/extensions/filters/common/lua:wrappers_lib", diff --git a/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.cc b/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.cc index b3859b429cd72..171a04124358b 100644 --- a/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.cc +++ b/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.cc @@ -1,6 +1,7 @@ #include "source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h" -#include "source/common/router/config_impl.h" +#include "source/common/http/header_utility.h" +#include "source/common/router/delegating_route_impl.h" namespace Envoy { namespace Extensions { @@ -123,10 +124,10 @@ std::string LuaClusterSpecifierPlugin::startLua(const Http::HeaderMap& headers) Envoy::Router::RouteConstSharedPtr LuaClusterSpecifierPlugin::route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo&) const { - return std::make_shared(std::move(parent), - startLua(headers)); + const StreamInfo::StreamInfo&, uint64_t) const { + return std::make_shared(std::move(parent), startLua(headers)); } + } // namespace Lua } // namespace Router } // namespace Extensions diff --git a/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h b/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h index ecd675389a533..4f68e95fd0540 100644 --- a/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h +++ b/source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.h @@ -134,10 +134,9 @@ class LuaClusterSpecifierPlugin : public Envoy::Router::ClusterSpecifierPlugin, Logger::Loggable { public: LuaClusterSpecifierPlugin(LuaClusterSpecifierConfigSharedPtr config); - Envoy::Router::RouteConstSharedPtr - route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, - const Http::RequestHeaderMap& header, - const StreamInfo::StreamInfo& stream_info) const override; + Envoy::Router::RouteConstSharedPtr route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, + const Http::RequestHeaderMap& header, + const StreamInfo::StreamInfo&, uint64_t) const override; private: std::string startLua(const Http::HeaderMap& headers) const; diff --git a/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.cc b/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.cc index 6b434eee663d1..70d35193631e2 100644 --- a/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.cc +++ b/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.cc @@ -56,7 +56,7 @@ class MatcherRouteEntry : public Envoy::Router::DelegatingRouteEntry { Envoy::Router::RouteConstSharedPtr MatcherClusterSpecifierPlugin::route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo& stream_info) const { + const StreamInfo::StreamInfo& stream_info, uint64_t) const { auto matcher_route = std::make_shared(parent, match_tree_); matcher_route->refreshRouteCluster(headers, stream_info); return matcher_route; diff --git a/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.h b/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.h index 18f4e40a704d6..52562d728cb0f 100644 --- a/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.h +++ b/source/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier.h @@ -58,10 +58,10 @@ class MatcherClusterSpecifierPlugin : public Envoy::Router::ClusterSpecifierPlug MatcherClusterSpecifierPlugin( Envoy::Matcher::MatchTreeSharedPtr match_tree) : match_tree_(match_tree) {} - Envoy::Router::RouteConstSharedPtr - route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, - const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo& stream_info) const override; + Envoy::Router::RouteConstSharedPtr route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent, + const Http::RequestHeaderMap& headers, + const StreamInfo::StreamInfo& stream_info, + uint64_t) const override; private: Envoy::Matcher::MatchTreeSharedPtr match_tree_; diff --git a/test/common/router/config_impl_integration_test.cc b/test/common/router/config_impl_integration_test.cc index fe7b8cb286454..cad2da4ea3b79 100644 --- a/test/common/router/config_impl_integration_test.cc +++ b/test/common/router/config_impl_integration_test.cc @@ -25,8 +25,8 @@ class FakeClusterSpecifierPluginFactoryConfig : public ClusterSpecifierPluginFac FakeClusterSpecifierPlugin(absl::string_view cluster) : cluster_name_(cluster) {} RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr parent, - const Http::RequestHeaderMap&, - const StreamInfo::StreamInfo&) const override { + const Http::RequestHeaderMap&, const StreamInfo::StreamInfo&, + uint64_t) const override { ASSERT(dynamic_cast(parent.get()) != nullptr); return std::make_shared( dynamic_cast(parent.get()), parent, cluster_name_); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index c289e9684e15b..ac1660c75a19b 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -3669,7 +3669,7 @@ TEST_F(RouteMatcherTest, InlineClusterSpecifierPlugin) { auto mock_route = std::make_shared>(); - EXPECT_CALL(*mock_cluster_specifier_plugin, route(_, _, _)).WillOnce(Return(mock_route)); + EXPECT_CALL(*mock_cluster_specifier_plugin, route(_, _, _, _)).WillOnce(Return(mock_route)); EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get()); } @@ -3799,10 +3799,10 @@ TEST_F(RouteMatcherTest, ClusterSpecifierPlugin) { auto mock_route = std::make_shared>(); - EXPECT_CALL(*mock_cluster_specifier_plugin_2, route(_, _, _)).WillOnce(Return(mock_route)); + EXPECT_CALL(*mock_cluster_specifier_plugin_2, route(_, _, _, _)).WillOnce(Return(mock_route)); EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get()); - EXPECT_CALL(*mock_cluster_specifier_plugin_3, route(_, _, _)).WillOnce(Return(mock_route)); + EXPECT_CALL(*mock_cluster_specifier_plugin_3, route(_, _, _, _)).WillOnce(Return(mock_route)); EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/bar", "GET"), 0).get()); } @@ -5025,7 +5025,8 @@ TEST_F(RouteMatcherTest, InvalidRetryBackOff) { )EOF"; factory_context_.cluster_manager_.initializeClusters({"backoff"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "retry_policy.max_interval must greater than or equal to the base_interval"); } diff --git a/test/extensions/router/cluster_specifiers/lua/lua_cluster_specifier_test.cc b/test/extensions/router/cluster_specifiers/lua/lua_cluster_specifier_test.cc index 5eb839e3a4f78..83f5591f3f275 100644 --- a/test/extensions/router/cluster_specifiers/lua/lua_cluster_specifier_test.cc +++ b/test/extensions/router/cluster_specifiers/lua/lua_cluster_specifier_test.cc @@ -78,7 +78,7 @@ TEST_F(LuaClusterSpecifierPluginTest, NormalLuaCode) { auto mock_route = std::make_shared>(); { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "fake"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("fake_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -86,7 +86,7 @@ TEST_F(LuaClusterSpecifierPluginTest, NormalLuaCode) { { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "header_value"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("web_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -100,7 +100,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ErrorLuaCode) { auto mock_route = std::make_shared>(); { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "fake"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("default_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -108,7 +108,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ErrorLuaCode) { { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "header_value"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("default_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -122,7 +122,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ReturnTypeNotStringLuaCode) { auto mock_route = std::make_shared>(); { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "fake"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("fake_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -130,7 +130,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ReturnTypeNotStringLuaCode) { { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"header_key", "header_value"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("default_service", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. config_->perLuaCodeSetup()->runtimeGC(); @@ -167,7 +167,7 @@ TEST_F(LuaClusterSpecifierPluginTest, GetClustersBadArg) { auto mock_route = std::make_shared>(); Http::TestRequestHeaderMapImpl headers{{":path", "/"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("default_service", route->routeEntry()->clusterName()); } @@ -192,7 +192,7 @@ TEST_F(LuaClusterSpecifierPluginTest, GetClustersMissing) { auto mock_route = std::make_shared>(); Http::TestRequestHeaderMapImpl headers{{":path", "/"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("nil", route->routeEntry()->clusterName()); } @@ -242,7 +242,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ClusterMethods) { auto mock_route = std::make_shared>(); Http::TestRequestHeaderMapImpl headers{{":path", "/"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("pass", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. @@ -279,7 +279,7 @@ TEST_F(LuaClusterSpecifierPluginTest, ClusterRef) { auto mock_route = std::make_shared>(); Http::TestRequestHeaderMapImpl headers{{":path", "/"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("pass", route->routeEntry()->clusterName()); // Force the runtime to gc and destroy all the userdata. @@ -310,7 +310,7 @@ TEST_F(LuaClusterSpecifierPluginTest, Logging) { {"warn", "log test"}, {"error", "log test"}, {"critical", "log test"}}), - { plugin_->route(mock_route, headers, stream_info_); }); + { plugin_->route(mock_route, headers, stream_info_, 0); }); } } // namespace Lua diff --git a/test/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier_test.cc b/test/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier_test.cc index 206c4f9d44c9a..513ccbdecef4a 100644 --- a/test/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier_test.cc +++ b/test/extensions/router/cluster_specifiers/matcher/matcher_cluster_specifier_test.cc @@ -116,19 +116,19 @@ TEST_F(MatcherClusterSpecifierPluginTest, NormalConfigTest) { auto mock_route = std::make_shared>(); { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"env", "staging"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("staging-cluster", route->routeEntry()->clusterName()); } { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"env", "prod"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("prod-cluster", route->routeEntry()->clusterName()); } { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"env", "not-exist"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("default-cluster", route->routeEntry()->clusterName()); } } @@ -139,13 +139,13 @@ TEST_F(MatcherClusterSpecifierPluginTest, NormalConfigWithoutDefaultCluster) { auto mock_route = std::make_shared>(); { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"env", "staging"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("staging-cluster", route->routeEntry()->clusterName()); } { Http::TestRequestHeaderMapImpl headers{{":path", "/"}, {"env", "not-exist"}}; - auto route = plugin_->route(mock_route, headers, stream_info_); + auto route = plugin_->route(mock_route, headers, stream_info_, 0); EXPECT_EQ("", route->routeEntry()->clusterName()); } } diff --git a/test/mocks/router/mocks.cc b/test/mocks/router/mocks.cc index ffbb1b4c48c0e..84f83366402b3 100644 --- a/test/mocks/router/mocks.cc +++ b/test/mocks/router/mocks.cc @@ -217,7 +217,7 @@ MockGenericConnectionPoolCallbacks::MockGenericConnectionPoolCallbacks() { } MockClusterSpecifierPlugin::MockClusterSpecifierPlugin() { - ON_CALL(*this, route(_, _, _)).WillByDefault(Return(nullptr)); + ON_CALL(*this, route(_, _, _, _)).WillByDefault(Return(nullptr)); } MockClusterSpecifierPluginFactoryConfig::MockClusterSpecifierPluginFactoryConfig() { diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h index 1b3e88d97dfa1..b565a6c02938f 100644 --- a/test/mocks/router/mocks.h +++ b/test/mocks/router/mocks.h @@ -739,7 +739,7 @@ class MockClusterSpecifierPlugin : public ClusterSpecifierPlugin { MOCK_METHOD(RouteConstSharedPtr, route, (RouteEntryAndRouteConstSharedPtr parent, const Http::RequestHeaderMap& headers, - const StreamInfo::StreamInfo& stream_info), + const StreamInfo::StreamInfo& stream_info, uint64_t random), (const)); };