Skip to content

Commit

Permalink
filter state: add an object factory
Browse files Browse the repository at this point in the history
Signed-off-by: Kuat Yessenov <kuat@google.com>
  • Loading branch information
kyessenov committed Aug 15, 2023
1 parent d3c384a commit 9a1a3d5
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/root/configuration/advanced/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Advanced
:maxdepth: 2

well_known_dynamic_metadata
well_known_filter_state
12 changes: 12 additions & 0 deletions docs/root/configuration/advanced/well_known_filter_state.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.. _well_known_filter_state:

Well Known Filter State Objects
===============================

The following list of filter state objects are consumed by Envoy extensions:

.. csv-table::
:header: Filter state key, Purpose
:widths: 1, 3

``envoy.tcp_proxy.cluster``, :ref:`TCP proxy <config_network_filters_tcp_proxy>` dynamic cluster selection on a per-connection basis
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ addition, it provides a facility to store typed objects in a map
(``map<string, FilterState::Object>``). The state stored per filter can be
either write-once (immutable), or write-many (mutable).

See :ref:`the well-known dynamic metadata <well_known_dynamic_metadata>` and
:ref:`the well-known filter state <well_known_filter_state>` for the reference
list of the dynamic metadata and the filter state objects.

.. _arch_overview_advanced_filter_state_sharing:

Filter state sharing
Expand Down
1 change: 1 addition & 0 deletions envoy/stream_info/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ envoy_cc_library(
hdrs = ["filter_state.h"],
external_deps = ["abseil_optional"],
deps = [
"//envoy/config:typed_config_interface",
"//source/common/common:fmt_lib",
"//source/common/common:utility_lib",
"//source/common/protobuf",
Expand Down
18 changes: 18 additions & 0 deletions envoy/stream_info/filter_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <vector>

#include "envoy/common/pure.h"
#include "envoy/config/typed_config.h"

#include "source/common/common/fmt.h"
#include "source/common/common/utility.h"
Expand Down Expand Up @@ -103,6 +104,23 @@ class FilterState {
virtual absl::optional<std::string> serializeAsString() const { return absl::nullopt; }
};

/**
* Generic factory for filter state objects. The factory registry uses the
* object data name as the index for the object factory. This factory should be used by the
* dynamic extensions that cannot use the object constructors directly.
*/
class ObjectFactory : public Config::UntypedFactory {
public:
// Config::UntypedFactory
std::string category() const override { return "filter_state.object"; }

/**
* @return std::unique_ptr<Object> from the serialized object data or nullptr if the input
* is malformed.
*/
virtual std::unique_ptr<Object> createFromBytes(absl::string_view data) const PURE;
};

struct FilterObject {
std::shared_ptr<Object> data_;
StateType state_type_{StateType::ReadOnly};
Expand Down
1 change: 1 addition & 0 deletions source/common/tcp_proxy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ envoy_cc_library(
"//envoy/event:dispatcher_interface",
"//envoy/network:connection_interface",
"//envoy/network:filter_interface",
"//envoy/registry",
"//envoy/router:router_interface",
"//envoy/server:filter_config_interface",
"//envoy/stats:stats_interface",
Expand Down
12 changes: 12 additions & 0 deletions source/common/tcp_proxy/tcp_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "envoy/event/timer.h"
#include "envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.pb.h"
#include "envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.pb.validate.h"
#include "envoy/registry/registry.h"
#include "envoy/stats/scope.h"
#include "envoy/upstream/cluster_manager.h"
#include "envoy/upstream/upstream.h"
Expand Down Expand Up @@ -41,6 +42,17 @@ const std::string& PerConnectionCluster::key() {
CONSTRUCT_ON_FIRST_USE(std::string, "envoy.tcp_proxy.cluster");
}

class PerConnectionClusterFactory : public StreamInfo::FilterState::ObjectFactory {
public:
std::string name() const override { return PerConnectionCluster::key(); }
std::unique_ptr<StreamInfo::FilterState::Object>
createFromBytes(absl::string_view data) const override {
return std::make_unique<PerConnectionCluster>(data);
}
};

REGISTER_FACTORY(PerConnectionClusterFactory, StreamInfo::FilterState::ObjectFactory);

Config::SimpleRouteImpl::SimpleRouteImpl(const Config& parent, absl::string_view cluster_name)
: parent_(parent), cluster_name_(cluster_name) {}

Expand Down
1 change: 1 addition & 0 deletions source/common/tcp_proxy/tcp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ class PerConnectionCluster : public StreamInfo::FilterState::Object {
public:
PerConnectionCluster(absl::string_view cluster) : cluster_(cluster) {}
const std::string& value() const { return cluster_; }
absl::optional<std::string> serializeAsString() const override { return cluster_; }
static const std::string& key();

private:
Expand Down
12 changes: 12 additions & 0 deletions test/common/tcp_proxy/tcp_proxy_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,18 @@ TEST_F(TcpProxyTest, UpstreamStartSecureTransport) {
filter_->startUpstreamSecureTransport();
}

TEST(PerConnectionCluster, ObjectFactory) {
const std::string name = "envoy.tcp_proxy.cluster";
auto* factory =
Registry::FactoryRegistry<StreamInfo::FilterState::ObjectFactory>::getFactory(name);
ASSERT_NE(nullptr, factory);
EXPECT_EQ(name, factory->name());
const std::string cluster = "per_connection_cluster";
auto object = factory->createFromBytes(cluster);
ASSERT_NE(nullptr, object);
EXPECT_EQ(cluster, object->serializeAsString());
}

} // namespace
} // namespace TcpProxy
} // namespace Envoy

0 comments on commit 9a1a3d5

Please sign in to comment.