// Copyright 2025 Envoy Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

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 "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 {
}

// 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.
  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.
message ExecuteFilterAction {
  // Filter specific configuration which depends on the filter being
  // instantiated. See the supported filters for further documentation.
  // Only one of ``typed_config`` or ``dynamic_config`` 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`` or ``dynamic_config`` can be set.
  DynamicConfig dynamic_config = 2
      [(udpa.annotations.field_migrate).oneof_promotion = "config_type"];

  // 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;
}
