From ae56db97bbdbf978c35b1fd2fc5692ded90e08da Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 15:52:02 -0700 Subject: [PATCH 01/21] Add a proposal for advanced filtering --- docs/broker/filtering.md | 336 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 docs/broker/filtering.md diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md new file mode 100644 index 00000000000..72d658f4ad8 --- /dev/null +++ b/docs/broker/filtering.md @@ -0,0 +1,336 @@ +# Advanced Filtering for Triggers Proposal + +## Problem + +As an `Event Consumer` I want to filter events in triggers with a variety of +strategies beyond exact match on predefined fields. Filtering strategies that +have been requested include: + +* Filtering by source or type prefix or regular expression +* Filtering by a custom extension field +* Filtering by data fields + +The existing filter capability of exact match on source and type is simple to +understand and use, but doesn't support these more advanced filtering scenarios. + +## Objective + +Design a flexible filtering mechanism that supports all of the advanced use +cases identified and can also implement simpler cases like exact match. + +The filtering mechanism MUST be safe and efficient. It SHOULD be compatible with +a future +[upstream propagation solution](https://github.com/knative/eventing/issues/934) +for delivery efficiency at scale. + +Filters should be easy for the user to specify and simple to interpret at a +glance. + +## Requirements + +* Support all of the advanced filtering use cases identified. +* Can implement simpler cases like exact match. +* Safe and secure when embedded in multi-tenant processes. +* Compatible with upstream filter propagation. +* Easily specified by the user. +* Simple for users to interpret. + +## Proposed Solution + +Add a field to the Trigger Filter spec allowing users to specify an expression +as a string. The expression is evaluated for each event considered by the +Trigger. If the expression evaluates to true, the event is delivered to the +Trigger's subscriber. + +The evaluation environment of the expression may include: + +* Standard CloudEvent fields like type and source +* Custom extensions dynamically parsed from the event +* Data fields parsed from the event, if the data content type is known to be + parseable + +Since parsing dynamic extension and data fields may be costly, the Trigger must +explicitly enable it by setting boolean fields adjacent to the expression. See +[examples](#examples) for syntax. + +The expression language chosen is +[CEL](https://github.com/google/cel-spec/blob/9cdb3682ba04109d2e03d9b048986bae113bf36f/doc/intro.md) +as it has the best combination of features for this purpose. See +[alternatives considered](#alternatives-considered) for comparisons to other +expression languages. + +```yaml +spec: + filter: + cel: + expression: > + ce.type == "com.github.pull.create" && + source == "https://github.com/knative/eventing/pulls/123" +``` + +### Why CEL? + +CEL is the +[Common Expression Language](https://github.com/google/cel-spec/blob/9cdb3682ba04109d2e03d9b048986bae113bf36f/doc/langdef.md). +It is designed for expressing security policy and protocols, and has the +following +[guiding philosophy](https://github.com/google/cel-spec/blob/9cdb3682ba04109d2e03d9b048986bae113bf36f/README.md): + +* **Small and fast.** CEL is not Turing complete, so it is easy to understand + and implement. +* **Extensible.** CEL is designed to be embedded and can be extended with new + functionality. +* **Developer-friendly.** The language spec was based on experience and + usability testing from implementing Firebase Rules. + +Additional properties of CEL that make it attractive for Trigger Filtering +include: + +* **Familiar expression syntax.** Filter expressions written in CEL look and + behave like conditional expressions written in the most popular languages. +* **Expressions can be compiled and cached for efficiency.** We expect users + will create many filters that change rarely in comparison to frequency of + evaluations. This usage pattern works in favor of an expression language + that can be cached in compiled form. +* **Expressions are serializable and composable.** These properties are useful + in implementing upstream filter propagation. For example, a Broker could + advertise a single CEL expression composed of the union of its Triggers' + filters, allowing upstream sources to filter events before publishing to the + Broker. + +CEL is +[memory-safe, side-effect-free, and terminating](https://github.com/google/cel-spec/blob/master/doc/langdef.md#overview), +making it safe and secure to embed in a multi-tenant dispatcher process. + +## Examples + +### Single field exact match + +Specified with the SourceAndType field: `yaml spec: filter: sourceAndType: type: +com.github.pull.create` + +Specified with a CEL expression: + +```yaml +spec: + filter: + cel: + expression: ce.type == "com.github.pull.create" +``` + +### Multiple fields exact match + +Specified with the SourceAndType field: + +```yaml +spec: + filter: + sourceAndType: + type: com.github.pull.create + source: https://github.com/knative/eventing/pulls/123 +``` + +Specified with a CEL expression: + +_The `>` syntax is a standard yaml multiline string._ + +```yaml +spec: + filter: + cel: + expression: > + ce.type == "com.github.pull.create" && + source == "https://github.com/knative/eventing/pulls/123" +``` + +### Prefix match on source + +Cannot be specified with the SourceAndType field. + +CEL doesn't support prefix match directly, but prefix match can be accomplished +with a regular expression: + +```yaml +spec: + filter: + cel: + expression: ce.source.matches("^https://github.com") +``` + +### Complex boolean expression + +Cannot be specified with the SourceAndType field. + +_The `>` syntax is a standard yaml multiline string._ + +```yaml +spec: + filter: + cel: + expression: > + ce.type == "com.github.pull.create" || + (ce.type == "com.github.issue.create" && + ce.source.matches("proposals") + +``` + +### Parsed extensions + +Cannot be specified with the SourceAndType field. + +_This example assumes the repository name is available as a CloudEvent extension +with name `repository`._ + +_The `>` syntax is a standard yaml multiline string._ + +```yaml +spec: + filter: + cel: + parseExtensions: true + expression: > + ce.type == "com.github.pull.create" || + (ce.type == "com.github.issue.create" && + ext.repository == "proposals") + +``` + +### Parsed data + +Cannot be specified with the SourceAndType field. + +_The `>` syntax is a standard yaml multiline string._ + +_Until [google/cel-go#203](https://github.com/google/cel-go/issues/203) is +resolved, dynamic integer fields in CEL must be compared as floats._ + +```yaml +spec: + filter: + cel: + parseData: true + expression: > + ce.type == "dev.knative.observation" && + data.latency > 300.0 +``` + +## Caveats + +The main caveat is the choice of CEL as expression language. + +CEL is new and the language is not officially supported by Google. Participation +by non-Google contributors is low. OPA is planning to replace their policy +language Rego with CEL, but +[no timeline has been announced for this migration](https://github.com/open-policy-agent/opa/issues/811#issuecomment-401844999). +The KrakenD API Gateway has announced support for CEL +[here](https://medium.com/devops-faith/krakend-api-gateway-0-9-released-9427c249dbcd). + +The CEL language is new and has limited exposure, despite being informed by +experience and research at Google. We may discover issues that make it less +suitable for Trigger filtering (e.g. +[google/cel-go#203](https://github.com/google/cel-go/issues/203). + +If CEL turns out to be a liability, a new expression language could be added +alongside CEL without breaking existing triggers, allowing for an orderly +deprecation. + +For example, a javascript filter could be added without disrupting existing CEL +filters: + +```yaml +spec: + filter: + javascript: + expression: ce.type == "com.github.pull.create" +``` + +## Alternatives Considered + +The following alternative solutions were considered but rejected. + +### Javascript or Lua as expression language + +Trigger filtering is a very limited case for an embedded language. All that is +needed from a language is the ability to write conditions that evaluate to true +or false. + +Javascript and Lua are commonly used as embedded languages, but their +capabilities extend well beyond the needs of Trigger filtering. Those +capabilities come with complexity: Javascript and Lua programs may not provably +terminate, may have memory leaks, and may consume excessive amounts of CPU. All +these cases would need to be guarded against by any process involved in +filtering. If the expression language is used for upstream filter propagation, +this could be a large number of diverse processes. + +Due to this additional implementation complexity, both Javascript and Lua have +been judged less suitable for Trigger filtering than CEL. + +### Rego (OPA) + +[Rego](https://www.openpolicyagent.org/docs/v0.10.7/language-reference/) is +already as a policy expression language by +[Open Policy Agent](https://www.openpolicyagent.org/). It could be an attractive +choice, but +[OPA has indicated a desire to replace Rego with CEL](https://github.com/open-policy-agent/opa/issues/811#issuecomment-401844999). +Since Rego doesn't seem to be used outside OPA, choosing Rego for Trigger +filters would likely make Triggers the only remaining use of Rego. + +The possible maintenance burden of being the only Rego user makes Rego less +suitable for Trigger filtering than CEL. + +### Custom expression language + +We could develop our own custom expression language for Trigger filters. This +might be attractive since we could design the language for the needs of Trigger +filters specifically. + +A possible example is Kubernetes' set-based label selectors: + +``` +environment in (production, qa) +tier notin (frontend, backend) +partition +!partition +``` + +The disadvantage of this approach is that the Knative Eventing contributors +would be responsible for implementing, documenting, and maintaining the +language. CEL already meets the current needs of Trigger filters and is +extensible to support future needs. + +The implementation and maintenance work required to develop a custom expression +language make this solution less suitable for Trigger filtering than CEL. + +### Structured filters + +Instead of using an expression language, we could design a system of structured +filters expressible as yaml or JSON, similar to Kubernetes set-based label +selectors: + +```yaml +matchExpressions: + - {key: tier, operator: In, values: [cache]} + - {key: environment, operator: NotIn, values: [dev]} +``` + +One advantage of structured filters is that their schema can be expressed in an +OpenAPI document and syntax-checked at creation time without embedding a +language runtime. + +Structured filters are not as flexible as an expression language. For example, +the above Kubernetes label selectors cannot compose expressions with Boolean OR. +This lack of flexibility makes structured filters difficult to use for upstream +filter propagation. + +Structured filters would need a custom implementation maintained by Knative +contributors that grows in complexity as new capabilities are added. An +off-the-shelf expression language can be embedded and immediately support +significant complexity without additional effort. + +The inflexibility and implementation complexity of structured filters make this +solution less suitable for Trigger filtering than CEL. However, structured +filters can be a useful and important user interface on top of an expression +language: for example, the existing SourceAndType syntax for expressing a filter +could be implemented by generating an equivalent CEL expression. This provides +users a structured filter interface when their needs are simple, and allows them +to transition to a more complex interface when their needs require it. From 1a8ae226e4e705a45dede6f48b54eb43d2123358 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:04:34 -0700 Subject: [PATCH 02/21] fix typo in example --- docs/broker/filtering.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 72d658f4ad8..7edd578485c 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -140,7 +140,7 @@ spec: cel: expression: > ce.type == "com.github.pull.create" && - source == "https://github.com/knative/eventing/pulls/123" + ce.source == "https://github.com/knative/eventing/pulls/123" ``` ### Prefix match on source From a35d4a505c813ee09b9c803dad8f32f3e005b6bd Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:04:53 -0700 Subject: [PATCH 03/21] Add caveat about variable prefixes --- docs/broker/filtering.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 7edd578485c..2d92132f3bf 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -216,6 +216,24 @@ spec: ## Caveats +### Variable prefixes + +Due to limitations in the CloudEvents SDK, dynamic fields like extensions and +data must have a separate prefix from non-dynamic types. The examples here use +these prefixes: + +|--------|-------------------------------------------------| +| `ce` | Official CloudEvents fields defined in the spec.| +| `ext` | Extensions parsed dynamically from the event. | +| `data` | Fields parsed dynamically from the event data. | +|--------|-------------------------------------------------| + +This limitation may be lifted in the future, allowing official CloudEvents +fields to use the same prefix as extensions. Extensions can then be elevated to +official fields without changing filter expressions. + +### CEL + The main caveat is the choice of CEL as expression language. CEL is new and the language is not officially supported by Google. Participation From 2fe4d27725cd41398751a5bbfcdc6c2bc61e224d Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:13:50 -0700 Subject: [PATCH 04/21] pluralize CloudEvents --- docs/broker/filtering.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 2d92132f3bf..6f1b8418cb5 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -44,7 +44,7 @@ Trigger's subscriber. The evaluation environment of the expression may include: -* Standard CloudEvent fields like type and source +* Standard CloudEvents fields like type and source * Custom extensions dynamically parsed from the event * Data fields parsed from the event, if the data content type is known to be parseable @@ -178,7 +178,7 @@ spec: Cannot be specified with the SourceAndType field. -_This example assumes the repository name is available as a CloudEvent extension +_This example assumes the repository name is available as a CloudEvents extension with name `repository`._ _The `>` syntax is a standard yaml multiline string._ From ef691e7b5911a41e315eae31b765705c7e929d00 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:18:18 -0700 Subject: [PATCH 05/21] fix formatting formatted by formatter --- docs/broker/filtering.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 6f1b8418cb5..4f89808fb70 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -106,8 +106,14 @@ making it safe and secure to embed in a multi-tenant dispatcher process. ### Single field exact match -Specified with the SourceAndType field: `yaml spec: filter: sourceAndType: type: -com.github.pull.create` +Specified with the SourceAndType field: + +```yaml +spec: + filter: + sourceAndType: + type: com.github.pull.create +``` Specified with a CEL expression: From d12eb858a8b06a72db6eac947f272d766b5eeaac Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:18:59 -0700 Subject: [PATCH 06/21] Improve readability of complex expression example --- docs/broker/filtering.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 4f89808fb70..7bc8297e04d 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -175,8 +175,7 @@ spec: cel: expression: > ce.type == "com.github.pull.create" || - (ce.type == "com.github.issue.create" && - ce.source.matches("proposals") + (ce.type == "com.github.issue.create" && ce.source.matches("proposals") ``` From 88c3f86cc7c8fbfe5ae2bb058c930aa67c88cad4 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 11 Apr 2019 16:38:22 -0700 Subject: [PATCH 07/21] CloudEvents fields are called attributes --- docs/broker/filtering.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 7bc8297e04d..40a53954ce2 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -3,11 +3,11 @@ ## Problem As an `Event Consumer` I want to filter events in triggers with a variety of -strategies beyond exact match on predefined fields. Filtering strategies that -have been requested include: +strategies beyond exact match on predefined attributes. Filtering strategies +that have been requested include: * Filtering by source or type prefix or regular expression -* Filtering by a custom extension field +* Filtering by a custom extension attribute * Filtering by data fields The existing filter capability of exact match on source and type is simple to @@ -44,14 +44,14 @@ Trigger's subscriber. The evaluation environment of the expression may include: -* Standard CloudEvents fields like type and source +* Standard CloudEvents attributes like type and source * Custom extensions dynamically parsed from the event * Data fields parsed from the event, if the data content type is known to be parseable -Since parsing dynamic extension and data fields may be costly, the Trigger must -explicitly enable it by setting boolean fields adjacent to the expression. See -[examples](#examples) for syntax. +Since parsing dynamic extension attributes and data fields may be costly, the +Trigger must explicitly enable it by setting boolean fields adjacent to the +expression. See [examples](#examples) for syntax. The expression language chosen is [CEL](https://github.com/google/cel-spec/blob/9cdb3682ba04109d2e03d9b048986bae113bf36f/doc/intro.md) @@ -104,7 +104,7 @@ making it safe and secure to embed in a multi-tenant dispatcher process. ## Examples -### Single field exact match +### Single attribute exact match Specified with the SourceAndType field: @@ -124,7 +124,7 @@ spec: expression: ce.type == "com.github.pull.create" ``` -### Multiple fields exact match +### Multiple attributes exact match Specified with the SourceAndType field: @@ -223,19 +223,19 @@ spec: ### Variable prefixes -Due to limitations in the CloudEvents SDK, dynamic fields like extensions and -data must have a separate prefix from non-dynamic types. The examples here use +Due to limitations in the CloudEvents SDK, dynamic attributes and data fields +must have a separate prefix from non-dynamic types. The examples here use these prefixes: -|--------|-------------------------------------------------| -| `ce` | Official CloudEvents fields defined in the spec.| -| `ext` | Extensions parsed dynamically from the event. | -| `data` | Fields parsed dynamically from the event data. | -|--------|-------------------------------------------------| +|--------|-----------------------------------------------------| +| `ce` | Official CloudEvents attributes defined in the spec.| +| `ext` | Extensions parsed dynamically from the event. | +| `data` | Fields parsed dynamically from the event data. | +|--------|-----------------------------------------------------| This limitation may be lifted in the future, allowing official CloudEvents -fields to use the same prefix as extensions. Extensions can then be elevated to -official fields without changing filter expressions. +attributes to use the same prefix as extensions. Extensions can then be elevated +to official attributes without changing filter expressions. ### CEL From f40f81149a262b0166f36add64db401c2eaebca9 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Fri, 12 Apr 2019 16:36:01 -0700 Subject: [PATCH 08/21] Fix table formatting (From Ahmed) --- docs/broker/filtering.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 40a53954ce2..2f0bfd62227 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -227,11 +227,11 @@ Due to limitations in the CloudEvents SDK, dynamic attributes and data fields must have a separate prefix from non-dynamic types. The examples here use these prefixes: +| Attribute|Description | |--------|-----------------------------------------------------| | `ce` | Official CloudEvents attributes defined in the spec.| | `ext` | Extensions parsed dynamically from the event. | | `data` | Fields parsed dynamically from the event data. | -|--------|-----------------------------------------------------| This limitation may be lifted in the future, allowing official CloudEvents attributes to use the same prefix as extensions. Extensions can then be elevated From 2b42cdb5e64fc62fe048c21f392f2f3a75c6cf53 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Tue, 16 Apr 2019 16:28:24 -0700 Subject: [PATCH 09/21] Move extensions to the `ce` prefix This makes extension attributes easier to use and promote to official attributes. The `ext` prefix has been removed. --- docs/broker/filtering.md | 53 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 2f0bfd62227..2d7c203c6b6 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -44,15 +44,11 @@ Trigger's subscriber. The evaluation environment of the expression may include: -* Standard CloudEvents attributes like type and source -* Custom extensions dynamically parsed from the event +* Official CloudEvents attributes like type and source. +* Custom extension attributes dynamically parsed from the event. * Data fields parsed from the event, if the data content type is known to be parseable -Since parsing dynamic extension attributes and data fields may be costly, the -Trigger must explicitly enable it by setting boolean fields adjacent to the -expression. See [examples](#examples) for syntax. - The expression language chosen is [CEL](https://github.com/google/cel-spec/blob/9cdb3682ba04109d2e03d9b048986bae113bf36f/doc/intro.md) as it has the best combination of features for this purpose. See @@ -65,9 +61,30 @@ spec: cel: expression: > ce.type == "com.github.pull.create" && - source == "https://github.com/knative/eventing/pulls/123" + ce.source == "https://github.com/knative/eventing/pulls/123" ``` +### Variable prefixes + +| Prefix |Description | +|--------|------------| +| `ce` | Official CloudEvents attributes defined in the spec, plus extension attributes if requested. | +| `data` | Fields parsed from the event data, if requested. | + +Official attributes and extension attributes are both available to the +expression under the prefix `ce`. This co-mingling is intended to ease the +promotion of extension attributes to official attributes. The prefix `ce` was +chosen for succintness and its suggestion that CloudEvents is the operative +specification. + +Data fields are available to the expression under the prefix `data`. + +Parsing dynamic extension attributes and data fields may be costly. In this +initial proposal, the Trigger must explicitly enable dynamic parsing by setting +boolean fields `parseExtensions` and/or `parseData`. Future work may +eliminate the need for these fields by detecting the use of extension attributes +and/or data fields in the expression. + ### Why CEL? CEL is the @@ -183,8 +200,8 @@ spec: Cannot be specified with the SourceAndType field. -_This example assumes the repository name is available as a CloudEvents extension -with name `repository`._ +_This example assumes the repository name is available as a CloudEvents +extension with name `repository`._ _The `>` syntax is a standard yaml multiline string._ @@ -196,7 +213,7 @@ spec: expression: > ce.type == "com.github.pull.create" || (ce.type == "com.github.issue.create" && - ext.repository == "proposals") + ce.repository == "proposals") ``` @@ -221,22 +238,6 @@ spec: ## Caveats -### Variable prefixes - -Due to limitations in the CloudEvents SDK, dynamic attributes and data fields -must have a separate prefix from non-dynamic types. The examples here use -these prefixes: - -| Attribute|Description | -|--------|-----------------------------------------------------| -| `ce` | Official CloudEvents attributes defined in the spec.| -| `ext` | Extensions parsed dynamically from the event. | -| `data` | Fields parsed dynamically from the event data. | - -This limitation may be lifted in the future, allowing official CloudEvents -attributes to use the same prefix as extensions. Extensions can then be elevated -to official attributes without changing filter expressions. - ### CEL The main caveat is the choice of CEL as expression language. From 2b4d7db9d62eedf2e2b2ba30d3571e6e0268af67 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 22 Apr 2019 13:54:44 -0700 Subject: [PATCH 10/21] Expand prefix match example Mention startsWith, match, and matches functions. --- docs/broker/filtering.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 2d7c203c6b6..35a7540e4ba 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -170,14 +170,33 @@ spec: Cannot be specified with the SourceAndType field. -CEL doesn't support prefix match directly, but prefix match can be accomplished -with a regular expression: +CEL supports multiple options for prefix match. The simplest is `startsWith`: ```yaml spec: filter: cel: - expression: ce.source.matches("^https://github.com") + expression: ce.source.startsWith("https://github.com") +``` + +CEL also implements shell-style wildcards with `match`: + +```yaml +spec: + filter: + cel: + expression: ce.source.match("https://github.com*") +``` + +For the most complex matching needs, CEL implements +[RE2-style](https://github.com/google/re2/wiki/Syntax) regular expressions with +`matches`: + +```yaml +spec: + filter: + cel: + expression: ce.source.matches("https://github.com.*") ``` ### Complex boolean expression @@ -196,7 +215,7 @@ spec: ``` -### Parsed extensions +### Exact match on Extension Cannot be specified with the SourceAndType field. @@ -217,7 +236,7 @@ spec: ``` -### Parsed data +### Exact match on Data Cannot be specified with the SourceAndType field. From cb182c571f534910f002dff583867938f18043be Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 22 Apr 2019 14:55:30 -0700 Subject: [PATCH 11/21] Check expression syntax in the Trigger webhook --- docs/broker/filtering.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 35a7540e4ba..b8642d76c54 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -64,6 +64,11 @@ spec: ce.source == "https://github.com/knative/eventing/pulls/123" ``` +Add a check to the Trigger webhook that validates the expression's syntax and +rejects the request if an error is encountered. This will not catch errors +arising from dynamic extension attributes or data fields - these can only be +caught at evaluation time. + ### Variable prefixes | Prefix |Description | From e57a18ff7720e1b0a84db89eafea571a4478f1a6 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 22 Apr 2019 15:38:09 -0700 Subject: [PATCH 12/21] Add versioning caveat --- docs/broker/filtering.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index b8642d76c54..5ccf76d22aa 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -262,7 +262,7 @@ spec: ## Caveats -### CEL +### Choice of CEL The main caveat is the choice of CEL as expression language. @@ -292,6 +292,25 @@ spec: expression: ce.type == "com.github.pull.create" ``` +### Versioning + +Embedding an expression language into the Trigger specification means that we +effectively have two versions exposed to the user: the Trigger CRD APIVersion and +the expression language version. As the CEL spec evolves, backward incompatible +changes may be made that would require a version change in the Trigger. + +I propose that we rely on the Trigger CRD APIVersion to encode both the Trigger +version and the CEL version. This ensures that Triggers with the same APIVersion +always have the same behavior, and the upgrade semantics are the same as those +for other Kubernetes objects. + +There is a concern that tying the CEL version to the Trigger APIVersion could +block users from upgrading, because they need to upgrade all of their +expressions at the same time as a Knative upgrade. If no automatic upgrade is +possible, we should support both CEL versions for one or more Knative releases. +It might be necessary to add a Trigger field specifying the version of CEL that +should evaluate the expression. + ## Alternatives Considered The following alternative solutions were considered but rejected. From 73859cfc05cb9e855dd2a6521bfc69bf9c2fef76 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 22 Apr 2019 16:28:55 -0700 Subject: [PATCH 13/21] Reimplement SourceAndType as an expression --- docs/broker/filtering.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 5ccf76d22aa..53072088c9e 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -69,6 +69,12 @@ rejects the request if an error is encountered. This will not catch errors arising from dynamic extension attributes or data fields - these can only be caught at evaluation time. +Reimplement the SourceAndType filter (and any future structured filtering +interfaces) as a mechanical transformation to an equivalent CEL expression. +This makes CEL the only code path that does filtering, both simplifying +maintenance and making the implementation of filtering easier in other +components (such as upstream event sources). + ### Variable prefixes | Prefix |Description | @@ -398,6 +404,7 @@ The inflexibility and implementation complexity of structured filters make this solution less suitable for Trigger filtering than CEL. However, structured filters can be a useful and important user interface on top of an expression language: for example, the existing SourceAndType syntax for expressing a filter -could be implemented by generating an equivalent CEL expression. This provides -users a structured filter interface when their needs are simple, and allows them -to transition to a more complex interface when their needs require it. +should be implemented by transformation to an equivalent CEL expression. This +provides users a structured filter interface when their needs are simple, and +allows them to transition to a more complex interface when their needs require +it. From 018df8e60ad881de5318390f8f60b1d6b8c2efa2 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 25 Apr 2019 13:39:13 -0700 Subject: [PATCH 14/21] Remove parse flags Extensions are always parsed anyway by the CloudEvents SDK, so setting parseExtensions to false has no efficiency benefit. Removing the field improves the approachability of the filtering interface. We can detect when parsing the expression whether data fields are used. This provides a more reliable signal than the parseData flag, so the flag is unnecessary. --- docs/broker/filtering.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 53072088c9e..7900eb53f3f 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -88,13 +88,9 @@ promotion of extension attributes to official attributes. The prefix `ce` was chosen for succintness and its suggestion that CloudEvents is the operative specification. -Data fields are available to the expression under the prefix `data`. - -Parsing dynamic extension attributes and data fields may be costly. In this -initial proposal, the Trigger must explicitly enable dynamic parsing by setting -boolean fields `parseExtensions` and/or `parseData`. Future work may -eliminate the need for these fields by detecting the use of extension attributes -and/or data fields in the expression. +Data fields are available to the expression under the prefix `data`, if the data +serialization format used is known and can be parsed by the filtering +implementation. ### Why CEL? @@ -239,7 +235,6 @@ _The `>` syntax is a standard yaml multiline string._ spec: filter: cel: - parseExtensions: true expression: > ce.type == "com.github.pull.create" || (ce.type == "com.github.issue.create" && @@ -260,7 +255,6 @@ resolved, dynamic integer fields in CEL must be compared as floats._ spec: filter: cel: - parseData: true expression: > ce.type == "dev.knative.observation" && data.latency > 300.0 From 26b1c9b59fea57c068b5942ff10cf3cf290ae250 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 29 Apr 2019 16:37:28 -0700 Subject: [PATCH 15/21] Simplify syntax and add attributes filter The `cel` level of the expression filter is removed and `expression` is moved up to its place. An `attributes` filter is added to replace `sourceAndType` (now deprecated). Filter combination at the top level is explicitly disallowed. Examples have been added to clarify some unusual cases. --- docs/broker/filtering.md | 213 +++++++++++++++++++++++++++++---------- 1 file changed, 162 insertions(+), 51 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 7900eb53f3f..dadc6ab3d5a 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -37,10 +37,17 @@ glance. ## Proposed Solution -Add a field to the Trigger Filter spec allowing users to specify an expression -as a string. The expression is evaluated for each event considered by the -Trigger. If the expression evaluates to true, the event is delivered to the -Trigger's subscriber. +Extend the Trigger's filter syntax to allow specifying an expression written in +[CEL](https://github.com/google/cel-spec). The existing `sourceAndType` filter +will be deprecated and replaced with an `attributes` map that allows filtering +on any CloudEvents attribute. + +### Add CEL expression filter + +Add an `expression` filter to the Trigger allowing users to specify an +expression as a string. The expression is evaluated for each event considered +by the Trigger. If the expression evaluates to true, the event is delivered to +the Trigger's subscriber. The evaluation environment of the expression may include: @@ -58,24 +65,52 @@ expression languages. ```yaml spec: filter: - cel: - expression: > - ce.type == "com.github.pull.create" && - ce.source == "https://github.com/knative/eventing/pulls/123" + expression: > + ce.type == "com.github.pull.create" && + ce.source == "https://github.com/knative/eventing/pulls/123" ``` +### Validate expression via webhook + Add a check to the Trigger webhook that validates the expression's syntax and rejects the request if an error is encountered. This will not catch errors -arising from dynamic extension attributes or data fields - these can only be +arising from use of dynamic extension attributes or data fields - these can only be caught at evaluation time. -Reimplement the SourceAndType filter (and any future structured filtering -interfaces) as a mechanical transformation to an equivalent CEL expression. -This makes CEL the only code path that does filtering, both simplifying -maintenance and making the implementation of filtering easier in other -components (such as upstream event sources). +### Add attributes map filter and deprecate SourceAndType + +Add an `attributes` filter that allows the user to specify equality for any +CloudEvents context attribute. Multiple attributes may be specified. The event +is delivered if all specified attribute values match the event exactly (Boolean +`AND`). + +Extensions may be specified as attributes. Nested extension fields must be +specified using a dot syntax, e.g. `field1.field2.field3`. + +Deprecate the SourceAndType filter as its functionality is subsumed by the +`attributes` filter. + +### Transform all filters into CEL expressions + +Implement the `attributes` filter (and reimplement the deprecated SourceAndType +filter) as a transformation to an equivalent CEL expression. This makes CEL the +only code path that does filtering, both simplifying maintenance and making the +implementation of filtering easier in other components (such as upstream event +sources). + +### Document policy for filter specifications -### Variable prefixes +To strike a balance between flexibility, maintainability, and user convenience, +adopt the following principles: + +* Only one top-level filter may be used per Trigger. A Trigger that specifies + more than one is rejected. +* All filters must be transformable to an equivalent CEL expression. +* Additional filter specifications may be added if indicated by user feedback. + +## Implementation details + +### Variables in the expression | Prefix |Description | |--------|------------| @@ -130,7 +165,7 @@ making it safe and secure to embed in a multi-tenant dispatcher process. ### Single attribute exact match -Specified with the SourceAndType field: +Specified with the SourceAndType filter: ```yaml spec: @@ -139,18 +174,26 @@ spec: type: com.github.pull.create ``` -Specified with a CEL expression: +Specified with the attributes filter: ```yaml spec: filter: - cel: - expression: ce.type == "com.github.pull.create" + attributes: + type: com.github.pull.create +``` + +Specified with the expression filter: + +```yaml +spec: + filter: + expression: ce.type == "com.github.pull.create" ``` ### Multiple attributes exact match -Specified with the SourceAndType field: +Specified with the SourceAndType filter: ```yaml spec: @@ -160,30 +203,38 @@ spec: source: https://github.com/knative/eventing/pulls/123 ``` -Specified with a CEL expression: +Specified with the attributes filter: + +```yaml +spec: + filter: + attributes: + type: com.github.pull.create + source: https://github.com/knative/eventing/pulls/123 +``` + +Specified with the expression filter: _The `>` syntax is a standard yaml multiline string._ ```yaml spec: filter: - cel: - expression: > - ce.type == "com.github.pull.create" && - ce.source == "https://github.com/knative/eventing/pulls/123" + expression: > + ce.type == "com.github.pull.create" && + ce.source == "https://github.com/knative/eventing/pulls/123" ``` ### Prefix match on source -Cannot be specified with the SourceAndType field. +Cannot be specified with the SourceAndType filter or the attributes filter. CEL supports multiple options for prefix match. The simplest is `startsWith`: ```yaml spec: filter: - cel: - expression: ce.source.startsWith("https://github.com") + expression: ce.source.startsWith("https://github.com") ``` CEL also implements shell-style wildcards with `match`: @@ -191,8 +242,7 @@ CEL also implements shell-style wildcards with `match`: ```yaml spec: filter: - cel: - expression: ce.source.match("https://github.com*") + expression: ce.source.match("https://github.com*") ``` For the most complex matching needs, CEL implements @@ -202,49 +252,111 @@ For the most complex matching needs, CEL implements ```yaml spec: filter: - cel: - expression: ce.source.matches("https://github.com.*") + expression: ce.source.matches("https://github.com.*") ``` ### Complex boolean expression -Cannot be specified with the SourceAndType field. +Cannot be specified with the SourceAndType filter. _The `>` syntax is a standard yaml multiline string._ ```yaml spec: filter: - cel: - expression: > - ce.type == "com.github.pull.create" || - (ce.type == "com.github.issue.create" && ce.source.matches("proposals") + expression: > + ce.type == "com.github.pull.create" || + (ce.type == "com.github.issue.create" && ce.source.matches("proposals") +``` + +### Exact match on official and extension attribute + +Cannot be specified with the SourceAndType filter. + +_This example assumes the repository name is available as a CloudEvents +extension `{"repository":proposals"}`._ + +Specified with the attributes filter: + +```yaml +spec: + filter: + attributes: + type: com.github.issue.create + repository: proposals +``` +_The `>` syntax is a standard yaml multiline string._ + +```yaml +spec: + filter: + expression: > + ce.type == "com.github.issue.create" && + ce.repository == "proposals" ``` -### Exact match on Extension +### Exact match on extension with dotted name -Cannot be specified with the SourceAndType field. +Cannot be specified with the SourceAndType filter. _This example assumes the repository name is available as a CloudEvents -extension with name `repository`._ +extension `{"github.repository":proposals"}`._ + +Specified with the attributes filter: + +```yaml +spec: + filter: + attributes: + github.repository: proposals +``` + +_The `>` syntax is a standard yaml multiline string._ + +```yaml +spec: + filter: + expression: > + ce["github.repository"] == "proposals" +``` + +### Exact match on nested extension + +Cannot be specified with the SourceAndType filter or the attributes filter. + +_This example assumes the repository name is available as a **nested** +CloudEvents extension `{"github":{"repository":"proposals"}}`._ _The `>` syntax is a standard yaml multiline string._ ```yaml spec: filter: - cel: - expression: > - ce.type == "com.github.pull.create" || - (ce.type == "com.github.issue.create" && - ce.repository == "proposals") + expression: > + ce.github.repository == "proposals" +``` + +### Exact match on data string field + +Cannot be specified with the SourceAndType filter or the attributes filter. + +_This example assumes the event data is the parseable equivalent of +`{"user":{"id":"abc123"}`._ +```yaml +spec: + filter: + expression: > + user.id == "abc123" ``` -### Exact match on Data +### Exact match on data number field + +Cannot be specified with the SourceAndType filter or the attributes filter. -Cannot be specified with the SourceAndType field. +_This example assumes the event data is the parseable equivalent of +`{"latency":300}`._ _The `>` syntax is a standard yaml multiline string._ @@ -254,10 +366,9 @@ resolved, dynamic integer fields in CEL must be compared as floats._ ```yaml spec: filter: - cel: - expression: > - ce.type == "dev.knative.observation" && - data.latency > 300.0 + expression: > + ce.type == "dev.knative.observation" && + data.latency > 300.0 ``` ## Caveats From f1a85082c254e6b2c54893f77e999bac7e0be3c5 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 29 Apr 2019 16:42:34 -0700 Subject: [PATCH 16/21] Note that CloudEvents is vague and in flux CloudEvents is still figuring out whether it wants to support numeric values in extensions. Note that there will probably be dragons for a while. --- docs/broker/filtering.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index dadc6ab3d5a..bcac9c03a65 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -373,6 +373,16 @@ spec: ## Caveats +### Numeric and nested extension values + +Some CloudEvents transports (such as the HTTP binary content mode) may be unable +to differentiate numeric and string values for top-level or nested extension +attributes. This is still being discussed by the CloudEvents working group (see +https://github.com/cloudevents/spec/pull/413). + +Until this is resolved, the type of numeric values parsed in CloudEvents +extensions may be unpredictable. + ### Choice of CEL The main caveat is the choice of CEL as expression language. From 004bfc8b2de5df71628874c60b19972e8967edf8 Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Mon, 29 Apr 2019 16:43:24 -0700 Subject: [PATCH 17/21] Clarify structured filters alternative This "alternative considered" is about using structured filters exclusively, without an expression language. Be clear that structured filters are fine as long as they compile down to an expression. --- docs/broker/filtering.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index bcac9c03a65..b26a6d92e4d 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -489,7 +489,7 @@ extensible to support future needs. The implementation and maintenance work required to develop a custom expression language make this solution less suitable for Trigger filtering than CEL. -### Structured filters +### Structured filters exclusively Instead of using an expression language, we could design a system of structured filters expressible as yaml or JSON, similar to Kubernetes set-based label @@ -503,7 +503,8 @@ matchExpressions: One advantage of structured filters is that their schema can be expressed in an OpenAPI document and syntax-checked at creation time without embedding a -language runtime. +language runtime. Another is that simple structured filters may be easier to +implement in many languages than a CEL runtime. Structured filters are not as flexible as an expression language. For example, the above Kubernetes label selectors cannot compose expressions with Boolean OR. @@ -516,10 +517,11 @@ off-the-shelf expression language can be embedded and immediately support significant complexity without additional effort. The inflexibility and implementation complexity of structured filters make this -solution less suitable for Trigger filtering than CEL. However, structured -filters can be a useful and important user interface on top of an expression -language: for example, the existing SourceAndType syntax for expressing a filter -should be implemented by transformation to an equivalent CEL expression. This -provides users a structured filter interface when their needs are simple, and -allows them to transition to a more complex interface when their needs require -it. +solution less suitable for Trigger filtering than CEL. + +However, structured filters are a useful and important user interface _in +addition to_ an expression language. Structured filters like the `attributes` +filter or `SourceAndType` filter should be implemented by transformation to an +equivalent CEL expression. This provides users a structured filter interface +for simple needs while also preserving the benefits of a single well-specified +mechanism for evaluating filters. From 0b262b825b4b4f5804de7b90394a0d42b15f64ee Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Tue, 30 Apr 2019 10:44:39 -0700 Subject: [PATCH 18/21] Explain choice of exclusive top-level filter --- docs/broker/filtering.md | 45 ++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index b26a6d92e4d..f5353d0e343 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -108,6 +108,7 @@ adopt the following principles: * All filters must be transformable to an equivalent CEL expression. * Additional filter specifications may be added if indicated by user feedback. + ## Implementation details ### Variables in the expression @@ -373,16 +374,6 @@ spec: ## Caveats -### Numeric and nested extension values - -Some CloudEvents transports (such as the HTTP binary content mode) may be unable -to differentiate numeric and string values for top-level or nested extension -attributes. This is still being discussed by the CloudEvents working group (see -https://github.com/cloudevents/spec/pull/413). - -Until this is resolved, the type of numeric values parsed in CloudEvents -extensions may be unpredictable. - ### Choice of CEL The main caveat is the choice of CEL as expression language. @@ -413,7 +404,7 @@ spec: expression: ce.type == "com.github.pull.create" ``` -### Versioning +### Expression language versioning Embedding an expression language into the Trigger specification means that we effectively have two versions exposed to the user: the Trigger CRD APIVersion and @@ -432,6 +423,38 @@ possible, we should support both CEL versions for one or more Knative releases. It might be necessary to add a Trigger field specifying the version of CEL that should evaluate the expression. +### Numeric and nested extension values + +Some CloudEvents transports (such as the HTTP binary content mode) may be unable +to differentiate numeric and string values for top-level or nested extension +attributes. This is still being discussed by the CloudEvents working group (see +https://github.com/cloudevents/spec/pull/413). + +Until this is resolved, the type of numeric values parsed in CloudEvents +extensions may be unpredictable. + +### Single top-level filter + +Top-level filters are now explicitly exclusive: only one may be specified. This +is done to ensure that Trigger filters are easily understood by the user. +Composable filters at the top-level would have unclear composition logic: are +they composed by Boolean **OR** or **AND**? The user must be aware of the +implicit semantics to understand the result of the trigger. + +If there is user demand for structured filter composition, top-level `or` and +`and` filters can be introduced that indicate how filter elements are composed. +This example is presented as an illustration only; it is not an element of the +proposal. + +```yaml +spec: + filter: + and: + - attributes: + type: com.github.pull.create + - expression: ce.source.match("knative") +``` + ## Alternatives Considered The following alternative solutions were considered but rejected. From f7c97b32f99d56b5ea13f6e7495efad18595bc3d Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Wed, 1 May 2019 15:33:33 -0700 Subject: [PATCH 19/21] Add filter spec alternatives considered --- docs/broker/filtering.md | 70 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index f5353d0e343..0afb67331a0 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -459,7 +459,9 @@ spec: The following alternative solutions were considered but rejected. -### Javascript or Lua as expression language +### Alternate expression language + +#### Javascript or Lua Trigger filtering is a very limited case for an embedded language. All that is needed from a language is the ability to write conditions that evaluate to true @@ -476,7 +478,7 @@ this could be a large number of diverse processes. Due to this additional implementation complexity, both Javascript and Lua have been judged less suitable for Trigger filtering than CEL. -### Rego (OPA) +#### Rego [Rego](https://www.openpolicyagent.org/docs/v0.10.7/language-reference/) is already as a policy expression language by @@ -489,7 +491,7 @@ filters would likely make Triggers the only remaining use of Rego. The possible maintenance burden of being the only Rego user makes Rego less suitable for Trigger filtering than CEL. -### Custom expression language +#### Custom expression language We could develop our own custom expression language for Trigger filters. This might be attractive since we could design the language for the needs of Trigger @@ -512,7 +514,7 @@ extensible to support future needs. The implementation and maintenance work required to develop a custom expression language make this solution less suitable for Trigger filtering than CEL. -### Structured filters exclusively +### Use structured filters with no expression language Instead of using an expression language, we could design a system of structured filters expressible as yaml or JSON, similar to Kubernetes set-based label @@ -548,3 +550,63 @@ filter or `SourceAndType` filter should be implemented by transformation to an equivalent CEL expression. This provides users a structured filter interface for simple needs while also preserving the benefits of a single well-specified mechanism for evaluating filters. + +### Alternate filter specification + +#### SourceAndType + +```yaml +spec: + filter: + sourceAndType: + source: https://github.com + type: com.github.pull +``` + +Only supports source and type fields, not subject or other fields. + +#### Extra level for expression options + +```yaml +spec: + filter: + cel: + expression: ce.subject == "knative/eventing/pull/23" +``` + +The ability to specify expression options was not sufficiently useful to justify +the extra level of nesting, plus we don't have a current need for expression +options. + +If expression options are needed later, we can add this syntax back. + +#### Multiple top-level filters + +```yaml +spec: + filter: + attributes: + source: https://github.com + type: com.github.pull + expression: ce.subject == "knative/eventing/pull/23" +``` + +The result of this filter is unclear: does the filter pass if all filters pass +or any filters pass? + +If we later want composable filters, we can add top-level `or` and `and` +filters. + +#### matchSource and matchTypes + +```yaml +spec: + filter: + matchTypes: com.github* + matchSource: https://github.com* + expression: ce.subject == "knative/eventing/pull/23" +``` + +Only supports matching on type and source, not subject or other fields. The +result of the filter is unclear due to implicit composition, same as +[Multiple top-level filters](#multiple-top-level-filters). \ No newline at end of file From bcfd13db413a81f8b11ddf62865071a81bbe1cfd Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 2 May 2019 12:27:55 -0700 Subject: [PATCH 20/21] Correct inequality example --- docs/broker/filtering.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 0afb67331a0..1cfa154d0e3 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -352,7 +352,7 @@ spec: user.id == "abc123" ``` -### Exact match on data number field +### Inequality on data number field Cannot be specified with the SourceAndType filter or the attributes filter. From 76554b8672d1311a4d607cfcde8e86643dc3987f Mon Sep 17 00:00:00 2001 From: Grant Rodgers Date: Thu, 2 May 2019 12:55:23 -0700 Subject: [PATCH 21/21] Add open questions section Add open questions related to evaluation errors. --- docs/broker/filtering.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/broker/filtering.md b/docs/broker/filtering.md index 1cfa154d0e3..935ee578bbc 100644 --- a/docs/broker/filtering.md +++ b/docs/broker/filtering.md @@ -609,4 +609,10 @@ spec: Only supports matching on type and source, not subject or other fields. The result of the filter is unclear due to implicit composition, same as -[Multiple top-level filters](#multiple-top-level-filters). \ No newline at end of file +[Multiple top-level filters](#multiple-top-level-filters). + +## Open Questions + +### Evaluation error handling + +Should the filter fail open (accept) or fail closed (reject)? How should evaluation errors be surfaced to the user? \ No newline at end of file