// Copyright 2018 the Istio 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";

// $title: Redis Quota
// $description: Adapter for a Redis-based quota management system.
// $location: https://istio.io/docs/reference/config/policy-and-telemetry/adapters/redisquota.html
// $supported_templates: quota
// $aliases:
// $  - /docs/reference/config/adapters/redisquota.html

// The `redisquota` adapter can be used to support Istio's quota management
// system. It depends on a Redis server to store quota values.
//
// This adapter supports the [quota template](https://istio.io/docs/reference/config/policy-and-telemetry/templates/quota/).
package adapter.redisquota.config;

import "google/protobuf/duration.proto";
import "gogoproto/gogo.proto";

option go_package = "config";
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.equal_all) = false;
option (gogoproto.gostring_all) = false;

// redisquota adapter supports the rate limit quota using either fixed or
// rolling window algorithm. And it is using Redis as a shared data storage.
//
// Example configuration:
//
// ```yaml
// redisServerUrl: localhost:6379
// connectionPoolSize: 10
// quotas:
// - name: requestcount.quota.istio-system
//   maxAmount: 50
//   validDuration: 60s
//   bucketDuration: 1s
//   rateLimitAlgorithm: ROLLING_WINDOW
//   overrides:
//   - dimensions:
//       destination: ratings
//       source: reviews
//     maxAmount: 12
//   - dimensions:
//       destination: reviews
//     maxAmount: 5
// ```
message Params {
  message Override {
    option (gogoproto.goproto_getters) = true;

    // The specific dimensions for which this override applies.
    // String representation of instance dimensions is used to check against configured dimensions.
    // `dimensions` should not be empty
    map <string, string> dimensions = 1 [(gogoproto.nullable) = false];

    // The upper limit for this quota override.
    // This value should be bigger than 0
    int64 max_amount = 2;
  }

  // Algorithms for rate-limiting:
  enum QuotaAlgorithm {
    // `FIXED_WINDOW` The fixed window approach can allow 2x peak specified rate, whereas the rolling-window doesn't.
    FIXED_WINDOW = 0;
    // `ROLLING_WINDOW` The rolling window algorithm's additional precision comes at the cost of increased redis resource usage.
    ROLLING_WINDOW = 1;
  }

  message Quota {
    option (gogoproto.goproto_getters) = true;

    // The name of the quota
    string name = 1;

    // The upper limit for this quota. max_amount should be bigger than 0
    int64 max_amount = 2;

    // The amount of time allocated quota remains valid before it is
    // automatically released. This is only meaningful for rate limit quotas.
    // value should be `0 < validDuration`
    google.protobuf.Duration valid_duration = 3 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];

    // The `bucketDuration` will be ignored if `rateLimitAlgorithm` is `FIXED_WINDOW`
    // value should be `0 < bucketDuration < validDuration`
    google.protobuf.Duration bucket_duration = 4 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];

    // Quota management algorithm. The default value is `FIXED_WINDOW`
    QuotaAlgorithm rate_limit_algorithm = 5;

    // Overrides associated with this quota.
    // The first matching override is applied.
    repeated Override overrides = 6;
  }

  // The set of known quotas. At least one quota configuration is required
  repeated Quota quotas = 1 [(gogoproto.nullable) = false];

  // Redis connection string `<hostname>:<port number>`
  // ex) localhost:6379
  string redis_server_url = 2;

  // Maximum number of idle connections to redis
  // Default is 10 connections per every CPU as reported by runtime.NumCPU.
  int64 connection_pool_size = 3;
}
