-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* GSB API OpenAPI and AsyncAPI. * GSB API docs with API usage sequence diagrams --------- Co-authored-by: Przemyslaw Walski <pwalski@users.noreply.github.com> Co-authored-by: stranger80 <stranger80@users.noreply.github.com>
- Loading branch information
1 parent
8bc7dab
commit 909ace3
Showing
4 changed files
with
410 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,8 @@ | ||
## Yagna public API | ||
Public Yagna REST APIs client binding with Data Model and specifications in [OpenAPI](http://spec.openapis.org/) format. | ||
# Yagna public API | ||
|
||
Public Yagna REST APIs client binding with Data Model and specifications in | ||
[OpenAPI](http://spec.openapis.org/) format. | ||
|
||
## GSB API | ||
|
||
GSB API documentation [page](docs/gsb_api.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# GSB API | ||
|
||
GSB REST API allows to bind and unbind GSB services. | ||
|
||
Binding GSB service enables WebSocket endpoint which allows to listen on incoming GSB messages. | ||
Path to WebSocket endpoint is returned in bind service response. | ||
|
||
API documentation: | ||
|
||
- REST endpoints OpenAPI [schema](../specs/gsb-api.yaml). | ||
|
||
- WS AsyncAPI [schema](../specs/gsb-api-messages.yaml). | ||
|
||
Open it directly or by using AsyncAPI Studio. | ||
|
||
`docker run -it -p 8000:80 asyncapi/studio` | ||
|
||
## Sample GSB API usage scenarios | ||
|
||
### Basic scenario | ||
|
||
```mermaid | ||
sequenceDiagram | ||
participant App as WebSocket Client | ||
participant Backend as Backend Yagna | ||
participant Service as Golem Service | ||
App ->>+ Backend: POST /gsb-api/v1/services:<br> { listen: { on: '/public/gftp/myapp', <br> components: ['GetMetadata', 'GetChunk'] }} | ||
Backend -->> App: HTTP 201<br>{ listen: { ..., links: { messages: <br>'gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw' } } } | ||
App ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw <br> Headers: { Upgrade: websocket } | ||
Backend -->> App: HTTP 101 | ||
par WebSocket connection lifespan | ||
App ->> Backend: WS Event: Open | ||
loop Multiple GSB message calls | ||
Service ->>+ Backend: GSB: GetChunk <br>public/gftp/myapp | ||
Backend ->> App: WS Message: gsbRequest<br> { id: '<br>L3B1YmxpYy9nZnRwL215YXBw', <br>component: 'GetMetadata', <br>payload: { .. } } | ||
App -->> Backend: WS Message: gsbResponse<br> { id: '<br>L3B1YmxpYy9nZnRwL215YXBw', payload: { .. } } | ||
Backend -->>- Service : GSB: GftpMetadata | ||
end | ||
App ->> Backend: DELETE /gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App: WS Event: Close<br> CloseCode: Normal | ||
end | ||
Backend -->>- App: HTTP 200 | ||
``` | ||
|
||
### Early GSB request scenario (simplified) | ||
|
||
```mermaid | ||
sequenceDiagram | ||
participant App as WebSocket Client | ||
participant Backend as Backend Yagna | ||
participant Service as Golem Service | ||
App ->>+ Backend: POST /gsb-api/v1/services | ||
Backend -->> App: HTTP 201 | ||
Service ->>+ Backend: GSB: GetChunk | ||
Note right of Backend: Buffered GSB request | ||
App ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App: HTTP 101 | ||
par WebSocket connection lifespan | ||
App ->> Backend: WS Event: Open | ||
Backend ->> App: WS Message: gsbRequest | ||
App -->> Backend: WS Message: gsbResponse | ||
Backend -->>- Service : GSB: GftpMetadata | ||
App ->> Backend: DELETE /gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App: WS Event: Close<br> CloseCode: Normal | ||
end | ||
Backend -->>- App: HTTP 200 | ||
``` | ||
|
||
#### GSB messages buffering and cancelling (simplified) | ||
|
||
```mermaid | ||
sequenceDiagram | ||
participant App as WebSocket Client | ||
participant Backend as Backend Yagna | ||
participant Service as Golem Service | ||
App ->>+ Backend: POST /gsb-api/v1/services | ||
Backend -->> App: HTTP 201 | ||
App ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App: HTTP 101 | ||
par 1st WS connection lifespan | ||
App -->> Backend: WS Event: Close<br>CloseCode: Abnormal | ||
end | ||
Service ->>+ Backend: GSB: GetMetadata | ||
Note right of Backend: Buffering GSB request<br>when WS disconnected | ||
App ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App: HTTP 101 | ||
par 2nd WS connection lifespan | ||
App ->> Backend: WS Event: Open | ||
Backend ->> App: WS Message: gsbRequest | ||
App -->> Backend: WS Message: gsbResponse | ||
Backend -->>- Service : GSB: GftpMetadata | ||
Service ->>+ Backend: GSB: GetChunk | ||
Backend ->> App: WS Message: gsbRequest | ||
App -->> Backend: WS Event: Close<br>CloseCode: Abnormal | ||
end | ||
Note right of Backend: Canceling GSB request<br> on WS Close | ||
Backend -->>- Service: GSB: Error<br>ya_service_bus::Error::Closed | ||
App ->> Backend: DELETE /gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->>- App: HTTP 200 | ||
``` | ||
|
||
### Disconnect WS on new WS connection (simplified) | ||
|
||
```mermaid | ||
sequenceDiagram | ||
participant App0 as WebSocket Client<br>Old session | ||
participant App1 as WebSocket Client<br>New session | ||
participant Backend as Backend Yagna | ||
App0 ->>+ Backend: POST /gsb-api/v1/services | ||
Backend -->> App0: HTTP 201 | ||
App0 ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App0: HTTP 101 | ||
par Old WS connection | ||
App0 ->> Backend: WS Event: Open | ||
App1 ->> Backend: GET gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App0: WS Event: Close<br>CloseCode: Policy | ||
end | ||
par New WS connection | ||
Backend -->> App1: HTTP 101 | ||
App1 ->> Backend: WS Event: Open | ||
App1 ->> Backend: DELETE /gsb-api/v1/services/<br>L3B1YmxpYy9nZnRwL215YXBw | ||
Backend -->> App1: WS Event: Close<br> CloseCode: Normal | ||
end | ||
Backend -->>- App0: HTTP 200 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
asyncapi: "2.6.0" | ||
|
||
info: | ||
title: GSB services Websocket API | ||
description: " | ||
GSB services Websocket API allows to listen and respond to incoming GSB messages. | ||
In order to access endpoint required is to bind GSB services using 'POST /services' REST API endpoint. | ||
Request to 'DELETE /services/{servicesId}' closes WebSocket connection, cancels pending GSB requests, and disables WebSocket endpoint created for these services. | ||
" | ||
version: "0.1.0" | ||
|
||
servers: | ||
public: | ||
url: /gsb-api/v1 | ||
protocol: ws | ||
|
||
channels: | ||
/services/{servicesId}: | ||
parameters: | ||
servicesId: | ||
description: " | ||
Generated id for bound GSB services. | ||
Path with id is in response of POST /services (field 'listen.links.messages') | ||
" | ||
schema: | ||
type: string | ||
bindings: | ||
ws: | ||
method: GET | ||
subscribe: | ||
summary: GSB requests | ||
description: GSB message requests to bound services | ||
message: | ||
$ref: "#/components/messages/gsbRequest" | ||
|
||
publish: | ||
summary: GSB responses | ||
description: GSB message responses | ||
message: | ||
$ref: "#/components/messages/gsbResponse" | ||
|
||
components: | ||
messages: | ||
gsbRequest: | ||
payload: | ||
$ref: "#/components/schemas/gsbRequest" | ||
contentType: application/octet-stream | ||
gsbResponse: | ||
payload: | ||
$ref: "#/components/schemas/gsbResponse" | ||
contentType: application/octet-stream | ||
|
||
schemas: | ||
gsbRequest: | ||
summary: "GSB API services message request" | ||
type: object | ||
required: | ||
- "id" | ||
- "component" | ||
properties: | ||
id: | ||
$ref: "#/components/schemas/id" | ||
component: | ||
type: string | ||
description: "GSB message REQUEST type name" | ||
examples: | ||
- "GetChunk" | ||
payload: | ||
type: object | ||
description: " | ||
Serialized into object GSB message of 'component' REQUEST type (e.g. GetChunk type). | ||
Some GSB messages can be found here https://github.com/golemfactory/yagna/tree/master/core/model/src | ||
In case of request with no payload it can be empty (or missing). | ||
" | ||
contentMediaType: application/octet-stream | ||
contentEncoding: flexbuffers | ||
|
||
gsbResponse: | ||
summary: "GSB API services message response" | ||
type: object | ||
oneOf: | ||
- required: | ||
- id | ||
- payload | ||
not: | ||
required: | ||
- error | ||
- required: | ||
- id | ||
- error | ||
not: | ||
required: | ||
- payload | ||
properties: | ||
id: | ||
$ref: "#/components/schemas/id" | ||
payload: | ||
type: object | ||
description: " | ||
Serialized into object GSB message of 'component' RESPONSE type | ||
(e.g. for GetChunk it will have GftpChunk type). | ||
Some GSB messages can be found here https://github.com/golemfactory/yagna/tree/master/core/model/src | ||
" | ||
error: | ||
type: object | ||
description: " | ||
Object mapping GSB message error variant name to error message value. | ||
Example shows error ya_core_model::gftp::Error::InternalError. | ||
Some GSB message errors types can be found here https://github.com/golemfactory/yagna/tree/master/core/model/src | ||
" | ||
examples: | ||
- { "InternalError": "Failed to read file" } | ||
contentMediaType: application/octet-stream | ||
contentEncoding: flexbuffers | ||
|
||
id: | ||
type: string | ||
description: Id used to match request to response |
Oops, something went wrong.