Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Removed Config or Runtime
New Features
------------
* http3: downstream HTTP/3 support is now GA! Upstream HTTP/3 also GA for specific deployments. See :ref:`here <arch_overview_http3>` for details.
* matching: the matching API can now express a match tree that will always match by omitting a matcher at the top level.


Deprecated
Expand Down
28 changes: 26 additions & 2 deletions source/common/matcher/matcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ static inline MaybeMatchResult evaluateMatch(MatchTree<DataType>& match_tree,

template <class DataType> using FieldMatcherFactoryCb = std::function<FieldMatcherPtr<DataType>()>;

/**
* A matcher that will always resolve to associated on_no_match. This is used when
* the matcher is configured without a matcher, allowing for a tree that always resolves
* to a specific OnMatch.
*/
template <class DataType> class AnyMatcher : public MatchTree<DataType> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comments.

public:
explicit AnyMatcher(absl::optional<OnMatch<DataType>> on_no_match)
: on_no_match_(std::move(on_no_match)) {}

typename MatchTree<DataType>::MatchResult match(const DataType&) override {
return {MatchState::MatchComplete, on_no_match_};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert here, but should the 2nd param (on_no_match_ object) be returned by ref?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in other use cases this always does a copy, since the Action object is generally small (lambda + pointer). We could probably change this around but would be a bigger refactor I think

}
const absl::optional<OnMatch<DataType>> on_no_match_;
};

/**
* Recursively constructs a MatchTree from a protobuf configuration.
* @param DataType the type used as a source for DataInputs
Expand All @@ -83,8 +99,7 @@ class MatchTreeFactory : public OnMatchFactory<DataType> {
case MatcherType::kMatcherList:
return createListMatcher(config);
case MatcherType::MATCHER_TYPE_NOT_SET:
IS_ENVOY_BUG("match fail");
return nullptr;
return createAnyMatcher(config);
}
return nullptr;
}
Expand All @@ -100,6 +115,15 @@ class MatchTreeFactory : public OnMatchFactory<DataType> {
}

private:
template <class MatcherType>
MatchTreeFactoryCb<DataType> createAnyMatcher(const MatcherType& config) {
auto on_no_match = createOnMatch(config.on_no_match());

return [on_no_match]() {
return std::make_unique<AnyMatcher<DataType>>(
on_no_match ? absl::make_optional((*on_no_match)()) : absl::nullopt);
};
}
template <class MatcherType>
MatchTreeFactoryCb<DataType> createListMatcher(const MatcherType& config) {
std::vector<std::pair<FieldMatcherFactoryCb<DataType>, OnMatchFactoryCb<DataType>>>
Expand Down
24 changes: 24 additions & 0 deletions test/common/matcher/matcher_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "test/test_common/utility.h"

#include "gtest/gtest.h"
#include "xds/type/matcher/v3/matcher.pb.validate.h"

namespace Envoy {
namespace Matcher {
Expand Down Expand Up @@ -83,6 +84,29 @@ TEST_F(MatcherTest, TestMatcher) {
EXPECT_NE(result.on_match_->action_cb_, nullptr);
}

TEST_F(MatcherTest, TestAnyMatcher) {
const std::string yaml = R"EOF(
on_no_match:
action:
name: test_action
typed_config:
"@type": type.googleapis.com/google.protobuf.StringValue
value: match!!
)EOF";

xds::type::matcher::v3::Matcher matcher;
MessageUtil::loadFromYaml(yaml, matcher, ProtobufMessage::getStrictValidationVisitor());

TestUtility::validate(matcher);

auto match_tree = factory_.create(matcher);

const auto result = match_tree()->match(TestData());
EXPECT_EQ(result.match_state_, MatchState::MatchComplete);
EXPECT_TRUE(result.on_match_.has_value());
EXPECT_NE(result.on_match_->action_cb_, nullptr);
}

TEST_F(MatcherTest, CustomGenericInput) {
const std::string yaml = R"EOF(
matcher_list:
Expand Down