Skip to content
Open
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
15 changes: 11 additions & 4 deletions source/extensions/filters/http/composite/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
#include "source/common/config/utility.h"
#include "source/extensions/filters/http/composite/filter.h"

#include "absl/base/no_destructor.h"

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace Composite {

static const absl::NoDestructor<NamedFilterChainFactoryMap> kEmptyNamedChains;
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 think the Envoy pattern is CONSTRUCT_ON_FIRST_USE, although I'm not sure what are the tradeoffs to a static const like this.


absl::StatusOr<NamedFilterChainFactoryMapSharedPtr>
CompositeFilterFactory::compileNamedFilterChains(
const envoy::extensions::filters::http::composite::v3::Composite& config,
Expand Down Expand Up @@ -68,8 +72,9 @@ absl::StatusOr<Http::FilterFactoryCb> CompositeFilterFactory::createFilterFactor
FilterStats{ALL_COMPOSITE_FILTER_STATS(POOL_COUNTER_PREFIX(context.scope(), prefix))});

return [stats, named_chains](Http::FilterChainFactoryCallbacks& callbacks) -> void {
auto filter = std::make_shared<Filter>(*stats, callbacks.dispatcher(), false /* is_upstream */,
named_chains);
auto filter =
std::make_shared<Filter>(*stats, callbacks.dispatcher(), false /* is_upstream */,
named_chains == nullptr ? *kEmptyNamedChains : *named_chains);
callbacks.addStreamFilter(filter);
callbacks.addAccessLogHandler(filter);
};
Expand All @@ -85,8 +90,10 @@ absl::StatusOr<Http::FilterFactoryCb> CompositeFilterFactory::createFilterFactor
auto stats = std::make_shared<FilterStats>(
FilterStats{ALL_COMPOSITE_FILTER_STATS(POOL_COUNTER_PREFIX(dual_info.scope, prefix))});

return [stats, dual_info](Http::FilterChainFactoryCallbacks& callbacks) -> void {
auto filter = std::make_shared<Filter>(*stats, callbacks.dispatcher(), dual_info.is_upstream);
return [stats, dual_info,
named_chains = *kEmptyNamedChains](Http::FilterChainFactoryCallbacks& callbacks) -> void {
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.

nit: is the named_chains copy needed here, or can the *kEmptyNamedChains be used directly inside the lambda function scope?

auto filter = std::make_shared<Filter>(*stats, callbacks.dispatcher(), dual_info.is_upstream,
named_chains);
callbacks.addStreamFilter(filter);
callbacks.addAccessLogHandler(filter);
};
Expand Down
6 changes: 3 additions & 3 deletions source/extensions/filters/http/composite/filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ void Filter::onMatchCallback(const Matcher::Action& action) {
const std::string& chain_name = composite_action.filterChainName();

// Soft fail: if no named filter chains are configured, do nothing.
if (!named_filter_chains_) {
if (named_filter_chains_.empty()) {
ENVOY_LOG(debug, "filter_chain_name '{}' specified but no named filter chains configured",
chain_name);
return;
}

// Look up the filter chain by name.
auto it = named_filter_chains_->find(chain_name);
if (it == named_filter_chains_->end()) {
auto it = named_filter_chains_.find(chain_name);
if (it == named_filter_chains_.end()) {
// Soft fail: if the named filter chain is not found, do nothing.
ENVOY_LOG(debug, "filter_chain_name '{}' not found in named filter chains", chain_name);
return;
Expand Down
12 changes: 6 additions & 6 deletions source/extensions/filters/http/composite/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ class Filter : public Http::StreamFilter,
Logger::Loggable<Logger::Id::filter> {
public:
Filter(FilterStats& stats, Event::Dispatcher& dispatcher, bool is_upstream,
NamedFilterChainFactoryMapSharedPtr named_filter_chains = nullptr)
: dispatcher_(dispatcher), stats_(stats), is_upstream_(is_upstream),
named_filter_chains_(std::move(named_filter_chains)) {}
const NamedFilterChainFactoryMap& named_filter_chains)
: dispatcher_(dispatcher), stats_(stats), named_filter_chains_(named_filter_chains),
is_upstream_(is_upstream) {}

// Http::StreamDecoderFilter
Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers,
Expand Down Expand Up @@ -197,10 +197,10 @@ class Filter : public Http::StreamFilter,
Http::StreamEncoderFilterCallbacks* encoder_callbacks_{};
Http::StreamDecoderFilterCallbacks* decoder_callbacks_{};
FilterStats& stats_;
// Filter in the upstream filter chain.
bool is_upstream_;
// Named filter chains compiled at config time.
NamedFilterChainFactoryMapSharedPtr named_filter_chains_;
const NamedFilterChainFactoryMap& named_filter_chains_;
// Filter is in the upstream filter chain.
bool is_upstream_;
};

} // namespace Composite
Expand Down
19 changes: 11 additions & 8 deletions test/extensions/filters/http/composite/filter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "test/test_common/logging.h"
#include "test/test_common/registry.h"

#include "absl/base/no_destructor.h"
#include "gtest/gtest.h"

namespace Envoy {
Expand All @@ -27,10 +28,12 @@ namespace {

using Envoy::Protobuf::util::MessageDifferencer;

static const absl::NoDestructor<NamedFilterChainFactoryMap> kEmptyMap;

class CompositeFilterTest : public ::testing::Test {
public:
CompositeFilterTest(bool is_upstream)
: filter_(stats_, decoder_callbacks_.dispatcher(), is_upstream) {
: filter_(stats_, decoder_callbacks_.dispatcher(), is_upstream, *kEmptyMap) {
filter_.setDecoderFilterCallbacks(decoder_callbacks_);
filter_.setEncoderFilterCallbacks(encoder_callbacks_);
}
Expand Down Expand Up @@ -1765,7 +1768,7 @@ TEST(FilterCallbacksWrapperTest, SingleModeRejectsMultipleFiltersAndExposesDispa
testing::NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
testing::NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks;

Filter filter(stats, dispatcher, false);
Filter filter(stats, dispatcher, false, *kEmptyMap);
filter.setDecoderFilterCallbacks(decoder_callbacks);
filter.setEncoderFilterCallbacks(encoder_callbacks);

Expand All @@ -1789,7 +1792,7 @@ TEST(FilterCallbacksWrapperTest, ChainModeAcceptsMultipleFilters) {
testing::NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
testing::NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks;

Filter filter(stats, dispatcher, false);
Filter filter(stats, dispatcher, false, *kEmptyMap);
filter.setDecoderFilterCallbacks(decoder_callbacks);
filter.setEncoderFilterCallbacks(encoder_callbacks);

Expand Down Expand Up @@ -1819,7 +1822,7 @@ TEST_F(FilterTest, NamedFilterChainLookupWithSamplingSkipped) {
}};

// Create filter with named chains.
Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, named_chains);
Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, *named_chains);
filter_with_chains.setDecoderFilterCallbacks(decoder_callbacks_);
filter_with_chains.setEncoderFilterCallbacks(encoder_callbacks_);

Expand Down Expand Up @@ -1855,7 +1858,7 @@ TEST_F(FilterTest, NamedFilterChainLookupNoNamedChainsConfigured) {
.WillByDefault(testing::ReturnRef(filter_state));

// Create filter without the named chains.
Filter filter_without_chains(stats_, decoder_callbacks_.dispatcher(), false, nullptr);
Filter filter_without_chains(stats_, decoder_callbacks_.dispatcher(), false, *kEmptyMap);
filter_without_chains.setDecoderFilterCallbacks(decoder_callbacks_);
filter_without_chains.setEncoderFilterCallbacks(encoder_callbacks_);

Expand Down Expand Up @@ -1889,7 +1892,7 @@ TEST_F(FilterTest, NamedFilterChainLookupChainNotFound) {
cb.addStreamFilter(std::make_shared<Http::MockStreamFilter>());
}};

Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, named_chains);
Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, *named_chains);
filter_with_chains.setDecoderFilterCallbacks(decoder_callbacks_);
filter_with_chains.setEncoderFilterCallbacks(encoder_callbacks_);

Expand Down Expand Up @@ -1925,7 +1928,7 @@ TEST_F(FilterTest, NamedFilterChainLookupSuccess) {
[&](Http::FilterChainFactoryCallbacks& cb) { cb.addStreamFilter(filter1); },
[&](Http::FilterChainFactoryCallbacks& cb) { cb.addStreamFilter(filter2); }};

Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, named_chains);
Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, *named_chains);
filter_with_chains.setDecoderFilterCallbacks(decoder_callbacks_);
filter_with_chains.setEncoderFilterCallbacks(encoder_callbacks_);

Expand Down Expand Up @@ -2006,7 +2009,7 @@ TEST_F(FilterTest, NamedFilterChainLookupWithAccessLoggers) {
},
};

Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, named_chains);
Filter filter_with_chains(stats_, decoder_callbacks_.dispatcher(), false, *named_chains);
filter_with_chains.setDecoderFilterCallbacks(decoder_callbacks_);
filter_with_chains.setEncoderFilterCallbacks(encoder_callbacks_);

Expand Down
Loading