diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index d04e7ad6d866a..c871602abdc55 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -156,7 +156,7 @@ def envoy_api_deps(skip_targets): ] for t in http_filter_bind_targets: native.bind( - name = "envoy_filter_" + t, + name = "envoy_filter_http_" + t, actual = "@envoy_api//api/filter/http:" + t + "_cc", ) network_filter_bind_targets = [ @@ -168,7 +168,7 @@ def envoy_api_deps(skip_targets): ] for t in network_filter_bind_targets: native.bind( - name = "envoy_filter_" + t, + name = "envoy_filter_network_" + t, actual = "@envoy_api//api/filter/network:" + t + "_cc", ) native.bind( diff --git a/include/envoy/router/BUILD b/include/envoy/router/BUILD index c05c964fe3f81..2ed8431718419 100644 --- a/include/envoy/router/BUILD +++ b/include/envoy/router/BUILD @@ -17,7 +17,7 @@ envoy_cc_library( envoy_cc_library( name = "route_config_provider_manager_interface", hdrs = ["route_config_provider_manager.h"], - external_deps = ["envoy_filter_http_connection_manager"], + external_deps = ["envoy_filter_http_http_connection_manager"], deps = [ ":rds_interface", "//include/envoy/event:dispatcher_interface", diff --git a/source/common/config/BUILD b/source/common/config/BUILD index a31fb3344b72f..fababa9383c66 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -87,7 +87,10 @@ envoy_cc_library( name = "filter_json_lib", srcs = ["filter_json.cc"], hdrs = ["filter_json.h"], - external_deps = ["envoy_filter_http_connection_manager"], + external_deps = [ + "envoy_filter_http_http_connection_manager", + "envoy_filter_network_mongo_proxy", + ], deps = [ ":json_utility_lib", ":protocol_json_lib", @@ -274,7 +277,7 @@ envoy_cc_library( "envoy_eds", "envoy_lds", "envoy_rds", - "envoy_filter_http_connection_manager", + "envoy_filter_http_http_connection_manager", ], deps = [ ":json_utility_lib", diff --git a/source/common/config/filter_json.cc b/source/common/config/filter_json.cc index 4eeb33042d34e..33e2661489572 100644 --- a/source/common/config/filter_json.cc +++ b/source/common/config/filter_json.cc @@ -213,5 +213,21 @@ void FilterJson::translateHttpConnectionManager( } } +void FilterJson::translateMongoProxy(const Json::Object& json_mongo_proxy, + envoy::api::v2::filter::network::MongoProxy& mongo_proxy) { + json_mongo_proxy.validateSchema(Json::Schema::MONGO_PROXY_NETWORK_FILTER_SCHEMA); + + JSON_UTIL_SET_STRING(json_mongo_proxy, mongo_proxy, stat_prefix); + JSON_UTIL_SET_STRING(json_mongo_proxy, mongo_proxy, access_log); + if (json_mongo_proxy.hasObject("fault")) { + const auto json_fault = json_mongo_proxy.getObject("fault")->getObject("fixed_delay"); + auto* delay = mongo_proxy.mutable_delay(); + + delay->set_type(envoy::api::v2::filter::FaultDelay::FIXED); + delay->set_percent(static_cast(json_fault->getInteger("percent"))); + JSON_UTIL_SET_DURATION_FROM_FIELD(*json_fault, *delay, fixed_delay, duration); + } +} + } // namespace Config } // namespace Envoy diff --git a/source/common/config/filter_json.h b/source/common/config/filter_json.h index 31f80abe196fa..17e9b1d7794d4 100644 --- a/source/common/config/filter_json.h +++ b/source/common/config/filter_json.h @@ -3,6 +3,7 @@ #include "envoy/json/json_object.h" #include "api/filter/http/http_connection_manager.pb.h" +#include "api/filter/network/mongo_proxy.pb.h" namespace Envoy { namespace Config { @@ -36,6 +37,15 @@ class FilterJson { static void translateHttpConnectionManager( const Json::Object& json_http_connection_manager, envoy::api::v2::filter::http::HttpConnectionManager& http_connection_manager); + + /** + * Translate a v1 JSON Mongo proxy object to v2 envoy::api::v2::filter::network::MongoProxy. + * @param json_mongo_proxy source v1 JSON HTTP connection manager object. + * @param mongo_proxy destination v2 + * envoy::api::v2::filter::network::MongoProxy. + */ + static void translateMongoProxy(const Json::Object& json_mongo_proxy, + envoy::api::v2::filter::network::MongoProxy& mongo_proxy); }; } // namespace Config diff --git a/source/common/config/json_utility.h b/source/common/config/json_utility.h index a01c8ff5eecc2..888aa2b667950 100644 --- a/source/common/config/json_utility.h +++ b/source/common/config/json_utility.h @@ -50,3 +50,13 @@ 1000 * (json).getInteger(#field_name "_s"))); \ } \ } while (0) + +// Set a google.protobuf.Duration field in a protobuf message with the specified field's +// milliseconds value from a JSON object if the field is set in the JSON object. +#define JSON_UTIL_SET_DURATION_FROM_FIELD(json, message, dst_field, src_field) \ + do { \ + if ((json).hasObject(#src_field "_ms")) { \ + (message).mutable_##dst_field()->CopyFrom( \ + Protobuf::util::TimeUtil::MillisecondsToDuration((json).getInteger(#src_field "_ms"))); \ + } \ + } while (0) diff --git a/source/common/http/access_log/BUILD b/source/common/http/access_log/BUILD index c824c582c2373..7b5cd505b6c98 100644 --- a/source/common/http/access_log/BUILD +++ b/source/common/http/access_log/BUILD @@ -23,7 +23,7 @@ envoy_cc_library( name = "access_log_lib", srcs = ["access_log_impl.cc"], hdrs = ["access_log_impl.h"], - external_deps = ["envoy_filter_http_connection_manager"], + external_deps = ["envoy_filter_http_http_connection_manager"], deps = [ "//include/envoy/access_log:access_log_interface", "//include/envoy/filesystem:filesystem_interface", diff --git a/source/common/mongo/BUILD b/source/common/mongo/BUILD index f99889edf0825..a9416fbd6f35c 100644 --- a/source/common/mongo/BUILD +++ b/source/common/mongo/BUILD @@ -40,6 +40,7 @@ envoy_cc_library( name = "proxy_lib", srcs = ["proxy.cc"], hdrs = ["proxy.h"], + external_deps = ["envoy_filter_network_mongo_proxy"], deps = [ ":codec_lib", ":utility_lib", @@ -57,7 +58,9 @@ envoy_cc_library( "//source/common/common:logger_lib", "//source/common/common:singleton", "//source/common/common:utility_lib", + "//source/common/config:filter_json_lib", "//source/common/network:filter_lib", + "//source/common/protobuf:utility_lib", ], ) diff --git a/source/common/mongo/proxy.h b/source/common/mongo/proxy.h index 0922fe9d81615..8e8b1b057f189 100644 --- a/source/common/mongo/proxy.h +++ b/source/common/mongo/proxy.h @@ -19,9 +19,11 @@ #include "common/buffer/buffer_impl.h" #include "common/common/logger.h" #include "common/common/singleton.h" -#include "common/json/json_loader.h" #include "common/mongo/utility.h" #include "common/network/filter_impl.h" +#include "common/protobuf/utility.h" + +#include "api/filter/network/mongo_proxy.pb.h" namespace Envoy { namespace Mongo { @@ -92,12 +94,9 @@ typedef std::shared_ptr AccessLogSharedPtr; */ class FaultConfig { public: - FaultConfig(const Json::Object& fault_config) - : delay_percent_( - static_cast(fault_config.getObject("fixed_delay")->getInteger("percent"))), - duration_ms_(static_cast( - fault_config.getObject("fixed_delay")->getInteger("duration_ms"))) {} - + FaultConfig(const envoy::api::v2::filter::FaultDelay& fault_config) + : delay_percent_(fault_config.percent()), + duration_ms_(PROTOBUF_GET_MS_REQUIRED(fault_config, fixed_delay)) {} uint32_t delayPercent() const { return delay_percent_; } uint64_t delayDuration() const { return duration_ms_; } diff --git a/source/common/router/BUILD b/source/common/router/BUILD index 2b13b1c51d4fe..35fc49b97af70 100644 --- a/source/common/router/BUILD +++ b/source/common/router/BUILD @@ -56,7 +56,7 @@ envoy_cc_library( srcs = ["rds_impl.cc"], hdrs = ["rds_impl.h"], external_deps = [ - "envoy_filter_http_connection_manager", + "envoy_filter_http_http_connection_manager", "envoy_rds", ], deps = [ @@ -85,7 +85,7 @@ envoy_cc_library( srcs = ["rds_subscription.cc"], hdrs = ["rds_subscription.h"], external_deps = [ - "envoy_filter_http_connection_manager", + "envoy_filter_http_http_connection_manager", ], deps = [ "//include/envoy/config:subscription_interface", diff --git a/source/server/config/http/BUILD b/source/server/config/http/BUILD index cc3923f4717e7..b4b887bf9b7f8 100644 --- a/source/server/config/http/BUILD +++ b/source/server/config/http/BUILD @@ -62,7 +62,7 @@ envoy_cc_library( name = "file_access_log_lib", srcs = ["file_access_log.cc"], hdrs = ["file_access_log.h"], - external_deps = ["envoy_filter_http_connection_manager"], + external_deps = ["envoy_filter_http_http_connection_manager"], deps = [ "//include/envoy/registry", "//include/envoy/server:access_log_config_interface", diff --git a/source/server/config/network/BUILD b/source/server/config/network/BUILD index 5b6413bb8117e..91ac19309d8ca 100644 --- a/source/server/config/network/BUILD +++ b/source/server/config/network/BUILD @@ -67,8 +67,6 @@ envoy_cc_library( "//include/envoy/registry", "//include/envoy/server:filter_config_interface", "//source/common/config:well_known_names", - "//source/common/json:config_schemas_lib", - "//source/common/json:json_loader_lib", "//source/common/mongo:proxy_lib", ], ) diff --git a/source/server/config/network/mongo_proxy.cc b/source/server/config/network/mongo_proxy.cc index fbbfe63966061..9f50c608e8cd1 100644 --- a/source/server/config/network/mongo_proxy.cc +++ b/source/server/config/network/mongo_proxy.cc @@ -5,28 +5,31 @@ #include "envoy/network/connection.h" #include "envoy/registry/registry.h" -#include "common/json/config_schemas.h" +#include "common/config/filter_json.h" #include "common/mongo/proxy.h" +#include "api/filter/network/mongo_proxy.pb.h" + namespace Envoy { namespace Server { namespace Configuration { -NetworkFilterFactoryCb -MongoProxyFilterConfigFactory::createFilterFactory(const Json::Object& config, - FactoryContext& context) { - config.validateSchema(Json::Schema::MONGO_PROXY_NETWORK_FILTER_SCHEMA); +NetworkFilterFactoryCb MongoProxyFilterConfigFactory::createMongoProxyFactory( + const envoy::api::v2::filter::network::MongoProxy& mongo_proxy, FactoryContext& context) { + + ASSERT(!mongo_proxy.stat_prefix().empty()); + std::string stat_prefix = "mongo." + mongo_proxy.stat_prefix() + "."; - std::string stat_prefix = "mongo." + config.getString("stat_prefix") + "."; Mongo::AccessLogSharedPtr access_log; - if (config.hasObject("access_log")) { - access_log.reset( - new Mongo::AccessLog(config.getString("access_log"), context.accessLogManager())); + if (!mongo_proxy.access_log().empty()) { + access_log.reset(new Mongo::AccessLog(mongo_proxy.access_log(), context.accessLogManager())); } Mongo::FaultConfigSharedPtr fault_config; - if (config.hasObject("fault")) { - fault_config = std::make_shared(*config.getObject("fault")); + if (mongo_proxy.has_delay()) { + auto delay = mongo_proxy.delay(); + ASSERT(delay.has_fixed_delay()); + fault_config = std::make_shared(mongo_proxy.delay()); } return [stat_prefix, &context, access_log, @@ -36,6 +39,22 @@ MongoProxyFilterConfigFactory::createFilterFactory(const Json::Object& config, }; } +NetworkFilterFactoryCb +MongoProxyFilterConfigFactory::createFilterFactory(const Json::Object& json_mongo_proxy, + FactoryContext& context) { + envoy::api::v2::filter::network::MongoProxy mongo_proxy; + Config::FilterJson::translateMongoProxy(json_mongo_proxy, mongo_proxy); + + return createMongoProxyFactory(mongo_proxy, context); +} + +NetworkFilterFactoryCb +MongoProxyFilterConfigFactory::createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) { + return createMongoProxyFactory( + dynamic_cast(config), context); +} + /** * Static registration for the mongo filter. @see RegisterFactory. */ diff --git a/source/server/config/network/mongo_proxy.h b/source/server/config/network/mongo_proxy.h index 99cb274233d3c..73f5105db0650 100644 --- a/source/server/config/network/mongo_proxy.h +++ b/source/server/config/network/mongo_proxy.h @@ -6,6 +6,8 @@ #include "common/config/well_known_names.h" +#include "api/filter/network/mongo_proxy.pb.h" + namespace Envoy { namespace Server { namespace Configuration { @@ -18,8 +20,15 @@ class MongoProxyFilterConfigFactory : public NamedNetworkFilterConfigFactory { // NamedNetworkFilterConfigFactory NetworkFilterFactoryCb createFilterFactory(const Json::Object& config, FactoryContext& context) override; + NetworkFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) override; std::string name() override { return Config::NetworkFilterNames::get().MONGO_PROXY; } + +private: + NetworkFilterFactoryCb + createMongoProxyFactory(const envoy::api::v2::filter::network::MongoProxy& mongo_proxy, + FactoryContext& context); }; } // namespace Configuration diff --git a/test/common/http/access_log/BUILD b/test/common/http/access_log/BUILD index 277e0d3abdfd1..111313530c445 100644 --- a/test/common/http/access_log/BUILD +++ b/test/common/http/access_log/BUILD @@ -24,7 +24,7 @@ envoy_cc_test( envoy_cc_test( name = "access_log_impl_test", srcs = ["access_log_impl_test.cc"], - external_deps = ["envoy_filter_http_connection_manager"], + external_deps = ["envoy_filter_http_http_connection_manager"], deps = [ "//include/envoy/upstream:cluster_manager_interface", "//include/envoy/upstream:upstream_interface", diff --git a/test/common/mongo/proxy_test.cc b/test/common/mongo/proxy_test.cc index b6569a9fa4790..0010666b332ca 100644 --- a/test/common/mongo/proxy_test.cc +++ b/test/common/mongo/proxy_test.cc @@ -15,6 +15,7 @@ #include "test/mocks/runtime/mocks.h" #include "test/test_common/printers.h" +#include "api/filter/fault.pb.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -76,17 +77,11 @@ class MongoProxyFilterTest : public testing::Test { } void setupDelayFault(bool enable_fault) { - const std::string json_config = R"EOF( - { - "fixed_delay": { - "percent": 50, - "duration_ms": 10 - } - } - )EOF"; - Json::ObjectSharedPtr config = Json::Factory::loadFromString(json_config); + envoy::api::v2::filter::FaultDelay fault{}; + fault.set_percent(50); + fault.mutable_fixed_delay()->CopyFrom(Protobuf::util::TimeUtil::MillisecondsToDuration(10)); - fault_config_.reset(new FaultConfig(*config)); + fault_config_.reset(new FaultConfig(fault)); EXPECT_CALL(runtime_.snapshot_, featureEnabled(_, _)).Times(AnyNumber()); EXPECT_CALL(runtime_.snapshot_, featureEnabled("mongo.fault.fixed_delay.percent", 50)) diff --git a/test/server/config/network/mongo_proxy_test.cc b/test/server/config/network/mongo_proxy_test.cc index e7e5c1ebc24c4..ed4f608fd5112 100644 --- a/test/server/config/network/mongo_proxy_test.cc +++ b/test/server/config/network/mongo_proxy_test.cc @@ -5,6 +5,7 @@ #include "test/mocks/server/mocks.h" #include "test/test_common/utility.h" +#include "api/filter/network/mongo_proxy.pb.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -32,6 +33,20 @@ TEST(MongoFilterConfigTest, CorrectConfigurationNoFaults) { cb(connection); } +TEST(MongoFilterConfigTest, ValidProtoConfigurationNoFaults) { + envoy::api::v2::filter::network::MongoProxy config{}; + + config.set_access_log("path/to/access/log"); + config.set_stat_prefix("my_stat_prefix"); + + NiceMock context; + MongoProxyFilterConfigFactory factory; + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addFilter(_)); + cb(connection); +} + void handleInvalidConfiguration(const std::string& json_string) { Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock context; @@ -217,6 +232,20 @@ TEST(MongoFilterConfigTest, CorrectFaultConfiguration) { cb(connection); } +TEST(MongoFilterConfigTest, CorrectFaultConfigurationInProto) { + envoy::api::v2::filter::network::MongoProxy config{}; + config.set_stat_prefix("my_stat_prefix"); + config.mutable_delay()->set_percent(50); + config.mutable_delay()->mutable_fixed_delay()->set_seconds(500); + + NiceMock context; + MongoProxyFilterConfigFactory factory; + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addFilter(_)); + cb(connection); +} + } // namespace Configuration } // namespace Server } // namespace Envoy