{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Configuration",
  "description": "Main Kango service configuration struct",
  "type": "object",
  "properties": {
    "connections": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/$defs/ConnectionConfig"
      }
    },
    "consumer": {
      "$ref": "#/$defs/ConsumerConfig"
    },
    "controlPlane": {
      "anyOf": [
        {
          "$ref": "#/$defs/ControlPlaneConfiguration"
        },
        {
          "type": "null"
        }
      ]
    },
    "persistence": {
      "$ref": "#/$defs/PersistenceConfiguration"
    },
    "settings": {
      "$ref": "#/$defs/Settings",
      "default": {
        "writeMode": "strict"
      }
    }
  },
  "examples": [
    {
      "connections": {
        "kafka-conn": {
          "config": {
            "bootstrap.servers": "localhost:9092"
          },
          "type": "kafka"
        },
        "mongodb-conn": {
          "config": {
            "database": "test",
            "url": "mongodb://localhost:27017/test?replicaSet=local"
          },
          "type": "mongo"
        }
      },
      "consumer": {
        "config": {
          "client.id": "kango",
          "group.id": "kango"
        },
        "connectionName": "kafka-conn",
        "topic": "test-topic-1",
        "type": "kafka"
      },
      "controlPlane": {
        "grpcAddress": "http://localhost:50052"
      },
      "persistence": {
        "collection": "test-collection-1",
        "connectionName": "mongo-conn"
      }
    }
  ],
  "required": [
    "persistence",
    "consumer",
    "connections"
  ],
  "$defs": {
    "ConnectionConfig": {
      "description": "Describes the possible type of connections that can be defined in the configuration file",
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "config": {
              "$ref": "#/$defs/KafkaConnectionConfig"
            },
            "type": {
              "type": "string",
              "const": "kafka"
            }
          },
          "required": [
            "type",
            "config"
          ]
        },
        {
          "type": "object",
          "properties": {
            "config": {
              "$ref": "#/$defs/MongodbConnectionConfig"
            },
            "type": {
              "type": "string",
              "const": "mongodb"
            }
          },
          "required": [
            "type",
            "config"
          ]
        }
      ]
    },
    "ConsumerConfig": {
      "description": "Describes the configuration of streaming layer, that is Kafka, to be adopted by the service",
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "kafka"
            }
          },
          "$ref": "#/$defs/KafkaConsumerConfig",
          "required": [
            "type"
          ]
        }
      ]
    },
    "ControlPlaneConfiguration": {
      "description": "Describes the service configuration to enable the interoperation with Control Plane",
      "type": "object",
      "properties": {
        "feedbackInterval": {
          "description": "Interval in milliseconds that must elapse between two feedback events sent to Control Plane Operator.\nIt defaults to `3000` ms when not provided during deserialization.",
          "type": "integer",
          "format": "uint64",
          "default": 3000,
          "minimum": 0
        },
        "grpcAddress": {
          "description": "Address to the gRPC server that should receive service feedback events",
          "type": "string",
          "examples": [
            "http://control-plane-operator:50052"
          ]
        },
        "onCreate": {
          "description": "Desired initial state of the Service, to be included in the registration request with the Control Plane.\nIf not provided, the service will start in `Pause` state.",
          "anyOf": [
            {
              "$ref": "#/$defs/InitialState"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "resumeAfterMs": {
          "description": "The number of milliseconds to wait before running the processing logic\nwhen connection with control plane operator failed\nand no desired fast data state was ever received.",
          "type": [
            "integer",
            "null"
          ],
          "format": "uint64",
          "default": null,
          "minimum": 0
        }
      },
      "required": [
        "grpcAddress"
      ]
    },
    "InitialState": {
      "description": "Enum to map the initial state of the service when registering to Control Plane,\naccording to the value defined in the configuration file.\n\nThis state should be used to be mapped to the Piper's ExecState.",
      "type": "string",
      "enum": [
        "pause",
        "resume"
      ]
    },
    "KafkaConnectionConfig": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/$defs/Secret"
      }
    },
    "KafkaConsumerConfig": {
      "type": "object",
      "properties": {
        "commitIntervalMs": {
          "description": "number of milliseconds between one commit and another",
          "type": "integer",
          "format": "uint64",
          "default": 500,
          "minimum": 0
        },
        "config": {
          "description": "librdkafka Kafka consumer configuration properties. Do not include here Kafka configurations\nabout the Kafka instance and/or connection, as it will be overrided by the selected connection",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/Secret"
          },
          "default": {}
        },
        "connectionName": {
          "description": "Reference to the Kafka configuration stored inside the Connection (`KafkaConnectionConfig`)\n\nThis property is required from version 0.6.0 onwards.",
          "type": "string"
        },
        "topic": {
          "description": "name of the Kafka topic from which the consumer will read messages",
          "type": "string"
        }
      },
      "required": [
        "connectionName",
        "topic"
      ]
    },
    "MongodbConnectionConfig": {
      "type": "object",
      "properties": {
        "appName": {
          "description": "The application name employed by MongoDB driver when performing queries.\nThis is useful for debugging purposes, such as recognizing which application\nis launching a query towards the database.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "database": {
          "description": "MongoDB database where events will be written to",
          "type": [
            "string",
            "null"
          ]
        },
        "url": {
          "description": "MongoDB connection string",
          "$ref": "#/$defs/Secret"
        }
      },
      "required": [
        "url"
      ]
    },
    "PersistenceConfiguration": {
      "description": "Describes the configuration of persistence layer, that is MongoDB, to be adopted by the service",
      "type": "object",
      "properties": {
        "appName": {
          "description": "The application name employed by MongoDB driver when performing queries.\nThis is useful for debugging purposes, such as recognizing which application\nis launching a query towards the database.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "collection": {
          "description": "MongoDB collection where events will be written to",
          "type": "string"
        },
        "connectionName": {
          "description": "Reference to the MongoDB configuration stored inside the Connection (`MongodbConnectionConfig`)\n\nThis property is required from version 0.6.0 onwards.",
          "type": "string"
        },
        "database": {
          "description": "MongoDB database where events will be written to",
          "type": [
            "string",
            "null"
          ]
        },
        "maxBatchSize": {
          "description": "Number of change events that should be buffered before\noffloading them in bulk onto the persistence layer",
          "type": "integer",
          "format": "uint",
          "default": 1000,
          "minimum": 0
        },
        "url": {
          "description": "MongoDB connection string",
          "anyOf": [
            {
              "$ref": "#/$defs/Secret"
            },
            {
              "type": "null"
            }
          ]
        },
        "writeIntervalMs": {
          "description": "Number of milliseconds that should elapse between two writes\non persistence layer when the maximum batch size is not reached\nwithin the interval",
          "type": "integer",
          "format": "uint64",
          "default": 1000,
          "minimum": 0
        }
      },
      "required": [
        "connectionName",
        "collection"
      ]
    },
    "Secret": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "object",
          "properties": {
            "encoding": {
              "description": "Define which type of encoding the library supports when it needs to read the actual secret value.",
              "type": "string",
              "enum": [
                "base64"
              ]
            },
            "key": {
              "type": "string"
            },
            "type": {
              "const": "env"
            }
          },
          "required": [
            "type",
            "key"
          ]
        },
        {
          "type": "object",
          "properties": {
            "encoding": {
              "description": "Define which type of encoding the library supports when it needs to read the actual secret value.",
              "type": "string",
              "enum": [
                "base64"
              ]
            },
            "key": {
              "type": "string"
            },
            "path": {
              "type": "string"
            },
            "type": {
              "const": "file"
            }
          },
          "required": [
            "type",
            "path"
          ]
        }
      ],
      "examples": [
        "my-secret",
        {
          "key": "CUSTOM_ENV_VAR",
          "type": "env"
        },
        {
          "encoding": "base64",
          "key": "CUSTOM_ENV_VAR",
          "type": "env"
        },
        {
          "path": "/path/to/file",
          "type": "file"
        }
      ]
    },
    "Settings": {
      "description": "Behavior settings",
      "type": "object",
      "properties": {
        "writeMode": {
          "$ref": "#/$defs/WriteMode"
        }
      },
      "required": [
        "writeMode"
      ]
    },
    "WriteMode": {
      "oneOf": [
        {
          "description": "_Insert_ and _update_ operations ensure that fields not found in the `after` payload are\nremoved from the potentially existing document on the persistence layer.\n\n_Inserts_ are executed as replace or insert operations, while _updates_ remove\nthe fields at first level that are not present in the `after` payload,\nbut are found in the `before` payload (use `\"$unset\"` clause).",
          "type": "string",
          "const": "strict"
        },
        {
          "description": "_Insert_ operations are treated as upserts, while _Update_ ones do not add the `\"$unset\"` clause.\nThus fields not mentioned in the after payload will be left untouched.",
          "type": "string",
          "const": "partial"
        }
      ]
    }
  }
}