Skip to content

Commit

Permalink
config: refactor filter registration (#1083)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattklein123 authored and RomanDzhabarov committed Jun 13, 2017
1 parent 23d018a commit e9c56dc
Show file tree
Hide file tree
Showing 73 changed files with 745 additions and 557 deletions.
2 changes: 1 addition & 1 deletion ci/build_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ then
fi

# This is the hash on https://github.com/lyft/envoy-filter-example.git we pin to.
(cd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" && git fetch origin && git checkout 48f83f5c697e61863b085e353cbdf77c4bba6d2a)
(cd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" && git fetch origin && git checkout b85101b303b3c256c70927a8389c15bde871a2aa)
cp -f "${ENVOY_SRCDIR}"/ci/WORKSPACE.filter.example "${ENVOY_FILTER_EXAMPLE_SRCDIR}"/WORKSPACE

# Also setup some space for building Envoy standalone.
Expand Down
16 changes: 16 additions & 0 deletions include/envoy/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,19 @@ envoy_cc_library(
"//include/envoy/network:address_interface",
],
)

envoy_cc_library(
name = "filter_config_interface",
hdrs = ["filter_config.h"],
deps = [
":drain_manager_interface",
"//include/envoy/access_log:access_log_interface",
"//include/envoy/init:init_interface",
"//include/envoy/local_info:local_info_interface",
"//include/envoy/ratelimit:ratelimit_interface",
"//include/envoy/runtime:runtime_interface",
"//include/envoy/thread_local:thread_local_interface",
"//include/envoy/tracing:http_tracer_interface",
"//include/envoy/upstream:cluster_manager_interface",
],
)
203 changes: 203 additions & 0 deletions include/envoy/server/filter_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
#pragma once

#include <functional>

#include "envoy/access_log/access_log.h"
#include "envoy/http/filter.h"
#include "envoy/init/init.h"
#include "envoy/json/json_object.h"
#include "envoy/network/filter.h"
#include "envoy/ratelimit/ratelimit.h"
#include "envoy/runtime/runtime.h"
#include "envoy/server/drain_manager.h"
#include "envoy/server/instance.h" // TODO(mattklein123): Remove post 1.4.0
#include "envoy/tracing/http_tracer.h"
#include "envoy/upstream/cluster_manager.h"

namespace Envoy {
namespace Server {
namespace Configuration {

/**
* Context passed to network and HTTP filters to access server resources.
* TODO(mattklein123): When we lock down visibility of the rest of the code, filters should only
* access the rest of the server via interfaces exposed here.
*/
class FactoryContext {
public:
virtual ~FactoryContext() {}

/**
* @return AccessLogManager for use by the entire server.
*/
virtual AccessLog::AccessLogManager& accessLogManager() PURE;

/**
* @return Upstream::ClusterManager& singleton for use by the entire server.
*/
virtual Upstream::ClusterManager& clusterManager() PURE;

/**
* @return Event::Dispatcher& the main thread's dispatcher. This dispatcher should be used
* for all singleton processing.
*/
virtual Event::Dispatcher& dispatcher() PURE;

/**
* @return DrainManager& singleton for use by the entire server.
*/
virtual DrainManager& drainManager() PURE;

/**
* @return whether external healthchecks are currently failed or not.
*/
virtual bool healthCheckFailed() PURE;

/**
* @return the server-wide http tracer.
*/
virtual Tracing::HttpTracer& httpTracer() PURE;

/**
* @return the server's init manager. This can be used for extensions that need to initialize
* after cluster manager init but before the server starts listening. All extensions
* should register themselves during configuration load. initialize() will be called on
* each registered target after cluster manager init but before the server starts
* listening. Once all targets have initialized and invoked their callbacks, the server
* will start listening.
*/
virtual Init::Manager& initManager() PURE;

/**
* @return information about the local environment the server is running in.
*/
virtual const LocalInfo::LocalInfo& localInfo() PURE;

/**
* @return RandomGenerator& the random generator for the server.
*/
virtual Envoy::Runtime::RandomGenerator& random() PURE;

/**
* @return a new ratelimit client. The implementation depends on the configuration of the server.
*/
virtual RateLimit::ClientPtr
rateLimitClient(const Optional<std::chrono::milliseconds>& timeout) PURE;

/**
* @return Runtime::Loader& the singleton runtime loader for the server.
*/
virtual Envoy::Runtime::Loader& runtime() PURE;

/**
* DEPRECATED: Do not call this function. It will be removed post 1.4.0 and is needed for other
* deprecated functionality.
*/
virtual Instance& server() PURE;

/**
* @return Stats::Scope& the filter's stats scope.
*/
virtual Stats::Scope& scope() PURE;

/**
* @return ThreadLocal::Instance& the thread local storage engine for the server. This is used to
* allow runtime lockless updates to configuration, etc. across multiple threads.
*/
virtual ThreadLocal::Instance& threadLocal() PURE;
};

enum class NetworkFilterType { Read, Write, Both };

/**
* This function is used to wrap the creation of a network filter chain for new connections as
* they come in. Filter factories create the lambda at configuration initialization time, and then
* they are used at runtime.
* @param filter_manager supplies the filter manager for the connection to install filters
* to. Typically the function will install a single filter, but it's technically possibly to
* install more than one if desired.
*/
typedef std::function<void(Network::FilterManager& filter_manager)> NetworkFilterFactoryCb;

/**
* Implemented by each network filter and registered via registerNamedNetworkFilterConfigFactory()
* or the convenience class RegisterNamedNetworkFilterConfigFactory.
*/
class NamedNetworkFilterConfigFactory {
public:
virtual ~NamedNetworkFilterConfigFactory() {}

/**
* Create a particular network filter factory implementation. If the implementation is unable to
* produce a factory with the provided parameters, it should throw an EnvoyException in the case
* of general error or a Json::Exception if the json configuration is erroneous. The returned
* callback should always be initialized.
* @param config supplies the general json configuration for the filter
* @param context supplies the filter's context.
* @return NetworkFilterFactoryCb the factory creation function.
*/
virtual NetworkFilterFactoryCb createFilterFactory(const Json::Object& config,
FactoryContext& context) PURE;

/**
* @return std::string the identifying name for a particular implementation of a network filter
* produced by the factory.
*/
virtual std::string name() PURE;

/**
* @return NetworkFilterType the type of filter.
*/
virtual NetworkFilterType type() PURE;
};

enum class HttpFilterType { Decoder, Encoder, Both };

/**
* This function is used to wrap the creation of an HTTP filter chain for new streams as they
* come in. Filter factories create the function at configuration initialization time, and then
* they are used at runtime.
* @param callbacks supplies the callbacks for the stream to install filters to. Typically the
* function will install a single filter, but it's technically possibly to install more than one
* if desired.
*/
typedef std::function<void(Http::FilterChainFactoryCallbacks& callbacks)> HttpFilterFactoryCb;

/**
* Implemented by each HTTP filter and registered via registerNamedHttpFilterConfigFactory() or the
* convenience class RegisterNamedHttpFilterConfigFactory.
*/
class NamedHttpFilterConfigFactory {
public:
virtual ~NamedHttpFilterConfigFactory() {}

/**
* Create a particular http filter factory implementation. If the implementation is unable to
* produce a factory with the provided parameters, it should throw an EnvoyException in the case
* of
* general error or a Json::Exception if the json configuration is erroneous. The returned
* callback should always be initialized.
* @param config supplies the general json configuration for the filter
* @param stat_prefix prefix for stat logging
* @param context supplies the filter's context.
* @return HttpFilterFactoryCb the factory creation function.
*/
virtual HttpFilterFactoryCb createFilterFactory(const Json::Object& config,
const std::string& stat_prefix,
FactoryContext& context) PURE;

/**
* @return std::string the identifying name for a particular implementation of an http filter
* produced by the factory.
*/
virtual std::string name() PURE;

/**
* @return HttpFilterType the type of filter.
*/
virtual HttpFilterType type() PURE;
};

} // Configuration
} // Server
} // Envoy
4 changes: 2 additions & 2 deletions source/common/dynamo/dynamo_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Dynamo {
*/
class DynamoFilter : public Http::StreamFilter {
public:
DynamoFilter(Runtime::Loader& runtime, const std::string& stat_prefix, Stats::Store& stats)
DynamoFilter(Runtime::Loader& runtime, const std::string& stat_prefix, Stats::Scope& stats)
: runtime_(runtime), stat_prefix_(stat_prefix + "dynamodb."), stats_(stats) {
enabled_ = runtime_.snapshot().featureEnabled("dynamodb.filter_enabled", 100);
}
Expand Down Expand Up @@ -58,7 +58,7 @@ class DynamoFilter : public Http::StreamFilter {

Runtime::Loader& runtime_;
std::string stat_prefix_;
Stats::Store& stats_;
Stats::Scope& stats_;

bool enabled_{};
std::string operation_{};
Expand Down
6 changes: 3 additions & 3 deletions source/common/filter/auth/client_ssl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Auth {
namespace ClientSsl {

Config::Config(const Json::Object& config, ThreadLocal::Instance& tls, Upstream::ClusterManager& cm,
Event::Dispatcher& dispatcher, Stats::Store& stats_store,
Event::Dispatcher& dispatcher, Stats::Scope& stats_store,
Runtime::RandomGenerator& random)
: RestApiFetcher(cm, config.getString("auth_api_cluster"), dispatcher, random,
std::chrono::milliseconds(config.getInteger("refresh_delay_ms", 60000))),
Expand All @@ -43,7 +43,7 @@ Config::Config(const Json::Object& config, ThreadLocal::Instance& tls, Upstream:

ConfigSharedPtr Config::create(const Json::Object& config, ThreadLocal::Instance& tls,
Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher,
Stats::Store& stats_store, Runtime::RandomGenerator& random) {
Stats::Scope& stats_store, Runtime::RandomGenerator& random) {
ConfigSharedPtr new_config(new Config(config, tls, cm, dispatcher, stats_store, random));
new_config->initialize();
return new_config;
Expand All @@ -53,7 +53,7 @@ const AllowedPrincipals& Config::allowedPrincipals() {
return tls_.getTyped<AllowedPrincipals>(tls_slot_);
}

GlobalStats Config::generateStats(Stats::Store& store, const std::string& prefix) {
GlobalStats Config::generateStats(Stats::Scope& store, const std::string& prefix) {
std::string final_prefix = fmt::format("auth.clientssl.{}.", prefix);
GlobalStats stats{ALL_CLIENT_SSL_AUTH_STATS(POOL_COUNTER_PREFIX(store, final_prefix),
POOL_GAUGE_PREFIX(store, final_prefix))};
Expand Down
6 changes: 3 additions & 3 deletions source/common/filter/auth/client_ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ class Config : public Http::RestApiFetcher {
public:
static ConfigSharedPtr create(const Json::Object& config, ThreadLocal::Instance& tls,
Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher,
Stats::Store& stats_store, Runtime::RandomGenerator& random);
Stats::Scope& stats_store, Runtime::RandomGenerator& random);

const AllowedPrincipals& allowedPrincipals();
const Network::IpList& ipWhiteList() { return ip_white_list_; }
GlobalStats& stats() { return stats_; }

private:
Config(const Json::Object& config, ThreadLocal::Instance& tls, Upstream::ClusterManager& cm,
Event::Dispatcher& dispatcher, Stats::Store& stats_store,
Event::Dispatcher& dispatcher, Stats::Scope& stats_store,
Runtime::RandomGenerator& random);

static GlobalStats generateStats(Stats::Store& store, const std::string& prefix);
static GlobalStats generateStats(Stats::Scope& store, const std::string& prefix);

// Http::RestApiFetcher
void createRequest(Http::Message& request) override;
Expand Down
4 changes: 2 additions & 2 deletions source/common/filter/ratelimit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Envoy {
namespace RateLimit {
namespace TcpFilter {

Config::Config(const Json::Object& config, Stats::Store& stats_store, Runtime::Loader& runtime)
Config::Config(const Json::Object& config, Stats::Scope& stats_store, Runtime::Loader& runtime)
: domain_(config.getString("domain")),
stats_(generateStats(config.getString("stat_prefix"), stats_store)), runtime_(runtime) {

Expand All @@ -27,7 +27,7 @@ Config::Config(const Json::Object& config, Stats::Store& stats_store, Runtime::L
}
}

InstanceStats Config::generateStats(const std::string& name, Stats::Store& store) {
InstanceStats Config::generateStats(const std::string& name, Stats::Scope& store) {
std::string final_prefix = fmt::format("ratelimit.{}.", name);
return {ALL_TCP_RATE_LIMIT_STATS(POOL_COUNTER_PREFIX(store, final_prefix),
POOL_GAUGE_PREFIX(store, final_prefix))};
Expand Down
4 changes: 2 additions & 2 deletions source/common/filter/ratelimit.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ struct InstanceStats {
*/
class Config {
public:
Config(const Json::Object& config, Stats::Store& stats_store, Runtime::Loader& runtime);
Config(const Json::Object& config, Stats::Scope& stats_store, Runtime::Loader& runtime);
const std::string& domain() { return domain_; }
const std::vector<Descriptor>& descriptors() { return descriptors_; }
Runtime::Loader& runtime() { return runtime_; }
const InstanceStats& stats() { return stats_; }

private:
static InstanceStats generateStats(const std::string& name, Stats::Store& store);
static InstanceStats generateStats(const std::string& name, Stats::Scope& store);

std::string domain_;
std::vector<Descriptor> descriptors_;
Expand Down
4 changes: 2 additions & 2 deletions source/common/filter/tcp_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ TcpProxyConfig::Route::Route(const Json::Object& config) {
}

TcpProxyConfig::TcpProxyConfig(const Json::Object& config,
Upstream::ClusterManager& cluster_manager, Stats::Store& stats_store)
Upstream::ClusterManager& cluster_manager, Stats::Scope& stats_store)
: stats_(generateStats(config.getString("stat_prefix"), stats_store)) {
config.validateSchema(Json::Schema::TCP_PROXY_NETWORK_FILTER_SCHEMA);

Expand Down Expand Up @@ -106,7 +106,7 @@ TcpProxy::~TcpProxy() {
}
}

TcpProxyStats TcpProxyConfig::generateStats(const std::string& name, Stats::Store& store) {
TcpProxyStats TcpProxyConfig::generateStats(const std::string& name, Stats::Scope& store) {
std::string final_prefix = fmt::format("tcp.{}.", name);
return {ALL_TCP_PROXY_STATS(POOL_COUNTER_PREFIX(store, final_prefix),
POOL_GAUGE_PREFIX(store, final_prefix))};
Expand Down
4 changes: 2 additions & 2 deletions source/common/filter/tcp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct TcpProxyStats {
class TcpProxyConfig {
public:
TcpProxyConfig(const Json::Object& config, Upstream::ClusterManager& cluster_manager,
Stats::Store& stats_store);
Stats::Scope& stats_store);

/**
* Find out which cluster an upstream connection should be opened to based on the
Expand All @@ -70,7 +70,7 @@ class TcpProxyConfig {
std::string cluster_name_;
};

static TcpProxyStats generateStats(const std::string& name, Stats::Store& store);
static TcpProxyStats generateStats(const std::string& name, Stats::Scope& store);

std::vector<Route> routes_;
const TcpProxyStats stats_;
Expand Down
4 changes: 2 additions & 2 deletions source/common/http/codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CodeUtility {
Code response_code);

struct ResponseStatInfo {
Stats::Store& global_store_;
Stats::Scope& global_store_;
Stats::Scope& cluster_scope_;
const std::string& prefix_;
const HeaderMap& response_headers_;
Expand All @@ -43,7 +43,7 @@ class CodeUtility {
static void chargeResponseStat(const ResponseStatInfo& info);

struct ResponseTimingInfo {
Stats::Store& global_store_;
Stats::Scope& global_store_;
Stats::Scope& cluster_scope_;
const std::string& prefix_;
std::chrono::milliseconds response_time_;
Expand Down
Loading

0 comments on commit e9c56dc

Please sign in to comment.