
# クラスター API

> **注意**
>
> この API は [実験的機能](EXPERIMENTAL.html) のため、正式版では仕様が変更される可能性があります。


## InitCluster

**x-sora-target**: Sora_20221221.InitCluster

クラスターを初期化する際に必ず実行する必要がある API です。

クラスター初期化時に参加させるどれかのノードに対して行ってください。

`node_name_list` には初期化されたクラスターに参加するノードのリストを指定してください。
API が成功すると、そのノードリストで構成されるクラスターが構築されます。

> **ヒント**
>
> InitCluster API の実行はひとつのクラスターにつき一度だけ必要です。
> InitCluster API が成功した場合、その後のノード追加には [JoinCluster](EXPERIMENTAL_API_CLUSTER.html#17f3f5) API を使います。
>
> InitCluster API が次に必要になるのはクラスターが破綻した場合です。
> 詳細は [クラスター運用](CLUSTER.html#0233aa) を参照ください。

* - キー
  - 型
* - node_name_list
  - array of string

```console
$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20221221.InitCluster \
    node_name_list:='["node-02@192.0.2.7", "node-03@10.99.0.8", "node-01@192.0.2.5"]' \
    -vvv
```


## JoinCluster

**x-sora-target**: Sora_20211215.JoinCluster

指定したクラスターノードに参加します。

参加したいクラスターに属するノードのいずれかを `contact_node_name` で指定してください。
クラスターに属していれば、どのノードでもかまいません。

- 参加したいクラスターがすでに初期化されている必要があります。
- 正常に完了するためには、参加したいクラスターの過半数のノードが正常に稼働している必要があります- 参加したいクラスターが 1 ノードのときは例外で、そのノードが稼働していれば正常に処理できます

> **注釈**
>
> 新規にクラスターを作成する場合には、まず [InitCluster](EXPERIMENTAL_API_CLUSTER.html#621990) API を使用してください。

事前にクラスターの参加ノードが判明している場合には `sora.conf` の `contact_node_name_list` に指定しておくと、
それらのノードに対して、起動時に自動で JoinCluster を試行するようになります。

* - キー
  - 型
* - contact_node_name
  - string

```console
$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20211215.JoinCluster \
    contact_node_name=node-03@10.99.0.8 \
    -vvv
POST / HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 42
Content-Type: application/json
Host: 127.0.0.1:3000
User-Agent: HTTPie/1.0.3
x-sora-target: Sora_20211215.JoinCluster

{
    "contact_node_name": "node-03@192.0.2.8"
}

HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: http://127.0.0.1:5000
access-control-max-age: 1000
content-length: 116
content-type: application/json
date: Tue, 16 Nov 2021 09:28:11 GMT
server: Cowboy

{
    "node_name_list": [
        "node-01@192.0.2.5",
        "node-02@192.0.2.7",
        "node-03@192.0.2.8",
        "node-04@192.0.2.9",
        "node-05@192.0.2.10"
    ]
}
```


## ListClusterNodes

**x-sora-target**: Sora_20211215.ListClusterNodes

クラスターのノード一覧を表示します。

* - キー
  - 型
* - include_all_known_nodes (オプション)
  - boolean

`include_all_known_nodes` を `true` に指定することで、接続していないノードも含め、そのノードが知っているすべてのノード一覧を返します。
接続していないノードについては `node_name` と `connected` のみが結果に含まれます。

**レスポンス JSON**

* - キー
  - 型
  - 内容
* - external_api_url
  - string
  - ``sora.conf`` の ``external_api_url``
* - epoch
  - integer
  - 再起動回数
* - license_max_nodes
  - integer
  - ライセンスの最大ノード数
* - license_max_connections
  - integer
  - ライセンスの最大同時接続数
* - license_serial_code
  - string
  - ライセンスのシリアルコード
* - license_type
  - string
  - ライセンスのタイプ
* - node_name
  - string
  - ``sora.conf`` の ``node_name``
* - connected
  - boolean
  - API 実行ノードと正常に接続できているかどうか
* - external_signaling_url
  - string
  - ``sora.conf`` の ``external_signaling_url``
* - version
  - string
  - Sora のバージョン
* - mode
  - string
  - モード (normal / block_new_session / block_new_connection / initial)

```console
$ http POST 127.0.0.1:3000/ \
    x-sora-target:Sora_20211215.ListClusterNodes \
    -vvv
POST / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: 127.0.0.1:3000
User-Agent: HTTPie/1.0.3
x-sora-target: Sora_20211215.ListClusterNodes



HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: http://127.0.0.1:5000
access-control-max-age: 1000
content-length: 1753
content-type: application/json
date: Tue, 16 Nov 2021 09:22:16 GMT
server: Cowboy

[
    {
        "external_api_url": "http://192.0.2.5:3000/",
        "epoch": 1,
        "license_max_connections": 500,
        "license_serial_code": "ABCDEF-SRA-E001-203801-500",
        "license_type": "Experimental",
        "node_name": "node-01@192.0.2.5",
        "mode": "normal",
        "connected": true,
        "external_signaling_url": "wss://node-01.example.com/signaling",
        "version": "2021.2"
    },
    {
        "api_url": "http://192.0.2.7:3000/",
        "epoch": 2,
        "license_max_connections": 500,
        "license_serial_code": "ABCDEF-SRA-E002-203801-500",
        "license_type": "Experimental",
        "node_name": "node-02@192.0.2.7",
        "mode": "normal",
        "connected": true,
        "external_signaling_url": "wss://node-02.example.com/signaling",
        "version": "2021.2"
    },
    {
        "external_api_url": "http://192.0.2.8:3000/",
        "epoch": 2,
        "license_max_connections": 500,
        "license_serial_code": "ABCDEF-SRA-E003-203801-500",
        "license_type": "Experimental",
        "node_name": "node-03@192.0.2.8",
        "mode": "normal",
        "connected": true,
        "external_signaling_url": "wss://node-03.example.com/signaling",
        "version": "2021.2"
    },
    {
        "external_api_url": "http://192.0.2.9:3000/",
        "epoch": 1,
        "license_max_connections": 500,
        "license_serial_code": "ABCDEF-SRA-E004-203801-500",
        "license_type": "Experimental",
        "node_name": "node-04@192.0.2.9",
        "mode": "normal",
        "connected": true,
        "external_signaling_url": "wss://node-04.example.com/signaling",
        "version": "2021.2"
    },
    {
        "external_api_url": "http://192.0.2.10:3000/",
        "epoch": 2,
        "license_max_connections": 500,
        "license_serial_code": "ABCDEF-SRA-E005-203801-500",
        "license_type": "Experimental",
        "node_name": "node-05@192.0.2.10",
        "mode": "normal",
        "connected": true,
        "external_signaling_url": "wss://node-05.example.com/signaling",
        "version": "2021.2"
    }
]
```


## ListClusterChannels

**x-sora-target**: Sora_20211215.ListClusterChannels

クラスターチャネル割り当て一覧を表示します。

* - キー
  - 型
  - 内容
* - channel_id
  - string
  - チャネル ID
* - owners
  - string
  - 担当ノード

owners には以下が含まれます。

* - キー
  - 型
  - 内容
* - node_name
  - string
  - ノード名
* - epoch
  - integer
  - 担当ノードへ割り当てられた際のクラスターへの参加回数
* - epoch_latest
  - boolean
  - 担当ノードが無効かどうか
* - connected
  - boolean
  - 担当ノードが API 実行ノードと正常に接続できているかどうか

```console
$ http POST 127.0.0.1:3000/ \
    x-sora-target:Sora_20211215.ListClusterChannels \
    -vvv
POST / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: 127.0.0.1:3000
User-Agent: HTTPie/1.0.3
x-sora-target: Sora_20211215.ListClusterChannels



HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: http://127.0.0.1:5000
access-control-max-age: 1000
content-length: 646
content-type: application/json
date: Tue, 16 Nov 2021 08:42:25 GMT
server: Cowboy

[
    {
        "channel_id": "sora",
        "owners": [
           {
               "node_name": "node-01@192.0.2.5",
               "epoch": 1,
               "epoch_latest": true,
               "connected": true
           }
        ]
    },
    {
        "channel_id": "lemon",
        "owners": [
           {
               "node_name": "node-01@192.0.2.5",
               "epoch": 1,
               "epoch_latest": true,
               "connected": true
           }
        ]
    },
    {
        "channel_id": "hisui",
        "owners": [
           {
               "node_name": "node-03@192.0.2.5",
               "epoch": 2,
               "epoch_latest": true,
               "connected": true
           }
        ]
    },
    {
        "channel_id": "zakuro",
        "owners": [
           {
               "node_name": "node-03@192.0.2.5",
               "epoch": 2,
               "epoch_latest": true,
               "connected": true
           }
        ]
    }
]
```


## PurgeClusterNode

**x-sora-target**: Sora_20220629.PurgeClusterNode

復旧がすぐには難しい障害が発生したノードや、縮退し再参加する予定が無いノードの情報をクラスターから完全消去します。

この API は 1 クラスターにつき 1 回実行すればすべての参加ノードから指定したノード情報が完全消去されます。

- この API の実行時には、消去対象のノードは停止している必要があります
- この API が正常に完了するためには、過半数のノードが正常に稼働している必要があります
- API を実行するノードは、クラスターに参加していて、正常に稼働しているノードであればどのノードでもかまいません

> **警告**
>
> PurgeClusterNode API はクラスターからノードを完全に消去するための API です。
> 再参加するノードに対しては基本的に使用しないでください。
> この API を含めた運用の手順は [クラスター運用](CLUSTER.html#0233aa) をご確認ください。

* - キー
  - 型
* - target_node_name
  - string

```console
$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20220629.PurgeClusterNode \
    target_node_name=node-03@192.0.2.5 \
    -vvv
POST / HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 39
Content-Type: application/json
Host: 127.0.0.1:3000
User-Agent: HTTPie/3.2.1
x-sora-target: Sora_20220629.PurgeClusterNode

{
    "target_node_name": "node-03@192.0.2.5"
}


HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: http://127.0.0.1:3000
access-control-max-age: 1000
content-length: 38
content-type: application/json
date: Sun, 12 Jun 2022 03:13:42 GMT
server: Cowboy

{
    "target_node_name": "node-03@192.0.2.5"
}
```

```console
$ http POST 127.0.0.1:3001/ x-sora-target:Sora_20220629.PurgeClusterNode \
    target_node_name=node-03@192.0.2.5 \
        -vvv
POST / HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 39
Content-Type: application/json
Host: 127.0.0.1:3000
User-Agent: HTTPie/3.2.1
x-sora-target: Sora_20220629.PurgeClusterNode

{
    "target_node_name": "node-03@192.0.2.5"
}


HTTP/1.1 400 Bad Request
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: http://127.0.0.1:3000
access-control-max-age: 1000
content-length: 79
content-type: application/json
date: Sun, 12 Jun 2022 03:13:29 GMT
server: Cowboy

{
    "error_reason": {
        "target_node": "node-03@192.0.2.5"
    },
    "error_type": "NODE-IS-ALIVE"
}
```
