diff --git a/source/common/config/BUILD b/source/common/config/BUILD index 8955c6cd16a61..d41b50d4347c6 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -237,6 +237,7 @@ envoy_cc_library( "//include/envoy/upstream:cluster_manager_interface", "//source/common/common:assert_lib", "//source/common/common:hex_lib", + "//source/common/common:singleton", "//source/common/json:config_schemas_lib", ], ) diff --git a/source/common/config/utility.cc b/source/common/config/utility.cc index ea42a65328606..ae979a0274e94 100644 --- a/source/common/config/utility.cc +++ b/source/common/config/utility.cc @@ -1,5 +1,6 @@ #include "common/config/utility.h" +#include "common/common/assert.h" #include "common/common/hex.h" #include "common/common/utility.h" #include "common/config/json_utility.h" @@ -11,18 +12,24 @@ namespace Envoy { namespace Config { -namespace { - -void translateApiConfigSource(const std::string& cluster, uint32_t refresh_delay_ms, - envoy::api::v2::ApiConfigSource& api_config_source) { - api_config_source.set_api_type(envoy::api::v2::ApiConfigSource::REST_LEGACY); +void Utility::translateApiConfigSource(const std::string& cluster, uint32_t refresh_delay_ms, + const std::string& api_type, + envoy::api::v2::ApiConfigSource& api_config_source) { + // TODO(junr03): document the option to chose an api type once we have created + // stronger constraints around v2. + if (api_type == ApiType::get().RestLegacy) { + api_config_source.set_api_type(envoy::api::v2::ApiConfigSource::REST_LEGACY); + } else if (api_type == ApiType::get().Rest) { + api_config_source.set_api_type(envoy::api::v2::ApiConfigSource::REST); + } else { + ASSERT(api_type == ApiType::get().Grpc); + api_config_source.set_api_type(envoy::api::v2::ApiConfigSource::GRPC); + } api_config_source.add_cluster_name(cluster); api_config_source.mutable_refresh_delay()->CopyFrom( Protobuf::util::TimeUtil::MillisecondsToDuration(refresh_delay_ms)); } -} // namespace - void Utility::checkCluster(const std::string& error_prefix, const std::string& cluster_name, Upstream::ClusterManager& cm) { Upstream::ThreadLocalCluster* cluster = cm.get(cluster_name); @@ -63,6 +70,7 @@ void Utility::translateEdsConfig(const Json::Object& json_config, envoy::api::v2::ConfigSource& eds_config) { translateApiConfigSource(json_config.getObject("cluster")->getString("name"), json_config.getInteger("refresh_delay_ms", 30000), + json_config.getString("api_type", ApiType::get().RestLegacy), *eds_config.mutable_api_config_source()); } @@ -70,6 +78,7 @@ void Utility::translateCdsConfig(const Json::Object& json_config, envoy::api::v2::ConfigSource& cds_config) { translateApiConfigSource(json_config.getObject("cluster")->getString("name"), json_config.getInteger("refresh_delay_ms", 30000), + json_config.getString("api_type", ApiType::get().RestLegacy), *cds_config.mutable_api_config_source()); } @@ -77,6 +86,7 @@ void Utility::translateRdsConfig(const Json::Object& json_rds, envoy::api::v2::f json_rds.validateSchema(Json::Schema::RDS_CONFIGURATION_SCHEMA); translateApiConfigSource(json_rds.getString("cluster"), json_rds.getInteger("refresh_delay_ms", 30000), + json_rds.getString("api_type", ApiType::get().RestLegacy), *rds.mutable_config_source()->mutable_api_config_source()); JSON_UTIL_SET_STRING(json_rds, rds, route_config_name); } @@ -86,6 +96,7 @@ void Utility::translateLdsConfig(const Json::Object& json_lds, json_lds.validateSchema(Json::Schema::LDS_CONFIG_SCHEMA); translateApiConfigSource(json_lds.getString("cluster"), json_lds.getInteger("refresh_delay_ms", 30000), + json_lds.getString("api_type", ApiType::get().RestLegacy), *lds_config.mutable_api_config_source()); } diff --git a/source/common/config/utility.h b/source/common/config/utility.h index 57c65472f12d2..ade756ca2ac6c 100644 --- a/source/common/config/utility.h +++ b/source/common/config/utility.h @@ -5,6 +5,7 @@ #include "envoy/local_info/local_info.h" #include "envoy/upstream/cluster_manager.h" +#include "common/common/singleton.h" #include "common/protobuf/protobuf.h" #include "api/base.pb.h" @@ -13,6 +14,18 @@ namespace Envoy { namespace Config { +/** + * Constant Api Type Values, used by envoy::api::v2::ApiConfigSource. + */ +class ApiTypeValues { +public: + const std::string RestLegacy{"REST_LEGACY"}; + const std::string Rest{"REST"}; + const std::string Grpc{"GRPC"}; +}; + +typedef ConstSingleton ApiType; + /** * General config API utilities. */ @@ -40,6 +53,17 @@ class Utility { static std::chrono::milliseconds apiConfigSourceRefreshDelay(const envoy::api::v2::ApiConfigSource& api_config_source); + /** + * Populate an envoy::api::v2::ApiConfigSource. + * @param cluster supplies the cluster name for the ApiConfigSource. + * @param refresh_delay_ms supplies the refresh delay for the ApiConfigSource in ms. + * @param api_type supplies the type of subscription to use for the ApiConfigSource. + * @param api_config_source a reference to the envoy::api::v2::ApiConfigSource object to populate. + */ + static void translateApiConfigSource(const std::string& cluster, uint32_t refresh_delay_ms, + const std::string& api_type, + envoy::api::v2::ApiConfigSource& api_config_source); + /** * Check cluster info for API config sanity. Throws on error. * @param error_prefix supplies the prefix to use in error messages. diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index d6c8617f04651..177d0cea2bfe4 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -103,6 +103,10 @@ const std::string Json::Schema::RDS_CONFIGURATION_SCHEMA(R"EOF( "type" : "integer", "minimum" : 0, "exclusiveMinimum" : true + }, + "api_type" : { + "type" : "string", + "enum" : ["REST_LEGACY", "REST", "GRPC"] } }, "required" : ["cluster", "route_config_name"], diff --git a/test/common/config/utility_test.cc b/test/common/config/utility_test.cc index 72b6415c23b08..1c400020b5f39 100644 --- a/test/common/config/utility_test.cc +++ b/test/common/config/utility_test.cc @@ -38,5 +38,31 @@ TEST(UtilityTest, ApiConfigSourceRefreshDelay) { EXPECT_EQ(1234, Utility::apiConfigSourceRefreshDelay(api_config_source).count()); } +TEST(UtilityTest, TranslateApiConfigSource) { + envoy::api::v2::ApiConfigSource api_config_source_rest_legacy; + Utility::translateApiConfigSource("test_rest_legacy_cluster", 10000, ApiType::get().RestLegacy, + api_config_source_rest_legacy); + EXPECT_EQ(envoy::api::v2::ApiConfigSource::REST_LEGACY, api_config_source_rest_legacy.api_type()); + EXPECT_EQ(10000, Protobuf::util::TimeUtil::DurationToMilliseconds( + api_config_source_rest_legacy.refresh_delay())); + EXPECT_EQ("test_rest_legacy_cluster", api_config_source_rest_legacy.cluster_name(0)); + + envoy::api::v2::ApiConfigSource api_config_source_rest; + Utility::translateApiConfigSource("test_rest_cluster", 20000, ApiType::get().Rest, + api_config_source_rest); + EXPECT_EQ(envoy::api::v2::ApiConfigSource::REST, api_config_source_rest.api_type()); + EXPECT_EQ(20000, Protobuf::util::TimeUtil::DurationToMilliseconds( + api_config_source_rest.refresh_delay())); + EXPECT_EQ("test_rest_cluster", api_config_source_rest.cluster_name(0)); + + envoy::api::v2::ApiConfigSource api_config_source_grpc; + Utility::translateApiConfigSource("test_grpc_cluster", 30000, ApiType::get().Grpc, + api_config_source_grpc); + EXPECT_EQ(envoy::api::v2::ApiConfigSource::GRPC, api_config_source_grpc.api_type()); + EXPECT_EQ(30000, Protobuf::util::TimeUtil::DurationToMilliseconds( + api_config_source_grpc.refresh_delay())); + EXPECT_EQ("test_grpc_cluster", api_config_source_grpc.cluster_name(0)); +} + } // namespace Config } // namespace Envoy