Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite / Stereotype Filters #3589

Open
benmadore-glassdoor opened this issue Nov 11, 2024 · 6 comments
Open

Composite / Stereotype Filters #3589

benmadore-glassdoor opened this issue Nov 11, 2024 · 6 comments

Comments

@benmadore-glassdoor
Copy link

benmadore-glassdoor commented Nov 11, 2024

Let's say I have a different types of routes in my application, routes of Type A and Type B.

And my application has filters: Filter1, Filter2 ... Filter10

For Type A routes I want to always apply Filters 1,2,3,4,5 and for Type B routes I always want to apply Filters 6,7,8.

Filter9 and Filter10 may by applied to either type of route.

Rather than having to copy/paste and specify each of the individual filters on every single route in my application, I'd love some mechanism to create Composite sets of filters that should be applied.

So for a route of Type A instead of:

- filters:
  - Filter1
  - Filter2
  - Filter3
  - Filter4
  - Filter5
  - Filter10
  ...

I could write something like:

-filters:
  - TypeA
  - Filter10
  ...

I attempted to do this via creating an TypeAGatewayFilterFactory that simply invokes 1,2,3,4,5 in turn, but this is not ideal as it doesn't respect the global ordering of the OrderedFilters the filters will always be applied immediately after the ordering of the TypeA OrderedFilter in the specific sequence they're applied.

I also attempted to use a yaml anchor reference e.g.

type-a-filters: &type-a-filters
  - Filter1
  - Filter2
  - Filter3
 ...
- filters
  - Filter10
  - *common-filters

But i got a errors like:

Binding to target [Bindable@1e8add86 type = java.util.List<org.springframework.cloud.gateway.filter.FilterDefinition>, value = 'provided', annotations = array<Annotation>[@jakarta.validation.Valid()], bindMethod = [null]] failed:

  Property: spring.cloud.gateway.routes[0].filters[1][0]
  Value: "Filter1"
  Origin: "spring.cloud.gateway.routes[0].filters[1][0]" from property source "bootstrapProperties-devConfigTest/gateway-app/"
  Reason: The elements [spring.cloud.gateway.routes[0].filters[1][0],spring.cloud.gateway.routes[0].filters[1][1],spring.cloud.gateway.routes[0].filters[1][2]] were left unbound.
  Property: spring.cloud.gateway.routes[0].filters[1][1]
  Value: "Filter2"
  Origin: "spring.cloud.gateway.routes[0].filters[1][1]" from property source "bootstrapProperties-devConfigTest/gateway-app/"
  Reason: The elements [spring.cloud.gateway.routes[0].filters[1][0],spring.cloud.gateway.routes[0].filters[1][1],spring.cloud.gateway.routes[0].filters[1][2]] were left unbound.
  Property: spring.cloud.gateway.routes[0].filters[1][2]
  Value: "Filter3"
  Origin: "spring.cloud.gateway.routes[0].filters[1][2]" from property source "bootstrapProperties-devConfigTest/gateway-app/"
  Reason: The elements [spring.cloud.gateway.routes[0].filters[1][0],spring.cloud.gateway.routes[0].filters[1][1],spring.cloud.gateway.routes[0].filters[1][2]] were left unbound.

Is there any alternate mechanism I should be considering to enable these types of Composite Filters?

@spencergibb
Copy link
Member

I don't know if boot supports yaml anchor references. @philwebb do you know?

@philwebb
Copy link

I'm pretty sure we don't have any tests for yaml anchor references, so they're certainly not officially supported. We rely on SnakeYAML to do the actual parsing, and I don't know how that deals with them. I've opened spring-projects/spring-boot#43125 to investigate.

@benmadore-glassdoor
Copy link
Author

benmadore-glassdoor commented Nov 12, 2024

@philwebb @spencergibb So it turns out that anchors do "just work", i just had some syntactical issues.

But they unfortunately specifically don't support my desired use case (merging elements of a sequence) yaml/yaml#35

So it appears I'm back to square 0. Any suggestions on a mechanism to perhaps programmatically trigger adding a set of Filters to given yaml-defined route (at startup) such that the actual filter execution order follows the order defined by the OrderedGatewayFilter?

@philwebb
Copy link

You could let Spring Boot do the list conversion then try something like this:

type-a-filters: "Filter1, Filter2, Filter3"
filters: "${type-a-filter}, Filter10"

When filters is resolved it should create a String containing "Filter1, Filter2, Filter3, Filter10" which we would convert to a List by splitting on the comma.

@spencergibb
Copy link
Member

Unless the filters have no arguments that's not going to work either.

@benmadore-glassdoor
Copy link
Author

@spencergibb That's a good point - a single shortcut configuration param works e.g. this seems fine:

type-a-filters: "Filter1, Filter2, Filter3=foo"
filters: "${type-a-filter}, Filter10=bar"

but if i actually have to specify out a nested configuration structure, or provide multiple comma delimited shortcut params... that doesn't work.

:(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants