diff --git a/docs/operate/data-backup.mdx b/docs/operate/data-backup.mdx index 30c105f0..f432f07f 100644 --- a/docs/operate/data-backup.mdx +++ b/docs/operate/data-backup.mdx @@ -1,93 +1,14 @@ --- -sidebar_position: 12 +sidebar_position: 13 description: "Backing up and restoring the Restate data store on single nodes" --- import Admonition from '@theme/Admonition'; -# Snapshots & Backups +# Data Backups -## Snapshotting - -Restate workers can be configured to periodically publish snapshots of their partition state to a shared destination. -Snapshots act as a form of backup and allow nodes that had not previously served a partition to bootstrap a copy of its state. -Without snapshots, rebuilding a partition processor would require the full replay of the partition's log. Replaying the log might take a long time or even be impossible if the log was trimmed. - - - To understand the terminology used on this page, it might be helpful to read through the [architecture reference](/references/architecture). - - -### Configuring Snapshots -Restate clusters should always be configured with a snapshot repository to allow nodes to efficiently share partition state. -Restate currently supports using Amazon S3 (or another API-compatible object store) as a shared snapshot repository. -To set up a snapshot destination, update your [server configuration](/operate/configuration/server) as follows: - -```toml -[worker.snapshots] -destination = "s3://snapshots-bucket/cluster-prefix" -snapshot-interval-num-records = 10000 -``` - -This enables automated periodic snapshots to be written to the specified bucket. -You can also trigger snapshot creation manually using the [`restatectl`](/deploy/server/cluster/deployment#controlling-clusters): -```shell -restatectl snapshots create-snapshot --partition-id -``` - -We recommend testing the snapshot configuration by requesting a snapshot and examining the contents of the bucket. -You should see a new prefix with each partition's id, and a `latest.json` file pointing to the most recent snapshot. - -No additional configuration is required to enable restoring snapshots. -When partition processors first start up, and no local partition state is found, the processor will attempt to restore the latest snapshot from the repository. -This allows for efficient bootstrapping of additional partition workers. - - - For testing purposes, you can also use the `file://` protocol to publish snapshots to a local directory. This is mostly useful when experimenting with multi-node configurations on a single machine. The `file` provider does not support conditional updates, which makes it unsuitable for potentially contended operation. - - -For S3 bucket destinations, Restate will use the AWS credentials available from the environment, or the configuration profile specified by `AWS_PROFILE` environment variable, falling back to the default AWS profile. - -### Log trimming and Snapshots - -In a distributed environment, the shared log is the mechanism for replicating partition state among nodes. -Therefore it is critical to that all cluster members can get all the relevant events recorded in the log, even newly built nodes that will join the cluster in the future. -This requirement is at odds with an immutable log growing unboundedly. Snapshots enable log trimming - the proces of removing older segments of the log. - -When partition processors successfully publish a snapshot, they update their "archived" log sequence number (LSN). -This reflects the position in the log at which the snapshot was taken and allows the cluster to safely trim its logs. - -By default, Restate will attempt to trim logs once an hour which you can override or disable in the server configuration: - -```toml -[admin] -log-trim-check-interval = "1h" -``` - -This interval determines only how frequently the check is performed, and not a guarantee that logs will be trimmed. Restate will automatically determine the appropriate safe trim point for each partition's log. - -If replicated logs are in use in a clustered environment, the log safe trim point will be determined based on the archived LSN. -If a snapshot repository is not configured, then archived LSNs are not reported. -Instead, the safe trim point will be determined by the smallest reported persisted LSN across all known processors for the given partition. -Single-node local-only logs are also trimmed based on the partitions' persisted LSNs. - -The presence of any dead nodes in a cluster will cause trimming to be suspended for all partitions, unless a snapshot repository is configured. -This is because we can not know what partitions may reside on the unreachable nodes, which will become stuck when the node comes back. - -When a node starts up with pre-existing partition state and finds that the partition's log has been trimmed to a point beyond the most recent locally-applied LSN, the node will attempt to download the latest snapshot from the configured repository. If a suitable snapshot is available, the processor will re-bootstrap its local state and resume applying the log. - - - If you observe repeated `Shutting partition processor down because it encountered a trim gap in the log.` errors in the Restate server log, it is an indication that a processor is failing to start up due to missing log records. To recover, you must ensure that a snapshot repository is correctly configured and accessible from the node reporting errors. You can still recover even if no snapshots were taken previously as long as there is at least one healthy node with a copy of the partition data. In that case, you must first configure the existing node(s) to publish snapshots for the affected partition(s) to a shared destination. - - -### Pruning the snapshot repository - - - Restate does not currently support pruning older snapshots from the snapshot repository. We recommend implementing an object lifecycle policy directly in the object store to manage retention. - - -## Data Backups - This page covers backing up individual Restate server instances. For sharing snapshots in a Restate cluster environment, see [Logs and Snapshots](/operate/data-backup#snapshotting). + This page covers backing up individual Restate server instances. For sharing snapshots in a Restate cluster environment, see [Snapshots](/operate/snapshots). The Restate server persists both metadata (such as the details of deployed services, in-flight invocations) and data (e.g., virtual object and workflow state keys) in its data store, which is located in its base directory (by default, the `restate-data` path relative to the startup working directory). Restate is configured to perform write-ahead logging with fsync enabled to ensure that effects are fully persisted before being acknowledged to participating services. diff --git a/docs/operate/snapshots.mdx b/docs/operate/snapshots.mdx new file mode 100644 index 00000000..4a404e18 --- /dev/null +++ b/docs/operate/snapshots.mdx @@ -0,0 +1,126 @@ +--- +sidebar_position: 12 +description: "Backing up and restoring the Restate data store on single nodes" +--- + +import Admonition from '@theme/Admonition'; + +# Snapshots + + + This page covers configuring a Restate cluster to share partition snapshots for fast fail-over and bootstrapping new nodes. For backup of Restate nodes, see [Data Backup](/operate/data-backup). + + +Restate workers can be configured to periodically publish snapshots of their partition state to a shared destination. Snapshots are not necessarily backups. Rather, snapshots allow nodes that had not previously served a partition to bootstrap a copy of its state. Without snapshots, placing a partition processor on a node that wasn't previously a follower would require the full replay of that partition's log. Replaying the log might take a long time - and is impossible if the log gets trimmed. + + + To understand the terminology used on this page, it might be helpful to read through the [architecture reference](/references/architecture). + + +## Configuring Snapshots +Restate clusters should always be configured with a snapshot repository to allow nodes to efficiently share partition state, and for new nodes to be added to the cluster in the future. +Restate currently supports using Amazon S3 (or an API-compatible object store) as a shared snapshot repository. +To set up a snapshot destination, update your [server configuration](/operate/configuration/server) as follows: + +```toml +[worker.snapshots] +destination = "s3://snapshots-bucket/cluster-prefix" +snapshot-interval-num-records = 10000 +``` + +This enables automated periodic snapshots to be written to the specified bucket. +You can also trigger snapshot creation manually using the [`restatectl`](/deploy/server/cluster/deployment#controlling-clusters): +```shell +restatectl snapshots create-snapshot --partition-id +``` + +We recommend testing the snapshot configuration by requesting a snapshot and examining the contents of the bucket. +You should see a new prefix with each partition's id, and a `latest.json` file pointing to the most recent snapshot. + +No additional configuration is required to enable restoring snapshots. +When partition processors first start up, and no local partition state is found, the processor will attempt to restore the latest snapshot from the repository. +This allows for efficient bootstrapping of additional partition workers. + + + For testing purposes, you can also use the `file://` protocol to publish snapshots to a local directory. This is mostly useful when experimenting with multi-node configurations on a single machine. The `file` provider does not support conditional updates, which makes it unsuitable for potentially contended operation. + + +## Object Store endpoint and access credentials + +Restate supports Amazon S3 and S3-compatible object stores. In typical server deployments to AWS, the configuration will be automatically inferred. Object store locations are specified in the form of a URL where the scheme is `s3://` and the authority is the name of the _bucket_. Optionally, you may supply an additonal path within the bucket, which will be used as a common prefix for all operations. If you need to specify a custom endpoint for S3-compatible stores, you can override the API endpoint using the `aws-endpoint-url` config key. + +For typical server deployments in AWS, you might not need to set region or credentials at all when using Amazon S3 beyond setting the path. Restate's object store support uses the conventional [AWS SDKs and Tools](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) credentials discovery. We strongly recommend against using long-lived credentials in configuration. For development, you can use short-term credentials provided by a profile. + +### Local development with Minio + +Minio is a common target while developing locally. You can configure it as follows: + +```toml +[worker.snapshots] +destination = "s3://bucket/cluster-name" +snapshot-interval-num-records = 1000 + +aws-region = "local" +aws-access-key-id = "minioadmin" +aws-secret-access-key = "minioadmin" +aws-endpoint-url = "http://localhost:9000" +aws-allow-http = true +``` + +### Local development with S3 + +Assuming you have a profile set up to assume a specific role granted access to your bucket, you can work with S3 directly using a configuration like: + +```toml +[worker.snapshots] +destination = "s3://bucket/cluster-name" +snapshot-interval-num-records = 1000 +aws-profile = "restate-dev" +``` + +This assumes that in your `~/.aws/config` you have a profile similar to: + +``` +[profile restate-dev] +source_profile = ... +region = us-east-1 +role_arn = arn:aws:iam::123456789012:role/restate-local-dev-role +``` + +## Log trimming and Snapshots + +In a distributed environment, the shared log is the mechanism for replicating partition state among nodes. +Therefore it is critical to that all cluster members can get all the relevant events recorded in the log, even newly built nodes that will join the cluster in the future. +This requirement is at odds with an immutable log growing unboundedly. Snapshots enable log trimming - the proces of removing older segments of the log. + +When partition processors successfully publish a snapshot, they update their "archived" log sequence number (LSN). +This reflects the position in the log at which the snapshot was taken and allows the cluster to safely trim its logs. + +By default, Restate will attempt to trim logs once an hour which you can override or disable in the server configuration: + +```toml +[admin] +log-trim-check-interval = "1h" +``` + +This interval determines only how frequently the check is performed, and not a guarantee that logs will be trimmed. Restate will automatically determine the appropriate safe trim point for each partition's log. + +If replicated logs are in use in a clustered environment, the log safe trim point will be determined based on the archived LSN. +If a snapshot repository is not configured, then archived LSNs are not reported. +Instead, the safe trim point will be determined by the smallest reported persisted LSN across all known processors for the given partition. +Single-node local-only logs are also trimmed based on the partitions' persisted LSNs. + +The presence of any dead nodes in a cluster will cause trimming to be suspended for all partitions, unless a snapshot repository is configured. +This is because we can not know what partitions may reside on the unreachable nodes, which will become stuck when the node comes back. + +When a node starts up with pre-existing partition state and finds that the partition's log has been trimmed to a point beyond the most recent locally-applied LSN, the node will attempt to download the latest snapshot from the configured repository. If a suitable snapshot is available, the processor will re-bootstrap its local state and resume applying the log. + + + If you observe repeated `Shutting partition processor down because it encountered a trim gap in the log.` errors in the Restate server log, it is an indication that a processor is failing to start up due to missing log records. To recover, you must ensure that a snapshot repository is correctly configured and accessible from the node reporting errors. You can still recover even if no snapshots were taken previously as long as there is at least one healthy node with a copy of the partition data. In that case, you must first configure the existing node(s) to publish snapshots for the affected partition(s) to a shared destination. + + +## Pruning the snapshot repository + + + Restate does not currently support pruning older snapshots from the snapshot repository. We recommend implementing an object lifecycle policy directly in the object store to manage retention. + diff --git a/docs/operate/troubleshooting.mdx b/docs/operate/troubleshooting.mdx index 37175ca2..40a89500 100644 --- a/docs/operate/troubleshooting.mdx +++ b/docs/operate/troubleshooting.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 13 +sidebar_position: 14 description: "Resolving common problems with Restate deployments" --- diff --git a/static/schemas/openapi-admin.json b/static/schemas/openapi-admin.json index 51ce7e60..c85707a8 100644 --- a/static/schemas/openapi-admin.json +++ b/static/schemas/openapi-admin.json @@ -1 +1 @@ -{"openapi":"3.0.0","info":{"title":"Admin API","version":"1.2.0"},"paths":{"/cluster-health":{"get":{"tags":["cluster_health"],"summary":"Cluster health","description":"Get the cluster health.","operationId":"cluster_health","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClusterHealthResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments":{"get":{"tags":["deployment"],"summary":"List deployments","description":"List all registered deployments.","operationId":"list_deployments","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDeploymentsResponse"}}}}}},"post":{"tags":["deployment"],"summary":"Create deployment","description":"Create deployment. Restate will invoke the endpoint to gather additional information required for registration, such as the services exposed by the deployment. If the deployment is already registered, this method will fail unless `force` is set to `true`.","operationId":"create_deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments/{deployment}":{"get":{"tags":["deployment"],"summary":"Get deployment","description":"Get deployment metadata","operationId":"get_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"put":{"tags":["deployment"],"summary":"Update deployment","description":"Update deployment. Invokes the endpoint and replaces the existing deployment metadata with the discovered information. This is a dangerous operation that should be used only when there are failing invocations on the deployment that cannot be resolved any other way. Sense checks are applied to test that the new deployment is sufficiently similar to the old one.","operationId":"update_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeploymentRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["deployment"],"summary":"Delete deployment","description":"Delete deployment. Currently it's supported to remove a deployment only using the force flag","operationId":"delete_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"If true, the deployment will be forcefully deleted. This might break in-flight invocations, use with caution.","style":"simple","schema":{"type":"boolean"}}],"responses":{"202":{"description":"Accepted"},"501":{"description":"Not implemented. Only using the force flag is supported at the moment."},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/health":{"get":{"tags":["health"],"summary":"Health check","description":"Check REST API Health.","operationId":"health","responses":{"200":{"description":"OK"}}}},"/invocations/{invocation_id}":{"delete":{"tags":["invocation"],"summary":"Delete an invocation","description":"Delete the given invocation. By default, an invocation is terminated by gracefully cancelling it. This ensures virtual object state consistency. Alternatively, an invocation can be killed which does not guarantee consistency for virtual object instance state, in-flight invocations to other services, etc. A stored completed invocation can also be purged","operationId":"delete_invocation","parameters":[{"name":"invocation_id","in":"path","description":"Invocation identifier.","required":true,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"If cancel, it will gracefully terminate the invocation. If kill, it will terminate the invocation with a hard stop. If purge, it will only cleanup the response for completed invocations, and leave unaffected an in-flight invocation.","style":"simple","schema":{"$ref":"#/components/schemas/DeletionMode"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/openapi":{"get":{"tags":["openapi"],"summary":"OpenAPI specification","externalDocs":{"url":"https://swagger.io/specification/"},"operationId":"openapi_spec","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"/services":{"get":{"tags":["service"],"summary":"List services","description":"List all registered services.","operationId":"list_services","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServicesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}":{"get":{"tags":["service"],"summary":"Get service","description":"Get a registered service.","operationId":"get_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"patch":{"tags":["service"],"summary":"Modify a service","description":"Modify a registered service.","operationId":"modify_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers":{"get":{"tags":["service_handler"],"summary":"List service handlers","description":"List all the handlers of the given service.","operationId":"list_service_handlers","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServiceHandlersResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers/{handler}":{"get":{"tags":["service_handler"],"summary":"Get service handler","description":"Get the handler of a service","operationId":"get_service_handler","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}},{"name":"handler","in":"path","description":"Handler name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/openapi":{"get":{"tags":["service"],"summary":"Get service OpenAPI","description":"Get the service OpenAPI 3.1 contract.","operationId":"get_service_openapi","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OpenAPI 3.1 of the service","content":{"application/json":{"schema":{}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/state":{"post":{"tags":["service"],"summary":"Modify a service state","description":"Modify service state","operationId":"modify_service_state","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceStateRequest"}}},"required":true},"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions":{"get":{"tags":["subscription"],"summary":"List subscriptions","description":"List all subscriptions.","operationId":"list_subscriptions","parameters":[{"name":"sink","in":"query","description":"Filter by the exact specified sink.","style":"simple","schema":{"type":"string"}},{"name":"source","in":"query","description":"Filter by the exact specified source.","style":"simple","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSubscriptionsResponse"}}}}}},"post":{"tags":["subscription"],"summary":"Create subscription","description":"Create subscription.","operationId":"create_subscription","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions/{subscription}":{"get":{"tags":["subscription"],"summary":"Get subscription","description":"Get subscription","operationId":"get_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["subscription"],"summary":"Delete subscription","description":"Delete subscription.","operationId":"delete_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/version":{"get":{"tags":["version"],"summary":"Admin version information","description":"Obtain admin version information.","operationId":"version","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInformation"}}}}}}}},"components":{"schemas":{"ClusterHealthResponse":{"type":"object","required":["cluster_name"],"properties":{"cluster_name":{"description":"Cluster name","type":"string"},"metadata_cluster_health":{"description":"Embedded metadata cluster health if it was enabled","allOf":[{"$ref":"#/components/schemas/EmbeddedMetadataClusterHealth"}],"nullable":true}}},"EmbeddedMetadataClusterHealth":{"type":"object","required":["members"],"properties":{"members":{"description":"Current members of the embedded metadata cluster","type":"array","items":{"type":"integer","format":"uint32","minimum":0.0}}}},"ErrorDescriptionResponse":{"title":"Error description response","description":"Error details of the response","type":"object","required":["message"],"properties":{"message":{"type":"string"},"restate_code":{"title":"Restate code","description":"Restate error code describing this error","type":"string","nullable":true}}},"ListDeploymentsResponse":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentResponse"}}}},"DeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceNameRevPair"}}}},"String":{"type":"string"},"ServiceNameRevPair":{"type":"object","required":["name","revision"],"properties":{"name":{"type":"string"},"revision":{"type":"integer","format":"uint32","minimum":0.0}}},"ProtocolType":{"type":"string","enum":["RequestResponse","BidiStream"]},"LambdaARN":{"type":"string","format":"arn"},"RegisterDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"use_http_11":{"title":"Use http1.1","description":"If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.","default":false,"type":"boolean"},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"RegisterDeploymentResponse":{"type":"object","required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ServiceMetadata":{"type":"object","required":["deployment_id","handlers","idempotency_retention","name","public","revision","ty"],"properties":{"name":{"title":"Name","description":"Fully qualified name of the service","type":"string"},"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}},"ty":{"$ref":"#/components/schemas/ServiceType"},"documentation":{"title":"Documentation","description":"Documentation of the service, as propagated by the SDKs.","type":"string","nullable":true},"metadata":{"title":"Metadata","description":"Additional service metadata, as propagated by the SDKs.","type":"object","additionalProperties":{"type":"string"}},"deployment_id":{"title":"Deployment Id","description":"Deployment exposing the latest revision of the service.","type":"string"},"revision":{"title":"Revision","description":"Latest revision of the service.","type":"integer","format":"uint32","minimum":0.0},"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean"},"idempotency_retention":{"title":"Idempotency retention","description":"The retention duration of idempotent requests for this service.","type":"string"},"workflow_completion_retention":{"title":"Workflow completion retention","description":"The retention duration of workflows. Only available on workflow services.","type":"string","nullable":true},"inactivity_timeout":{"title":"Inactivity timeout","description":"This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format.\n\nThis overrides the default inactivity timeout set in invoker options.","type":"string","nullable":true},"abort_timeout":{"title":"Abort timeout","description":"This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format.\n\nThis overrides the default abort timeout set in invoker options.","type":"string","nullable":true}}},"HandlerMetadata":{"type":"object","required":["input_description","name","output_description"],"properties":{"name":{"type":"string"},"ty":{"allOf":[{"$ref":"#/components/schemas/HandlerMetadataType"}],"nullable":true},"documentation":{"title":"Documentation","description":"Documentation of the handler, as propagated by the SDKs.","type":"string","nullable":true},"metadata":{"title":"Metadata","description":"Additional handler metadata, as propagated by the SDKs.","type":"object","additionalProperties":{"type":"string"}},"input_description":{"title":"Human readable input description","description":"If empty, no schema was provided by the user at discovery time.","type":"string"},"output_description":{"title":"Human readable output description","description":"If empty, no schema was provided by the user at discovery time.","type":"string"},"input_json_schema":{"title":"Input JSON Schema","description":"JSON Schema of the handler input","nullable":true},"output_json_schema":{"title":"Output JSON Schema","description":"JSON Schema of the handler output","nullable":true}}},"HandlerMetadataType":{"type":"string","enum":["Exclusive","Shared","Workflow"]},"ServiceType":{"type":"string","enum":["Service","VirtualObject","Workflow"]},"DetailedDeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"UpdateDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"use_http_11":{"title":"Use http1.1","description":"If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.","default":false,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"DeletionMode":{"type":"string","enum":["Cancel","Kill","Purge"]},"ListServicesResponse":{"type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ModifyServiceRequest":{"type":"object","properties":{"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","default":null,"type":"boolean","nullable":true},"idempotency_retention":{"title":"Idempotency retention","description":"Modify the retention of idempotent requests for this service.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","default":null,"type":"string","nullable":true},"workflow_completion_retention":{"title":"Workflow completion retention","description":"Modify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","default":null,"type":"string","nullable":true},"inactivity_timeout":{"title":"Inactivity timeout","description":"This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.\n\nThis overrides the default inactivity timeout set in invoker options.","default":null,"type":"string","nullable":true},"abort_timeout":{"title":"Abort timeout","description":"This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.\n\nThis overrides the default abort timeout set in invoker options.","default":null,"type":"string","nullable":true}}},"ListServiceHandlersResponse":{"type":"object","required":["handlers"],"properties":{"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"ModifyServiceStateRequest":{"type":"object","required":["new_state","object_key"],"properties":{"version":{"title":"Version","description":"If set, the latest version of the state is compared with this value and the operation will fail when the versions differ.","type":"string","nullable":true},"object_key":{"title":"Service key","description":"To what virtual object key to apply this change","type":"string"},"new_state":{"title":"New State","description":"The new state to replace the previous state with","type":"object","additionalProperties":{"type":"array","items":{"type":"integer","format":"uint8","minimum":0.0}}}}},"ListSubscriptionsResponse":{"type":"object","required":["subscriptions"],"properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"SubscriptionResponse":{"type":"object","required":["id","options","sink","source"],"properties":{"id":{"$ref":"#/components/schemas/String"},"source":{"type":"string"},"sink":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}}}},"CreateSubscriptionRequest":{"type":"object","required":["sink","source"],"properties":{"source":{"title":"Source","description":"Source uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`","type":"string"},"sink":{"title":"Sink","description":"Sink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`","type":"string"},"options":{"title":"Options","description":"Additional options to apply to the subscription.","type":"object","additionalProperties":{"type":"string"},"nullable":true}}},"VersionInformation":{"type":"object","required":["ingress_endpoint","max_admin_api_version","min_admin_api_version","version"],"properties":{"version":{"title":"Admin server version","description":"Version of the admin server","type":"string"},"min_admin_api_version":{"title":"Min admin API version","description":"Minimum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"max_admin_api_version":{"title":"Max admin API version","description":"Maximum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"ingress_endpoint":{"title":"Ingress endpoint","description":"Ingress endpoint that the Web UI should use to interact with.","type":"string","format":"uri"}}}}}} +{"openapi":"3.0.0","info":{"title":"Admin API","version":"1.2.1"},"paths":{"/cluster-health":{"get":{"tags":["cluster_health"],"summary":"Cluster health","description":"Get the cluster health.","operationId":"cluster_health","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClusterHealthResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments":{"get":{"tags":["deployment"],"summary":"List deployments","description":"List all registered deployments.","operationId":"list_deployments","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDeploymentsResponse"}}}}}},"post":{"tags":["deployment"],"summary":"Create deployment","description":"Create deployment. Restate will invoke the endpoint to gather additional information required for registration, such as the services exposed by the deployment. If the deployment is already registered, this method will fail unless `force` is set to `true`.","operationId":"create_deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments/{deployment}":{"get":{"tags":["deployment"],"summary":"Get deployment","description":"Get deployment metadata","operationId":"get_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"put":{"tags":["deployment"],"summary":"Update deployment","description":"Update deployment. Invokes the endpoint and replaces the existing deployment metadata with the discovered information. This is a dangerous operation that should be used only when there are failing invocations on the deployment that cannot be resolved any other way. Sense checks are applied to test that the new deployment is sufficiently similar to the old one.","operationId":"update_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDeploymentRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["deployment"],"summary":"Delete deployment","description":"Delete deployment. Currently it's supported to remove a deployment only using the force flag","operationId":"delete_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"If true, the deployment will be forcefully deleted. This might break in-flight invocations, use with caution.","style":"simple","schema":{"type":"boolean"}}],"responses":{"202":{"description":"Accepted"},"501":{"description":"Not implemented. Only using the force flag is supported at the moment."},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/health":{"get":{"tags":["health"],"summary":"Health check","description":"Check REST API Health.","operationId":"health","responses":{"200":{"description":"OK"}}}},"/invocations/{invocation_id}":{"delete":{"tags":["invocation"],"summary":"Delete an invocation","description":"Delete the given invocation. By default, an invocation is terminated by gracefully cancelling it. This ensures virtual object state consistency. Alternatively, an invocation can be killed which does not guarantee consistency for virtual object instance state, in-flight invocations to other services, etc. A stored completed invocation can also be purged","operationId":"delete_invocation","parameters":[{"name":"invocation_id","in":"path","description":"Invocation identifier.","required":true,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"If cancel, it will gracefully terminate the invocation. If kill, it will terminate the invocation with a hard stop. If purge, it will only cleanup the response for completed invocations, and leave unaffected an in-flight invocation.","style":"simple","schema":{"$ref":"#/components/schemas/DeletionMode"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/openapi":{"get":{"tags":["openapi"],"summary":"OpenAPI specification","externalDocs":{"url":"https://swagger.io/specification/"},"operationId":"openapi_spec","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"/services":{"get":{"tags":["service"],"summary":"List services","description":"List all registered services.","operationId":"list_services","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServicesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}":{"get":{"tags":["service"],"summary":"Get service","description":"Get a registered service.","operationId":"get_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"patch":{"tags":["service"],"summary":"Modify a service","description":"Modify a registered service.","operationId":"modify_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers":{"get":{"tags":["service_handler"],"summary":"List service handlers","description":"List all the handlers of the given service.","operationId":"list_service_handlers","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServiceHandlersResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers/{handler}":{"get":{"tags":["service_handler"],"summary":"Get service handler","description":"Get the handler of a service","operationId":"get_service_handler","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}},{"name":"handler","in":"path","description":"Handler name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/openapi":{"get":{"tags":["service"],"summary":"Get service OpenAPI","description":"Get the service OpenAPI 3.1 contract.","operationId":"get_service_openapi","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OpenAPI 3.1 of the service","content":{"application/json":{"schema":{}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/state":{"post":{"tags":["service"],"summary":"Modify a service state","description":"Modify service state","operationId":"modify_service_state","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceStateRequest"}}},"required":true},"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions":{"get":{"tags":["subscription"],"summary":"List subscriptions","description":"List all subscriptions.","operationId":"list_subscriptions","parameters":[{"name":"sink","in":"query","description":"Filter by the exact specified sink.","style":"simple","schema":{"type":"string"}},{"name":"source","in":"query","description":"Filter by the exact specified source.","style":"simple","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSubscriptionsResponse"}}}}}},"post":{"tags":["subscription"],"summary":"Create subscription","description":"Create subscription.","operationId":"create_subscription","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions/{subscription}":{"get":{"tags":["subscription"],"summary":"Get subscription","description":"Get subscription","operationId":"get_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["subscription"],"summary":"Delete subscription","description":"Delete subscription.","operationId":"delete_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/version":{"get":{"tags":["version"],"summary":"Admin version information","description":"Obtain admin version information.","operationId":"version","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInformation"}}}}}}}},"components":{"schemas":{"ClusterHealthResponse":{"type":"object","required":["cluster_name"],"properties":{"cluster_name":{"description":"Cluster name","type":"string"},"metadata_cluster_health":{"description":"Embedded metadata cluster health if it was enabled","allOf":[{"$ref":"#/components/schemas/EmbeddedMetadataClusterHealth"}],"nullable":true}}},"EmbeddedMetadataClusterHealth":{"type":"object","required":["members"],"properties":{"members":{"description":"Current members of the embedded metadata cluster","type":"array","items":{"type":"integer","format":"uint32","minimum":0.0}}}},"ErrorDescriptionResponse":{"title":"Error description response","description":"Error details of the response","type":"object","required":["message"],"properties":{"message":{"type":"string"},"restate_code":{"title":"Restate code","description":"Restate error code describing this error","type":"string","nullable":true}}},"ListDeploymentsResponse":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentResponse"}}}},"DeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceNameRevPair"}}}},"String":{"type":"string"},"ServiceNameRevPair":{"type":"object","required":["name","revision"],"properties":{"name":{"type":"string"},"revision":{"type":"integer","format":"uint32","minimum":0.0}}},"ProtocolType":{"type":"string","enum":["RequestResponse","BidiStream"]},"LambdaARN":{"type":"string","format":"arn"},"RegisterDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"use_http_11":{"title":"Use http1.1","description":"If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.","default":false,"type":"boolean"},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"RegisterDeploymentResponse":{"type":"object","required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ServiceMetadata":{"type":"object","required":["deployment_id","handlers","idempotency_retention","name","public","revision","ty"],"properties":{"name":{"title":"Name","description":"Fully qualified name of the service","type":"string"},"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}},"ty":{"$ref":"#/components/schemas/ServiceType"},"documentation":{"title":"Documentation","description":"Documentation of the service, as propagated by the SDKs.","type":"string","nullable":true},"metadata":{"title":"Metadata","description":"Additional service metadata, as propagated by the SDKs.","type":"object","additionalProperties":{"type":"string"}},"deployment_id":{"title":"Deployment Id","description":"Deployment exposing the latest revision of the service.","type":"string"},"revision":{"title":"Revision","description":"Latest revision of the service.","type":"integer","format":"uint32","minimum":0.0},"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean"},"idempotency_retention":{"title":"Idempotency retention","description":"The retention duration of idempotent requests for this service.","type":"string"},"workflow_completion_retention":{"title":"Workflow completion retention","description":"The retention duration of workflows. Only available on workflow services.","type":"string","nullable":true},"inactivity_timeout":{"title":"Inactivity timeout","description":"This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format.\n\nThis overrides the default inactivity timeout set in invoker options.","type":"string","nullable":true},"abort_timeout":{"title":"Abort timeout","description":"This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format.\n\nThis overrides the default abort timeout set in invoker options.","type":"string","nullable":true}}},"HandlerMetadata":{"type":"object","required":["input_description","name","output_description"],"properties":{"name":{"type":"string"},"ty":{"allOf":[{"$ref":"#/components/schemas/HandlerMetadataType"}],"nullable":true},"documentation":{"title":"Documentation","description":"Documentation of the handler, as propagated by the SDKs.","type":"string","nullable":true},"metadata":{"title":"Metadata","description":"Additional handler metadata, as propagated by the SDKs.","type":"object","additionalProperties":{"type":"string"}},"input_description":{"title":"Human readable input description","description":"If empty, no schema was provided by the user at discovery time.","type":"string"},"output_description":{"title":"Human readable output description","description":"If empty, no schema was provided by the user at discovery time.","type":"string"},"input_json_schema":{"title":"Input JSON Schema","description":"JSON Schema of the handler input","nullable":true},"output_json_schema":{"title":"Output JSON Schema","description":"JSON Schema of the handler output","nullable":true}}},"HandlerMetadataType":{"type":"string","enum":["Exclusive","Shared","Workflow"]},"ServiceType":{"type":"string","enum":["Service","VirtualObject","Workflow"]},"DetailedDeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"UpdateDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"use_http_11":{"title":"Use http1.1","description":"If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.","default":false,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"DeletionMode":{"type":"string","enum":["Cancel","Kill","Purge"]},"ListServicesResponse":{"type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ModifyServiceRequest":{"type":"object","properties":{"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","default":null,"type":"boolean","nullable":true},"idempotency_retention":{"title":"Idempotency retention","description":"Modify the retention of idempotent requests for this service.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","default":null,"type":"string","nullable":true},"workflow_completion_retention":{"title":"Workflow completion retention","description":"Modify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","default":null,"type":"string","nullable":true},"inactivity_timeout":{"title":"Inactivity timeout","description":"This timer guards against stalled service/handler invocations. Once it expires, Restate triggers a graceful termination by asking the service invocation to suspend (which preserves intermediate progress).\n\nThe 'abort timeout' is used to abort the invocation, in case it doesn't react to the request to suspend.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.\n\nThis overrides the default inactivity timeout set in invoker options.","default":null,"type":"string","nullable":true},"abort_timeout":{"title":"Abort timeout","description":"This timer guards against stalled service/handler invocations that are supposed to terminate. The abort timeout is started after the 'inactivity timeout' has expired and the service/handler invocation has been asked to gracefully terminate. Once the timer expires, it will abort the service/handler invocation.\n\nThis timer potentially **interrupts** user code. If the user code needs longer to gracefully terminate, then this value needs to be set accordingly.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.\n\nThis overrides the default abort timeout set in invoker options.","default":null,"type":"string","nullable":true}}},"ListServiceHandlersResponse":{"type":"object","required":["handlers"],"properties":{"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"ModifyServiceStateRequest":{"type":"object","required":["new_state","object_key"],"properties":{"version":{"title":"Version","description":"If set, the latest version of the state is compared with this value and the operation will fail when the versions differ.","type":"string","nullable":true},"object_key":{"title":"Service key","description":"To what virtual object key to apply this change","type":"string"},"new_state":{"title":"New State","description":"The new state to replace the previous state with","type":"object","additionalProperties":{"type":"array","items":{"type":"integer","format":"uint8","minimum":0.0}}}}},"ListSubscriptionsResponse":{"type":"object","required":["subscriptions"],"properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"SubscriptionResponse":{"type":"object","required":["id","options","sink","source"],"properties":{"id":{"$ref":"#/components/schemas/String"},"source":{"type":"string"},"sink":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}}}},"CreateSubscriptionRequest":{"type":"object","required":["sink","source"],"properties":{"source":{"title":"Source","description":"Source uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`","type":"string"},"sink":{"title":"Sink","description":"Sink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`","type":"string"},"options":{"title":"Options","description":"Additional options to apply to the subscription.","type":"object","additionalProperties":{"type":"string"},"nullable":true}}},"VersionInformation":{"type":"object","required":["ingress_endpoint","max_admin_api_version","min_admin_api_version","version"],"properties":{"version":{"title":"Admin server version","description":"Version of the admin server","type":"string"},"min_admin_api_version":{"title":"Min admin API version","description":"Minimum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"max_admin_api_version":{"title":"Max admin API version","description":"Maximum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"ingress_endpoint":{"title":"Ingress endpoint","description":"Ingress endpoint that the Web UI should use to interact with.","type":"string","format":"uri"}}}}}} diff --git a/static/schemas/restate-server-configuration-schema.json b/static/schemas/restate-server-configuration-schema.json index 688a1d1d..eed98fe4 100644 --- a/static/schemas/restate-server-configuration-schema.json +++ b/static/schemas/restate-server-configuration-schema.json @@ -1089,12 +1089,11 @@ }, "SnapshotsOptions": { "title": "Snapshot options.", - "description": "Partition store snapshotting settings.", + "description": "Partition store snapshotting settings. At a minimum, set `destination` and `snapshot-interval-num-records` to enable snapshotting. For a complete example, see [Snapshots](https://docs.restate.dev/operate/snapshots).", "type": "object", "properties": { "destination": { - "title": "Destination", - "description": "Newly produced snapshots are published to this location. Supports `s3://` and `file://` protocol scheme.\n\nFor S3 bucket destinations, Restate will use the AWS credentials available from the environment, or the configuration profile specified by `AWS_PROFILE` environment variable, falling back to the default AWS profile.\n\nExample: `s3://bucket/prefix` will put snapshots in the specified bucket and (optional) prefix.\n\nDefault: `None`", + "description": "Base URL for cluster snapshots. Supports `s3://` and `file://` protocol scheme.\n\nDefault: `None`", "default": null, "type": [ "string", @@ -1113,56 +1112,49 @@ "minimum": 1.0 }, "aws-profile": { - "description": "The AWS configuration profile to use for S3 object store destinations.", - "default": null, + "description": "The AWS configuration profile to use for S3 object store destinations. If you use named profiles in your AWS configuration, you can replace all the other settings with a single profile reference. See the [AWS documentation on profiles] (https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) for more.", "type": [ "string", "null" ] }, "aws-region": { - "description": "AWS region to use with S3 object store destinations.", - "default": null, + "description": "AWS region to use with S3 object store destinations. This may be inferred from the environment, for example the current region when running in EC2. Because of the request signing algorightm this must have a value. For Minio, you can generally set this to any string, such as `us-east-1`.", "type": [ "string", "null" ] }, "aws-access-key-id": { - "description": "AWS access key. We strongly recommend against using long-lived credentials; set up a configuration profile with a role-based session credentials provider instead.", - "default": null, + "description": "AWS access key (or username in Minio / S3-compatible stores).", "type": [ "string", "null" ] }, "aws-secret-access-key": { - "description": "AWS secret key. We strongly recommend against using long-lived credentials; set up a configuration profile with a role-based session credentials provider instead.", - "default": null, + "description": "AWS secret key (or password in Minio / S3-compatible stores).", "type": [ "string", "null" ] }, "aws-session-token": { - "description": "AWS session token. We strongly recommend against using long-lived credentials; set up a configuration profile with a role-based session credentials provider instead.", - "default": null, + "description": "AWS session token, needed with short-term STS session credentials.", "type": [ "string", "null" ] }, "aws-endpoint-url": { - "description": "AWS endpoint URL for S3 object store destinations. Some S3-compatible stores may require you to use this.", - "default": null, + "description": "Endpoint URL override. When you use Amazon S3, this is typically inferred from the region and there is no need to set it. With other object stores, you will have to provide an appropriate HTTP(S) endpoint. If *not* using HTTPS, also set `aws-allow-http` to `true`.", "type": [ "string", "null" ] }, "aws-allow-http": { - "description": "Allow plain HTTP to be used with the object store endpoint.", - "default": null, + "description": "Allow plain HTTP to be used with the object store endpoint. Required when the endpoint URL that isn't using HTTPS.", "type": [ "boolean", "null"