syntax = "proto3";

package envoy.extensions.filters.http.composite.v3;

import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/config_source.proto";
import "envoy/config/core/v3/extension.proto";

import "xds/type/matcher/v3/matcher.proto";

import "udpa/annotations/migrate.proto";
import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.http.composite.v3";
option java_outer_classname = "CompositeProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/composite/v3;compositev3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Composite]
// Composite Filter :ref:`configuration overview <config_http_filters_composite>`.
// [#extension: envoy.filters.http.composite]

// :ref:`Composite filter <config_http_filters_composite>` config. The composite filter config
// allows delegating filter handling to another filter as determined by matching on the request
// headers. This makes it possible to use different filters or filter configurations based on the
// incoming request.
//
// This is intended to be used with
// :ref:`ExtensionWithMatcher <envoy_v3_api_msg_extensions.common.matching.v3.ExtensionWithMatcher>`
// where a match tree is specified that indicates (via
// :ref:`ExecuteFilterAction <envoy_v3_api_msg_extensions.filters.http.composite.v3.ExecuteFilterAction>`)
// which filter configuration to create and delegate to.
message Composite {
  // Named filter chain definitions that can be referenced from
  // :ref:`ExecuteFilterAction.filter_chain_name
  // <envoy_v3_api_field_extensions.filters.http.composite.v3.ExecuteFilterAction.filter_chain_name>`.
  // The filter chains are compiled at configuration time and can be referenced by name.
  // This is useful when the same filter chain needs to be applied across many routes,
  // as it avoids duplicating the filter chain configuration.
  map<string, FilterChainConfiguration> named_filter_chains = 1;

  // [#not-implemented-hide:]
  // The match tree that will be used to select an action to execute. The action type should be
  // :ref:`ExecuteFilterAction
  // <envoy_v3_api_msg_extensions.filters.http.composite.v3.ExecuteFilterAction>`.
  xds.type.matcher.v3.Matcher matcher = 2;
}

// Per-route configuration for the Composite filter.
// [#not-implemented-hide:]
message CompositePerRoute {
  // Override of the match tree for this route.
  xds.type.matcher.v3.Matcher matcher = 1 [(validate.rules).message = {required: true}];
}

// A list of filter configurations to be called in order. Note that this can be used as the type
// inside of an ECDS :ref:`TypedExtensionConfig
// <envoy_v3_api_msg_config.core.v3.TypedExtensionConfig>` extension, which allows a chain of
// filters to be configured dynamically. In that case, the types of all filters in the chain must
// be present in the :ref:`ExtensionConfigSource.type_urls
// <envoy_v3_api_field_config.core.v3.ExtensionConfigSource.type_urls>` field.
message FilterChainConfiguration {
  repeated config.core.v3.TypedExtensionConfig typed_config = 1;
}

// Configuration for an extension configuration discovery service with name.
message DynamicConfig {
  // The name of the extension configuration. It also serves as a resource name in ExtensionConfigDS.
  // The resource type in the ``DiscoveryRequest`` will be :ref:`TypedExtensionConfig
  // <envoy_v3_api_msg_config.core.v3.TypedExtensionConfig>`.
  string name = 1 [(validate.rules).string = {min_len: 1}];

  // Configuration source specifier for an extension configuration discovery
  // service. In case of a failure and without the default configuration,
  // 500(Internal Server Error) will be returned.
  config.core.v3.ExtensionConfigSource config_discovery = 2;
}

// Composite match action (see :ref:`matching docs <arch_overview_matching_api>` for more info on match actions).
// This specifies the filter configuration of the filter that the composite filter should delegate filter interactions to.
// [#next-free-field: 6]
message ExecuteFilterAction {
  // Filter specific configuration which depends on the filter being
  // instantiated. See the supported filters for further documentation.
  // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name``
  // can be set.
  // [#extension-category: envoy.filters.http]
  config.core.v3.TypedExtensionConfig typed_config = 1
      [(udpa.annotations.field_migrate).oneof_promotion = "config_type"];

  // Dynamic configuration of filter obtained via extension configuration discovery service.
  // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name``
  // can be set.
  DynamicConfig dynamic_config = 2
      [(udpa.annotations.field_migrate).oneof_promotion = "config_type"];

  // An inlined list of filter configurations. The specified filters will be executed in order.
  // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name``
  // can be set.
  FilterChainConfiguration filter_chain = 4;

  // The name of a filter chain defined in
  // :ref:`Composite.named_filter_chains
  // <envoy_v3_api_field_extensions.filters.http.composite.v3.Composite.named_filter_chains>`.
  // At runtime, if the named filter chain is not found in the Composite filter's configuration,
  // no filter will be applied for this match (the action is silently skipped).
  // Only one of ``typed_config``, ``dynamic_config``, ``filter_chain``, or ``filter_chain_name``
  // can be set.
  string filter_chain_name = 5;

  // Probability of the action execution. If not specified, this is 100%.
  // This allows sampling behavior for the configured actions.
  // For example, if
  // :ref:`default_value <envoy_v3_api_field_config.core.v3.RuntimeFractionalPercent.default_value>`
  // under the ``sample_percent`` is configured with 30%, a dice roll with that
  // probability is done. The underline action will only be executed if the
  // dice roll returns positive. Otherwise, the action is skipped.
  config.core.v3.RuntimeFractionalPercent sample_percent = 3;
}
