Add GrpcFieldExtraction Filter (#28393)

Signed-off-by: Xuyang Tao <taoxuy@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 0eeeef336072d48bb5cf63693c7359e556e8ca25
main
update-envoy[bot] 1 year ago
parent eb439e77b3
commit 7c0db283c5
  1. 1
      envoy/extensions/filters/http/grpc_field_extraction/v3/BUILD
  2. 193
      envoy/extensions/filters/http/grpc_field_extraction/v3/config.proto

@ -8,6 +8,5 @@ api_proto_package(
deps = [
"//envoy/config/core/v3:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",
"@com_github_cncf_udpa//xds/annotations/v3:pkg",
],
)

@ -4,8 +4,6 @@ package envoy.extensions.filters.http.grpc_field_extraction.v3;
import "envoy/config/core/v3/base.proto";
import "xds/annotations/v3/status.proto";
import "udpa/annotations/status.proto";
import "validate/validate.proto";
@ -14,92 +12,130 @@ option java_outer_classname = "ConfigProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_field_extraction/v3;grpc_field_extractionv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;
option (xds.annotations.v3.file_status).work_in_progress = true;
// [#not-implemented-hide:]
// [#protodoc-title: gRPC Field Extraction]
// gRPC Field Extraction :ref:`configuration overview
// <config_http_filters_grpc_field_extraction>`.
//
// [#extension: envoy.filters.http.grpc_field_extraction]
// GrpcFieldExtraction filter supports extracting the fields from the first gRPC
//
// Overview
// --------
//
// This filter supports extracting the fields from the first gRPC
// request message no matter if it is unary or streaming and writing the result
// to the destination, for which currently only the static Envoy dynamic metadata `envoy.filters.http.grpc_field_extraction` is supported.
//
// # Assumptions
// Assumptions
// -----------
//
// This filter assumes
//
// 1. this filter is only applicable for gRPC with Protobuf as payload.
// 2. for bi-directional and client-side gRPC streaming, the initial message from the client should not depend on receiving the server initial metadata.
//
// # Process Flow
// Process Flow
// ------------
//
// When a request reaches the filter, it will check
// 1. if the request is gRPC request with a protobuf body, the filter tries to:
// a. block the incoming data before decoding the first complete gRPC message
// b. look up the target field from the buffered gRPC message
// c. if the extraction result isn't empty, write it into the dynamic metadata and resume the request propagation.
//
// 1. if the request is the gRPC request configured for extraction, the filter tries to:
//
// a. block the incoming data before decoding the first complete gRPC message
// b. look up the target field from the buffered gRPC message
// c. write the extraction result into the dynamic metadata and resume the request propagation.
//
// 2. otherwise, pass through the request.
//
// If the request is a malformed one found during 1.a or 1.b, the filter will reject the request.
//
// # Config Requirements
// 1. the target field should be of a singular primitive type or a repeated primitive type
// and its value will be extracted in string format.
// 2. the intermediate type could also be repeated.
// Config Requirements
// -------------------
//
// Here are config requirements
//
// 1. the target field should be among the following primitive types: `string`, `uint32`, `uint64`, `int32`, `int64`, `sint32`, `sint64`, `fixed32`, `fixed64`, `sfixed32`, `sfixed64`, `float`, `double`.
//
// 2. the target field could be repeated.
//
// 3. the intermediate type could also be repeated.
//
// Output Format
// -------------
//
// 1. the extracted field names/values will be wrapped in be ``field<StringValue>`` -> ``values<ListValue of StringValue>``, which will be added in the dynamic ``metadata<google.protobuf.Struct>``.
//
// 2. if the field value is empty, a empty ``<ListValue>`` will be set.
//
// # Output Format
// The result format will be `field<StringValue>` -> `values<ListValue of StringValue>` in the dynamic metadata<google.protobuf.Struct>.
// Performance
// -----------
//
// # Performance
// This filter should be performant as it
//
// 1. converts between the gRPC message from EnvoyBuffer without data copy.
// 2. parse the gRPC message binary directly without deserialization.
//
// though buffering the first message introduces some latency.
//
// # Example,
// we have the following request definition for the gRPC method `pkg.svc.Method`.
//
// message MethodRequest {
// string foo = 1;
// Nested nested = 2;
// ...
// }
//
// message Nested {
// repeated string bar = 1;
// }
//
// This is the filter config(expressed in JSON format).
// {
// "descriptor_set":{...},
// "extractions_by_method": {
// "pkg.svc.Method":{
// "request_field_extractions":{
// "foo":{
// },
// "nested.bar":{
// }
// }
// }
// },
// ...
// }
//
//
// During runtime, the filter receives the following `MethodRequest` message(expressed in JSON format).
// {
// foo: "val_foo",
// nested: { "bar": ["val_bar1", "val_bar2"]}
// }
//
// The filter will write the following dynamic metadata(expressed in JSON format).
//
// `envoy.filters.http.grpc_field_extraction`: {
// "foo":[
// "val_foo"
// ],
// "nested.bar":[
// "val_bar1", "val_bar2"
// ]
// }
// Example
// -------
//
// We have the following request definition for the gRPC method `pkg.svc.Method`.
//
// .. code-block:: proto
//
// message MethodRequest {
// string foo = 1;
// Nested nested = 2;
// uint32 baz = 3;
// ...
// }
//
// message Nested {
// repeated string bar = 1;
// }
//
// This is the filter config in JSON.
//
// .. code-block:: json
//
// {
// "descriptor_set":{},
// "extractions_by_method":{
// "pkg.svc.Method":{
// "request_field_extractions":{
// "foo":{
// },
// "nested.bar":{
// }
// "baz":{
// }
// }
// }
// }
// }
//
// During runtime, the filter receives the following `MethodRequest` message in JSON.
//
// .. code-block:: json
//
// {
// "foo": "val_foo",
// "nested": { "bar": ["val_bar1", "val_bar2"]}
// }
//
// The filter will write the following dynamic metadata(`envoy.filters.http.grpc_field_extraction`) in JSON.
//
// .. code-block:: json
//
// {
// "foo":[
// "val_foo"
// ],
// "nested.bar":[
// "val_bar1", "val_bar2"
// ]
// "baz":[
// ]
// }
message GrpcFieldExtractionConfig {
// The proto descriptor set binary for the gRPC services.
@ -124,17 +160,20 @@ message FieldExtractions {
// The key is the field path within the grpc request.
// For example, we can define `foo.bar.name` if we want to extract
// Request.foo.bar.name.
// message Request {
// // The namespace in which the Workspace should be created.
// Foo foo = 1;
// }
//
// message Foo {
// Bar bar = 1;
// }
// message Bar {
// string name = 1;
// }
// .. code-block:: proto
//
// message Request {
// Foo foo = 1;
// }
//
// message Foo {
// Bar bar = 1;
// }
//
// message Bar {
// string name = 1;
// }
map<string, RequestFieldValueDisposition> request_field_extractions = 1;
}

Loading…
Cancel
Save