Skip to content

Commit

Permalink
attribute: add upstream filter state
Browse files Browse the repository at this point in the history
Change-Id: I48b928db0e7b9b2d77dcafab0cbd897a7056b6ff
Signed-off-by: Kuat Yessenov <[email protected]>
  • Loading branch information
kyessenov committed May 21, 2024
1 parent a112766 commit 54cb5e5
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 2 deletions.
12 changes: 11 additions & 1 deletion docs/root/intro/arch_overview/advanced/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,17 @@ Data exchanged between filters is available as the following attributes:
:widths: 1, 1, 4

metadata, :ref:`Metadata<envoy_v3_api_msg_config.core.v3.metadata>`, Dynamic request metadata
filter_state, "map<string, bytes>", Mapping from a filter state name to its serialized string value
filter_state, "map<string, Value>", Mapping from the filter state name to the object value
upstream_filter_state, "map<string, Value>", Mapping from the upstream filter state name to the object value

Filter state value representation is determined based on the filter state
declaration in the following order:

* If the value is represented as a dynamic ``CelValue`` wrapper, ``CelValue``
is returned verbatim.
* If the key is well-known and has a field reflection enabled, then it is
returned as a map from the field names to the field values.
* Otherwise, the value is returned as the serialized bytes.

Note that these attributes may change during the life of a request as the data can be
updated by filters at any point.
Expand Down
1 change: 1 addition & 0 deletions source/extensions/filters/common/expr/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ constexpr absl::string_view Metadata = "metadata";

// Per-request or per-connection filter state
constexpr absl::string_view FilterState = "filter_state";
constexpr absl::string_view UpstreamFilterState = "upstream_filter_state";

// Connection properties
constexpr absl::string_view Connection = "connection";
Expand Down
8 changes: 7 additions & 1 deletion source/extensions/filters/common/expr/evaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace {

#define ACTIVATION_TOKENS(_f) \
_f(Request) _f(Response) _f(Connection) _f(Upstream) _f(Source) _f(Destination) _f(Metadata) \
_f(FilterState) _f(XDS)
_f(FilterState) _f(XDS) _f(UpstreamFilterState)

#define _DECLARE(_t) _t,
enum class ActivationToken { ACTIVATION_TOKENS(_DECLARE) };
Expand Down Expand Up @@ -69,6 +69,12 @@ absl::optional<CelValue> StreamActivation::FindValue(absl::string_view name,
Protobuf::Arena::Create<FilterStateWrapper>(arena, *arena, info.filterState()));
case ActivationToken::XDS:
return {};
case ActivationToken::UpstreamFilterState:
if (info.upstreamInfo().has_value() &&
info.upstreamInfo().value().get().upstreamFilterState() != nullptr) {
return CelValue::CreateMap(Protobuf::Arena::Create<FilterStateWrapper>(
arena, *arena, *info.upstreamInfo().value().get().upstreamFilterState()));
}
}
return {};
}
Expand Down
1 change: 1 addition & 0 deletions test/extensions/filters/common/expr/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ envoy_extension_cc_test(
tags = ["skip_on_windows"],
deps = [
"//source/extensions/filters/common/expr:evaluator_lib",
"//test/mocks/stream_info:stream_info_mocks",
"//test/test_common:utility_lib",
"@com_google_cel_cpp//eval/public/structs:cel_proto_wrapper",
],
Expand Down
12 changes: 12 additions & 0 deletions test/extensions/filters/common/expr/evaluator_test.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "source/extensions/filters/common/expr/evaluator.h"

#include "test/mocks/stream_info/mocks.h"
#include "test/test_common/utility.h"

#include "absl/time/time.h"
Expand Down Expand Up @@ -42,6 +43,17 @@ TEST(Evaluator, Print) {
EXPECT_EQ(print(CelValue::CreateError(&status)), "CelError value");
}

TEST(Evaluator, Activation) {
NiceMock<StreamInfo::MockStreamInfo> info;
auto filter_state =
std::make_shared<StreamInfo::FilterStateImpl>(StreamInfo::FilterState::LifeSpan::FilterChain);
info.upstreamInfo()->setUpstreamFilterState(filter_state);
ProtobufWkt::Arena arena;
const auto activation = createActivation(nullptr, info, nullptr, nullptr, nullptr);
EXPECT_TRUE(activation->FindValue("filter_state", &arena).has_value());
EXPECT_TRUE(activation->FindValue("upstream_filter_state", &arena).has_value());
}

} // namespace
} // namespace Expr
} // namespace Common
Expand Down
9 changes: 9 additions & 0 deletions test/integration/filters/empty.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
syntax = "proto3";

package test.integration.filters;

message Backpressure {
}

message Tee {
}

0 comments on commit 54cb5e5

Please sign in to comment.