# 画面設計書 99-投票設定除外追加

## 概要

本ドキュメントは、OpenSearchのPost Voting Config Exclusions API（`POST /_cluster/voting_config_exclusions`）の画面設計書である。投票設定除外をノードIDまたはノード名で追加するためのREST APIエンドポイントについて、入出力仕様・処理フロー・例外処理を定義する。

### 本画面の処理概要

本APIは、クラスタのマスター選出（投票設定）から特定のノードを除外するためのエンドポイントである。ノードの退役やメンテナンス時に使用される。

**業務上の目的・背景**：クラスタマネージャ対応ノード（master-eligible node）をクラスタから安全に取り除く際に使用される。ノードを直接停止すると、投票設定の整合性が崩れ、クラスタマネージャの選出に問題が生じる可能性がある。本APIで事前にノードを投票設定から除外することで、安全なノード退役が可能になる。

**画面へのアクセス方法**：HTTPクライアントから `POST /_cluster/voting_config_exclusions` にクエリパラメータでノードを指定してリクエストを送信する。

**主要な操作・処理内容**：
1. ノードIDを指定して投票設定除外を追加（`node_ids` パラメータ）
2. ノード名を指定して投票設定除外を追加（`node_names` パラメータ）
3. 除外処理完了までの待機（`timeout` パラメータ）

**画面遷移**：ノード情報（No.107）で対象ノードを確認した後、本APIで投票設定除外を追加する。ノード退役後、投票設定除外クリア（No.100）で除外設定をクリアする。

**権限による表示制御**：クラスタレベルの管理権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 53 | クラスタマネージャ選出 | 主機能 | 投票設定除外をノードIDまたは名前で更新する処理 |

## 画面種別

登録（REST API リクエスト/レスポンス）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| POST | `/_cluster/voting_config_exclusions` | 投票設定除外を追加 |
| POST | `/_cluster/voting_config_exclusions/{node_name}` | （非推奨）ノード名を指定して投票設定除外を追加 |

## 入出力項目

### パスパラメータ（非推奨）

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| node_name | string | いいえ | （非推奨）除外するノード名。node_idsまたはnode_namesクエリパラメータを使用すること |

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|------|------|-----------|------|
| node_ids | string | いいえ | - | 除外するノードの永続IDのカンマ区切りリスト。node_namesと同時指定不可 |
| node_names | string | いいえ | - | 除外するノード名のカンマ区切りリスト。node_idsと同時指定不可 |
| timeout | time | いいえ | 30s | 操作タイムアウト |

## 表示項目

### レスポンスフィールド

| フィールド | 型 | 説明 |
|-----------|------|------|
| （レスポンスボディ） | - | 成功時は空のJSONオブジェクトまたはacknowledgedレスポンス |

## イベント仕様

### 1-投票設定除外追加

クライアントからPOSTリクエストを受信すると、以下の処理が実行される。

1. `RestAddVotingConfigExclusionAction.prepareRequest()` でリクエストパラメータを解析
2. `resolveVotingConfigExclusionsRequest()` で `AddVotingConfigExclusionsRequest` を構築
3. `node_name`（非推奨パス）、`node_ids`、`node_names` のいずれかからノード指定を取得
4. `timeout` パラメータを解析（デフォルト30秒）
5. `AddVotingConfigExclusionsAction.INSTANCE` トランスポートアクションを実行
6. 投票設定除外が適用されるまで待機し、完了後にレスポンスを返却

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 投票設定除外追加 | クラスタメタデータ（VotingConfiguration） | UPDATE | 投票設定の除外リストにノードを追加 |

### テーブル別更新項目詳細

#### クラスタメタデータ（VotingConfiguration）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE | voting_config_exclusions | 指定されたノードID/名を除外リストに追加 | クラスタ状態のメタデータとして永続化 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| - | 成功 | 200 OK | 正常に投票設定除外が追加された場合 |
| - | 警告（非推奨） | "POST /_cluster/voting_config_exclusions/{node_name} will be removed..." | パスパラメータでnode_nameを指定した場合 |
| - | エラー | 408 Request Timeout | タイムアウト以内に除外が完了しなかった場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|---------------|------|
| IllegalArgumentException | 400 | node_idsとnode_namesの同時指定、または無効なノードID/名が指定された場合 |
| タイムアウト | 408 | 指定されたtimeout以内に除外処理が完了しなかった場合 |

## 備考

- `POST /_cluster/voting_config_exclusions/{node_name}` 形式は非推奨であり、将来のバージョンで削除予定。`node_ids` または `node_names` クエリパラメータを使用すること。
- `node_ids` と `node_names` は同時に指定できない。
- デフォルトのタイムアウトは30秒（`TimeValue.timeValueSeconds(30L)`）。
- 投票設定除外は永続的であり、手動でクリアするか、対象ノードがクラスタから離脱するまで保持される。

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AddVotingConfigExclusionsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/configuration/AddVotingConfigExclusionsRequest.java` | リクエスト構成（nodeDescriptions, nodeIds, nodeNames, timeout） |
| 1-2 | VotingConfigExclusion.java | `server/src/main/java/org/opensearch/cluster/coordination/CoordinationMetadata.java` | 除外されたノードのデータ構造 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestAddVotingConfigExclusionAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestAddVotingConfigExclusionAction.java` | RESTハンドラ。ノード指定方法の分岐処理 |

**主要処理フロー**:
1. **行72-77**: `routes()` で2パターンのPOSTを登録（非推奨パスとクエリパラメータ形式）
2. **行80-87**: `prepareRequest()` で `resolveVotingConfigExclusionsRequest()` を呼び出し
3. **行89-112**: `resolveVotingConfigExclusionsRequest()` でnode_name/node_ids/node_namesを解析
4. **行94-96**: 非推奨パスパラメータ `node_name` の処理
5. **行98-104**: クエリパラメータ `node_ids` と `node_names` の処理
6. **行106-111**: `AddVotingConfigExclusionsRequest` の構築（3種類のノード指定とtimeout）

### プログラム呼び出し階層図

```
RestAddVotingConfigExclusionAction.prepareRequest() [行80]
    |
    +-- resolveVotingConfigExclusionsRequest() [行81, 89]
    |       +-- node_name（非推奨）解析 [行94-96]
    |       +-- node_ids解析 [行98-100]
    |       +-- node_names解析 [行102-104]
    |       +-- AddVotingConfigExclusionsRequest構築 [行106-111]
    |
    +-- NodeClient.execute() [行82-86]
            +-- AddVotingConfigExclusionsAction.INSTANCE
            |
            +-- TransportAddVotingConfigExclusionsAction
                    +-- 投票設定除外の適用
                    +-- クラスタ状態の更新待機
```

### データフロー図

```
[入力]                                          [処理]                                          [出力]

POST /_cluster/voting_config_exclusions   --> RestAddVotingConfigExclusionAction          --> acknowledged
  ?node_ids=node1,node2                         |
  ?node_names=name1,name2                       +-- パラメータ解析
  ?timeout=30s                                  +-- AddVotingConfigExclusionsRequest構築
                                                +-- TransportAction実行
                                                +-- 投票設定除外適用
                                                +-- 完了待機
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestAddVotingConfigExclusionAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestAddVotingConfigExclusionAction.java` | ソース | RESTハンドラ |
| AddVotingConfigExclusionsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/configuration/AddVotingConfigExclusionsAction.java` | ソース | アクション定義 |
| AddVotingConfigExclusionsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/configuration/AddVotingConfigExclusionsRequest.java` | ソース | リクエストデータモデル |
| TransportAddVotingConfigExclusionsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/configuration/TransportAddVotingConfigExclusionsAction.java` | ソース | トランスポートアクション |
| cluster.post_voting_config_exclusions.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cluster.post_voting_config_exclusions.json` | 設定 | REST API仕様定義 |
