diff --git a/include/envoy/router/rds.h b/include/envoy/router/rds.h index 2456f561b95b..c0604e410a98 100644 --- a/include/envoy/router/rds.h +++ b/include/envoy/router/rds.h @@ -51,10 +51,10 @@ class RdsRouteConfigProvider : public RouteConfigProvider { virtual const std::string& routeConfigName() const PURE; /** - * @return const std::string& the name of the cluster the RdsRouteConfigProvider is issuing RDS - * requests to. + * @return const std::string& the configuration of the service the RdsRouteConfigProvider is + * issuing RDS requests to. */ - virtual const std::string& clusterName() const PURE; + virtual const std::string& configSource() const PURE; }; typedef std::shared_ptr RouteConfigProviderSharedPtr; diff --git a/source/common/protobuf/utility.cc b/source/common/protobuf/utility.cc index 2e1e467c5218..27ac04126d69 100644 --- a/source/common/protobuf/utility.cc +++ b/source/common/protobuf/utility.cc @@ -58,12 +58,16 @@ void MessageUtil::loadFromFile(const std::string& path, Protobuf::Message& messa } } -std::string MessageUtil::getJsonStringFromMessage(const Protobuf::Message& message) { +std::string MessageUtil::getJsonStringFromMessage(const Protobuf::Message& message, + const bool pretty_print) { Protobuf::util::JsonPrintOptions json_options; // By default, proto field names are converted to camelCase when the message is converted to JSON. // Setting this option makes debugging easier because it keeps field names consistent in JSON // printouts. json_options.preserve_proto_field_names = true; + if (pretty_print) { + json_options.add_whitespace = true; + } ProtobufTypes::String json; const auto status = Protobuf::util::MessageToJsonString(message, &json, json_options); // This should always succeed unless something crash-worthy such as out-of-memory. diff --git a/source/common/protobuf/utility.h b/source/common/protobuf/utility.h index d814159a8f29..3f11b42142d3 100644 --- a/source/common/protobuf/utility.h +++ b/source/common/protobuf/utility.h @@ -176,9 +176,11 @@ class MessageUtil { /** * Extract JSON as string from a google.protobuf.Message. * @param message message of type type.googleapis.com/google.protobuf.Message. - * @return std::string of JSON object. + * @param pretty_print whether the returned JSON should be formatted. + * @return std::string of formatted JSON object. */ - static std::string getJsonStringFromMessage(const Protobuf::Message& message); + static std::string getJsonStringFromMessage(const Protobuf::Message& message, + bool pretty_print = false); /** * Extract JSON object from a google.protobuf.Message. @@ -234,4 +236,4 @@ template <> struct hash { std::size_t operator()(Envoy::HashedValue const& v) const { return v.hash(); } }; -} // namespace std +} // namespace std \ No newline at end of file diff --git a/source/common/router/rds_impl.cc b/source/common/router/rds_impl.cc index b6f772cb8366..68d05c8d0f2c 100644 --- a/source/common/router/rds_impl.cc +++ b/source/common/router/rds_impl.cc @@ -71,15 +71,7 @@ RdsRouteConfigProviderImpl::RdsRouteConfigProviderImpl( }, "envoy.api.v2.RouteDiscoveryService.FetchRoutes", "envoy.api.v2.RouteDiscoveryService.StreamRoutes"); - - // In V2 we use a Subscription model where the fetch can happen via gRPC, REST, or - // local filesystem. If the subscription happens via local filesystem (e.g xds_integration_test), - // then there is no actual RDS server, and hence no RDS cluster name. - if (rds.has_config_source() && rds.config_source().has_api_config_source()) { - cluster_name_ = rds.config_source().api_config_source().cluster_names()[0]; - } else { - cluster_name_ = "NOT_USING_CLUSTER"; - } + config_source_ = MessageUtil::getJsonStringFromMessage(rds.config_source(), true); } RdsRouteConfigProviderImpl::~RdsRouteConfigProviderImpl() { @@ -249,7 +241,7 @@ Http::Code RouteConfigProviderManagerImpl::handlerRoutesLoop( response.add("{\n"); response.add(fmt::format("\"version_info\": \"{}\",\n", provider->versionInfo())); response.add(fmt::format("\"route_config_name\": \"{}\",\n", provider->routeConfigName())); - response.add(fmt::format("\"cluster_name\": \"{}\",\n", provider->clusterName())); + response.add(fmt::format("\"config_source\": {},\n", provider->configSource())); response.add("\"route_table_dump\": "); response.add(fmt::format("{}\n", provider->configAsJson())); response.add("}\n"); diff --git a/source/common/router/rds_impl.h b/source/common/router/rds_impl.h index 02084ba5d81a..351063945b43 100644 --- a/source/common/router/rds_impl.h +++ b/source/common/router/rds_impl.h @@ -98,10 +98,10 @@ class RdsRouteConfigProviderImpl // Router::RdsRouteConfigProvider std::string configAsJson() const override { - return MessageUtil::getJsonStringFromMessage(route_config_proto_); + return MessageUtil::getJsonStringFromMessage(route_config_proto_, true); } const std::string& routeConfigName() const override { return route_config_name_; } - const std::string& clusterName() const override { return cluster_name_; } + const std::string& configSource() const override { return config_source_; } const std::string versionInfo() const override { return subscription_->versionInfo(); } // Config::SubscriptionCallbacks @@ -130,7 +130,7 @@ class RdsRouteConfigProviderImpl Upstream::ClusterManager& cm_; std::unique_ptr> subscription_; ThreadLocal::SlotPtr tls_; - std::string cluster_name_; + std::string config_source_; const std::string route_config_name_; bool initialized_{}; uint64_t last_config_hash_{}; diff --git a/test/common/router/rds_impl_test.cc b/test/common/router/rds_impl_test.cc index 9aee219affd3..c83fa6c88bfc 100644 --- a/test/common/router/rds_impl_test.cc +++ b/test/common/router/rds_impl_test.cc @@ -215,8 +215,17 @@ TEST_F(RdsImplTest, Basic) { { "version_info": "", "route_config_name": "foo_route_config", -"cluster_name": "foo_cluster", +"config_source": { + "api_config_source": { + "cluster_names": [ + "foo_cluster" + ], + "refresh_delay": "1s" + } +} +, "route_table_dump": {} + } ] )EOF"; @@ -248,8 +257,19 @@ TEST_F(RdsImplTest, Basic) { { "version_info": "hash_15ed54077da94d8b", "route_config_name": "foo_route_config", -"cluster_name": "foo_cluster", -"route_table_dump": {"name":"foo_route_config"} +"config_source": { + "api_config_source": { + "cluster_names": [ + "foo_cluster" + ], + "refresh_delay": "1s" + } +} +, +"route_table_dump": { + "name": "foo_route_config" +} + } ] )EOF"; @@ -327,8 +347,45 @@ TEST_F(RdsImplTest, Basic) { { "version_info": "hash_7a3f97b327d08382", "route_config_name": "foo_route_config", -"cluster_name": "foo_cluster", -"route_table_dump": {"name":"foo_route_config","virtual_hosts":[{"name":"local_service","domains":["*"],"routes":[{"match":{"prefix":"/foo"},"route":{"cluster_header":":authority"}},{"match":{"prefix":"/bar"},"route":{"cluster":"bar"}}]}]} +"config_source": { + "api_config_source": { + "cluster_names": [ + "foo_cluster" + ], + "refresh_delay": "1s" + } +} +, +"route_table_dump": { + "name": "foo_route_config", + "virtual_hosts": [ + { + "name": "local_service", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/foo" + }, + "route": { + "cluster_header": ":authority" + } + }, + { + "match": { + "prefix": "/bar" + }, + "route": { + "cluster": "bar" + } + } + ] + } + ] +} + } ] )EOF"; @@ -524,14 +581,32 @@ TEST_F(RouteConfigProviderManagerImplTest, Basic) { { "version_info": "", "route_config_name": "foo_route_config", -"cluster_name": "bar_cluster", +"config_source": { + "api_config_source": { + "cluster_names": [ + "bar_cluster" + ], + "refresh_delay": "1s" + } +} +, "route_table_dump": {} + } ,{ "version_info": "", "route_config_name": "foo_route_config", -"cluster_name": "foo_cluster", +"config_source": { + "api_config_source": { + "cluster_names": [ + "foo_cluster" + ], + "refresh_delay": "1s" + } +} +, "route_table_dump": {} + } ] )EOF";