Skip to content

Commit

Permalink
Add last_operation endpoint for async bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt McNeeney committed Mar 21, 2017
1 parent 497ecda commit c1f610a
Showing 1 changed file with 68 additions and 16 deletions.
84 changes: 68 additions & 16 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
- [Synchronous and Asynchronous Operations](#synchronous-asynchronous)
- [Synchronous Operations](#synchronous-operations)
- [Asynchronous Operations](#asynchronous-operations)
- [Polling Last Operation](#polling)
- [Polling Interval and Duration](#polling-interval-and-duration)
- [Polling Last Service Instance Operation](#polling)
- [Polling Last Service Binding Operation](#polling-binding)
- [Polling Interval and Duration](#polling-interval-and-duration)
- [Provisioning](#provisioning)
- [Updating a Service Instance](#updating_service_instance)
- [Binding](#binding)
Expand Down Expand Up @@ -279,9 +280,9 @@ An asynchronous response triggers the platform marketplace to poll the endpoint
The marketplace must ensure that service brokers do not receive requests for an instance while an asynchronous operation is in progress. For example, if a broker is in the process of provisioning an instance asynchronously, the marketplace must not allow any update, bind, unbind, or deprovision requests to be made through the platform. A user who attempts to perform one of these actions while an operation is already in progress must receive an HTTP 400 response with the error message: `Another operation for this service instance is in progress`.

<div id="polling"/>
## Polling Last Operation
## Polling Last Service Instance Operation

When a broker returns status code `202 ACCEPTED` for [provision](#provisioning), [update](#updating_service_instance), [bind](#binding), [unbind](#unbinding) or [deprovision](#deprovisioning), the platform will begin polling the `/v2/service_instances/:guid/last_operation` endpoint to obtain the state of the last requested operation. The broker response must contain the field `state` and an optional field `description`.
When a broker returns status code `202 ACCEPTED` for [provision](#provisioning), [update](#updating_service_instance) or [deprovision](#deprovisioning), the platform will begin polling the `/v2/service_instances/:instance_id/last_operation` endpoint to obtain the state of the last requested operation. The broker response must contain the field `state` and an optional field `description`.

Valid values for `state` are `in progress`, `succeeded`, and `failed`. The platform will poll the `last_operation` endpoint as long as the broker returns `"state": "in progress"`. Returning `"state": "succeeded"` or `"state": "failed"` will cause the platform to cease polling. The value provided for `description` will be passed through to the platform API client and can be used to provide additional detail for users about the progress of the operation.

Expand All @@ -298,7 +299,7 @@ The request provides these query string parameters as useful hints for brokers.
|---|---|---|
| service_id | string | ID of the service from the catalog. |
| plan_id | string | ID of the plan from the catalog. |
| operation | string | A broker-provided identifier for the operation. When a value for <code>operation</code> is included with asynchronous responses for [Provision](#provisioning), [Update](#updating_service_instance), [Binding](#binding), [Unbinding](#unbinding) and [Deprovision](#deprovisioning) requests, the broker client should provide the same value using this query parameter as a URL-encoded string. |
| operation | string | A broker-provided identifier for the operation. When a value for <code>operation</code> is included with asynchronous responses for [Provision](#provisioning), [Update](#updating_service_instance) and [Deprovision](#deprovisioning) requests, the broker client should provide the same value using this query parameter as a URL-encoded string. |

<p class="note"><strong>Note:</strong> Although the request query parameters <code>service_id</code> and <code>plan_id</code> are not required, the platform should include them on all <code>last_operation</code> requests it makes to service brokers.</p>

Expand All @@ -322,6 +323,56 @@ All response bodies must be a valid JSON Object (`{}`). This is for future compa

For success responses, the following fields are valid.

| Response field | Type | Description |
|---|---|---|
| state* | string | Valid values are <code>in progress</code>, <code>succeeded</code>, and <code>failed</code>. While <code>"state": "in progress"</code>, the platform should continue polling. A response with <code>"state": "succeeded"</code> or <code>"state": "failed"</code> should cause the platform to cease polling. |
| description | string | Optional field. A user-facing message displayed to the platform API client. Can be used to tell the user details about the status polling-bindingof the operation. |

\* Fields with an asterisk are required.

<div id="polling-binding"/>
## Polling Last Service Binding Operation

When a broker returns status code `202 ACCEPTED` for [bind](#binding) or [unbind](#unbinding), the platform will begin polling the `/v2/service_instances/:instance_id/service_bindings/:binding_id/last_operation` endpoint to obtain the state of the last requested operation. The broker response must contain the field `state` and an optional field `description`.

Valid values for `state` are `in progress`, `succeeded`, and `failed`. The platform will poll the `last_operation` endpoint as long as the broker returns `"state": "in progress"`. Returning `"state": "succeeded"` or `"state": "failed"` will cause the platform to cease polling. The value provided for `description` will be passed through to the platform API client and can be used to provide additional detail for users about the progress of the operation.

### Request ###

##### Route #####
`GET /v2/service_instances/:instance_id/service_bindings/:binding_id/last_operation`

##### Parameters #####

The request provides these query string parameters as useful hints for brokers.

| Query-String Field | Type | Description |
|---|---|---|
| service_id | string | ID of the service from the catalog. |
| plan_id | string | ID of the plan from the catalog. |
| operation | string | A broker-provided identifier for the operation. When a value for <code>operation</code> is included with asynchronous responses for [Binding](#binding) and [Unbinding](#unbinding) requests, the broker client should provide the same value using this query parameter as a URL-encoded string. |

<p class="note"><strong>Note:</strong> Although the request query parameters <code>service_id</code> and <code>plan_id</code> are not required, the platform should include them on all <code>last_operation</code> requests it makes to service brokers.</p>

##### cURL #####
<pre class="terminal">
$ curl http://username:password@broker-url/v2/service_instances/:instance_id/service_bindings/:binding_id/last_operation
</pre>

### Response ###

| Status Code | Description |
|---|---|
| 200 OK | The expected response body is below. |

Responses with any other status code should be interpreted as an error or invalid response. The platform should continue polling until the broker returns a valid response or the [maximum polling duration](#polling-interval-and-duration) is reached. Brokers may use the `description` field to expose user-facing error messages about the operation state; for more info see [Broker Errors](#broker-errors).

##### Body #####

All response bodies must be a valid JSON Object (`{}`). This is for future compatibility; it will be easier to add fields in the future if JSON is expected rather than to support the cases when a JSON body may or may not be returned.

For success responses, the following fields are valid.

| Response field | Type | Description |

This comment has been minimized.

Copy link
@gberche-orange

gberche-orange Mar 22, 2017

Contributor

@mattmcneeney Shouldn't this include the binding credentials from the sync response body https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#body-6 ?

|---|---|---|
| state* | string | Valid values are <code>in progress</code>, <code>succeeded</code>, and <code>failed</code>. While <code>"state": "in progress"</code>, the platform should continue polling. A response with <code>"state": "succeeded"</code> or <code>"state": "failed"</code> should cause the platform to cease polling. |
Expand All @@ -332,15 +383,16 @@ For success responses, the following fields are valid.
<pre class="terminal">
{
"state": "in progress",
"description": "Creating service (10% complete)."
"description": "Binding service (10% complete)."
}
</pre>

<div id="polling-interval-and-duration"/>
### Polling Interval and Duration
## Polling Interval and Duration

The frequency and maximum duration of polling may vary by platform client. If a platform has a max polling duration and this limit is reached, the platform will cease polling and the operation state will be considered `failed`.


<div id="provisioning"/>
## Provisioning

Expand Down Expand Up @@ -398,7 +450,7 @@ $ curl http://username:password@broker-url/v2/service_instances/:instance_id -d
|---|---|
| 201 Created | Service instance has been provisioned. The expected response body is below. |
| 200 OK | May be returned if the service instance already exists and the requested parameters are identical to the existing service instance. The expected response body is below. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Service Instance Last Operation Endpoint](#polling) for operation status. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Last Service Instance Operation Endpoint](#polling) for operation status. |
| 409 Conflict | Should be returned if a service instance with the same id already exists but with different attributes. The expected response body is <code>{}</code>. |
| 422 Unprocessable Entity | Should be returned if the broker only supports asynchronous provisioning for the requested plan and the request did not include <code>?accepts_incomplete=true</code>. The expected response body is: <code>{ "error": "AsyncRequired", "description": "This service plan requires client support for asynchronous service operations." }</code>, as described below. |

Expand All @@ -414,7 +466,7 @@ For success responses, a broker may return the following fields. For error respo
| Response field | Type | Description |
|---|---|---|
| dashboard_url | string | The URL of a web-based management user interface for the service instance; we refer to this as a service dashboard. The URL should contain enough information for the dashboard to identify the resource being accessed (<code>9189kdfsk0vfnku</code> in the example below). |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Operation](#polling) endpoint in a URL encoded query parameter. |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Service Instance Operation](#polling) endpoint in a URL encoded query parameter. |

\* Fields with an asterisk are required.

Expand Down Expand Up @@ -497,7 +549,7 @@ $ curl http://username:password@broker-url/v2/service_instances/:instance_id -d
| Status Code | Description |
|---|---|
| 200 OK | The requests changes have been applied. The expected response body is <code>{}</code>. |
| 202 Accepted | Service instance update is in progress. This triggers the platform marketplace to poll the [Service Instance Last Operation Endpoint](#polling) for operation status. |
| 202 Accepted | Service instance update is in progress. This triggers the platform marketplace to poll the [Last Service Instance Operation Endpoint](#polling) for operation status. |
| 422 Unprocessable entity | May be returned if the requested change is not supported or if the request cannot currently be fulfilled due to the state of the instance (e.g. instance utilization is over the quota of the requested plan). Broker should include a user-facing message in the body; for details see [Broker Errors](#broker-errors). Additionally, a 422 can also be returned if the broker only supports asynchronous update for the requested plan and the request did not include <code>?accepts_incomplete=true</code>; in this case the expected response body is: <code>{ "error": "AsyncRequired", "description": "This service plan requires client support for asynchronous service operations." }</code> |

Responses with any other status code will be interpreted as a failure. Brokers can include a user-facing message in the `description` field; for details see [Broker Errors](#broker-errors).
Expand All @@ -510,7 +562,7 @@ For success responses, a broker may return the following field. Others will be i

| Response field | Type | Description |
|---|---|---|
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Operation](#polling) endpoint in a URL encoded query parameter. |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Service Instance Operation](#polling) endpoint in a URL encoded query parameter. |

\* Fields with an asterisk are required.

Expand Down Expand Up @@ -612,7 +664,7 @@ $ curl http://username:password@broker-url/v2/service_instances/:instance_id/ser
|---|---|
| 201 Created | Binding has been created. The expected response body is below. |
| 200 OK | May be returned if the binding already exists and the requested parameters are identical to the existing binding. The expected response body is below. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Service Instance Last Operation Endpoint](#polling) for operation status. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Last Service Binding Operation Endpoint](#polling-binding) for operation status. |
| 409 Conflict | Should be returned if the requested binding already exists. The expected response body is <code>{}</code>, though the description field can be used to return a user-facing error message, as described in [Broker Errors](#broker-errors). |
| 422 Unprocessable Entity | Should be returned if the broker requires that <code>app_guid</code> be included in the request body. The expected response body is: <code>{ "error": "RequiresApp", "description": "This service supports generation of credentials through binding an application only." }</code> Additionally, a 422 can also be returned if the broker only supports asynchronous binding for the requested plan and the request did not include <code>?accepts_incomplete=true</code>; in this case the expected response body is: <code>{ "error": "AsyncRequired", "description": "This service plan requires client support for asynchronous service operations." }</code> |

Expand All @@ -630,7 +682,7 @@ For success responses, the following fields are supported. Others will be ignore
| syslog\_drain_url | string | A URL to which logs may be streamed. <code>"requires":["syslog\_drain"]</code> must be declared in the [Catalog](#catalog-mgmt) endpoint or the platform should consider the response invalid. |
| route\_service_url | string | A URL to which the platform may proxy requests for the address sent with <code>bind\_resource.route</code> in the request body. <code>"requires":["route\_forwarding"]</code> must be declared in the [Catalog](#catalog-mgmt) endpoint or the platform should consider the response invalid. |
| volume\_mounts | array-of-objects | An array of configuration for mounting volumes. <code>"requires":["volume_mount"]</code> must be declared in the [Catalog](#catalog-mgmt) endpoint or the platform should consider the response invalid. |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Operation](#polling) endpoint in a URL encoded query parameter. |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Service Binding Operation](#polling-binding) endpoint in a URL encoded query parameter. |

<pre class="terminal">
{
Expand Down Expand Up @@ -682,7 +734,7 @@ $ curl 'http://username:password@broker-url/v2/service_instances/:instance_id/
| Status Code | Description |
|---|---|
| 200 OK | Binding was deleted. The expected response body is <code>{}</code>. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Service Instance Last Operation Endpoint](#polling) for operation status. |
| 202 Accepted | Service instance provisioning is in progress. This triggers the platform marketplace to poll the [Last Service Binding Operation Endpoint](#polling-binding) for operation status. |
| 410 Gone | Should be returned if the binding does not exist. The expected response body is <code>{}</code>. |
| 422 Unprocessable Entity | Should be returned if the broker only supports asynchronous unbinding for the requested plan and the request did not include <code>?accepts_incomplete=true</code>; in this case the expected response body is: <code>{ "error": "AsyncRequired", "description": "This service plan requires client support for asynchronous service operations." }</code> |

Expand All @@ -698,7 +750,7 @@ For success responses, the following fields are supported. Others will be ignore

| Response field | Type | Description |
|---|---|---|
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Operation](#polling) endpoint in a URL encoded query parameter. |
| operation | string | For asynchronous responses, service brokers may return an identifier representing the operation. The value of this field should be provided by the broker client with requests to the [Last Service Binding Operation](#polling-binding) endpoint in a URL encoded query parameter. |


<pre class="terminal">
Expand Down Expand Up @@ -746,7 +798,7 @@ $ curl 'http://username:password@broker-url/v2/service_instances/:instance_id?se
| Status Code | Description |
|---|---|
| 200 OK | Service instance was deleted. The expected response body is <code>{}</code>. |
| 202 Accepted | Service instance deletion is in progress. This triggers the marketplace to poll the [Service Instance Last Operation Endpoint](#polling) for operation status. |
| 202 Accepted | Service instance deletion is in progress. This triggers the marketplace to poll the [Last Service Instance Operation Endpoint](#polling) for operation status. |
| 410 Gone | Should be returned if the service instance does not exist. The expected response body is <code>{}</code>. |
| 422 Unprocessable Entity | Should be returned if the broker only supports asynchronous deprovisioning for the requested plan and the request did not include <code>?accepts_incomplete=true</code>. The expected response body is: <code>{ "error": "AsyncRequired", "description": "This service plan requires client support for asynchronous service operations." }</code>, as described below. |

Expand Down

0 comments on commit c1f610a

Please sign in to comment.