{
  "$schema" : "https://json-schema.org/draft/2020-12/schema",
  "$id" : "https://voltdb.com/voltsp/schemas/emitter/voltdb-bulk-procedure",
  "title" : "Voltdb-bulk-procedure Emitter Configuration",
  "description" : "The `voltdb-bulk-procedure` operator differs from a typical sink in that it enables two-way communication with VoltDB.\nIt sends requests to a VoltDB procedure and forwards the responses to be processed by subsequent components of the stream.\n\nThe `voltdb-bulk-procedure` operator processes requests in batches, enabling a high throughput procedure calls with at least once delivery guarantees.\n\nThe `voltdb-bulk-procedure` operator requires VoltDBResource to be configured either in yaml or in java, see examples.\n\n## Compatibility\n* VoltDB **v15** or later\n\n## Partitioning\nRequests that hash to the same partition are batched and send directly to site responsible for that partition.\nThe VoltDB site thread reads the requests one by one and executes the procedure invocation.\n\nAfter processing, responses (or errors) are serialized and inserted into the VoltSP stream.\nThe worker thread picks them up as regular events. Even if a VoltSP worker is unavailable, the event\nflow is preserved, and batches continue regardless of procedure execution delays.\n\nVoltSP can finalize processing current batch and start consuming new batch of data, while VoltDB is still executing the procedure - these phases are detached.\nEven if called procedure is slow, VoltSP processing is not disturbed.\n\n## Handling duplicates\nIn case of failure while sending data to VoltDB, the batch may be retried, which can cause duplicates.\nRequests are saved with a `batchId` and a unique `index` to ensure each row’s uniqueness. The target procedure\nmust deduplicate incoming requests if the business logic relies on lack of duplicates. It is similar to the situation when an application\nsends same request twice via a VoltDB client.\n\n## Reading responses\nFor each procedure (e.g. `MyProcedure.java`), VoltSP automatically creates an associated VoltDB stream\nnamed `myprocedure_sq`. Since VoltDB streams require a topic defined in `deployment.xml`, you must add it manually.\nFor example:\n\n```xml\n<?xml version=\"1.0\"?>\n<deployment>\n    ...\n    <topics enabled=\"true\">\n        <topic name=\"myprocedure_topic\" />\n    </topics>\n</deployment>\n```\n\nOnce the topic is configured, procedure responses are fetched, decoded, and made available in the child stream.\n\n## Handling avro encoding\nVoltDB procedures can accept and return Avro payloads. The first parameter must be the partition key;\nsubsequent parameters may be Avro GenericRecord instances or POJOs.\n\nTo enable Avro serialization, both VoltSP and VoltDB must be able to retrieve schemas from a remote schema registry.\n",
  "type" : "object",
  "properties" : {
    "voltdb-bulk-procedure" : {
      "type" : "object",
      "properties" : {
        "procedureName" : {
          "type" : "string",
          "description" : "The name of the stored procedure in VoltDB to be invoked for bulk operations."
        },
        "voltClientResource" : {
          "description" : "Client resource reference to be used when connecting to VoltDb cluster",
          "anyOf" : [ {
            "type" : "string"
          }, {
            "$ref" : "resource-voltdb-client.schema.json#/properties/voltdb-client"
          } ]
        },
        "batchSize" : {
          "type" : "integer",
          "description" : "The maximum number of records to include in a single batch before inserting data into VoltDB. Higher values can improve throughput but will increase memory usage.",
          "default" : "100000",
          "minimum" : -2147483648,
          "maximum" : 2147483647
        },
        "maxBatchesPerTask" : {
          "type" : "integer",
          "description" : "The maximum number of batches VoltDB will process in a single execution.",
          "default" : "1000",
          "minimum" : -2147483648,
          "maximum" : 2147483647
        },
        "taskExecutionInterval" : {
          "type" : "string",
          "pattern" : "^(\\d+[smhd]|P(T|\\d+[YMD]).*)",
          "description" : "Specifies a time interval between the start of each run of the VoltDB event processing task.",
          "default" : "100ms"
        },
        "exceptionHandler" : {
          "type" : "string",
          "description" : "A custom exception handler to process errors that occur during the execution of bulk operations."
        },
        "triggers" : {
          "type" : "array",
          "description" : "List of trigger configurations that create sub-pipelines",
          "items" : {
            "type" : "object",
            "properties" : {
              "trigger" : {
                "type" : "string",
                "enum" : [ "org.voltdb.stream.plugin.volt.api.VoltProcedureTrigger#onEachResponse" ],
                "description" : "The trigger point that activates this sub-pipeline"
              },
              "processors" : {
                "type" : "array",
                "description" : "Optional list of processors to apply before the sink or emitter",
                "items" : {
                  "$ref" : "#/$defs/processor"
                }
              },
              "sink" : {
                "$ref" : "#/$defs/sink"
              },
              "emitter" : {
                "$ref" : "#/$defs/emitter"
              }
            },
            "oneOf" : [ {
              "required" : [ "trigger", "sink" ]
            }, {
              "required" : [ "trigger", "emitter" ]
            } ]
          }
        }
      },
      "required" : [ "procedureName", "voltClientResource", "triggers" ],
      "additionalProperties" : false
    }
  },
  "required" : [ "voltdb-bulk-procedure" ],
  "additionalProperties" : false
}
