# 画面設計書 95-アロケーション説明

## 概要

本ドキュメントは、OpenSearchのCluster Allocation Explain API（`GET/POST /_cluster/allocation/explain`）の画面設計書である。シャードアロケーションの判断理由を取得するためのREST APIエンドポイントについて、入出力仕様・処理フロー・例外処理を定義する。

### 本画面の処理概要

本APIは、特定のシャードがなぜ現在のノードに割り当てられているのか、またはなぜ未割り当てのままなのかの説明を提供するエンドポイントである。

**業務上の目的・背景**：クラスタ運用において、シャードが期待通りに割り当てられない問題は頻繁に発生する。本APIは、アロケーションの判断プロセスを可視化し、各アロケーター（ディスク使用量、レプリカ配置制約等）のYES/NO判定結果を確認できる。シャード未割り当て問題のトラブルシューティングに不可欠なツールである。

**画面へのアクセス方法**：HTTPクライアントから `GET /_cluster/allocation/explain` にリクエストを送信する。リクエストボディなしで最初の未割り当てシャードの説明を取得するか、ボディで特定シャードを指定する。

**主要な操作・処理内容**：
1. 最初の未割り当てシャードのアロケーション説明を取得（ボディなし）
2. 特定インデックス・シャード番号・プライマリ/レプリカを指定してアロケーション説明を取得（ボディ指定）
3. YES判定結果の包含（`include_yes_decisions=true`）
4. ディスク情報の包含（`include_disk_info=true`）

**画面遷移**：クラスタヘルス（No.90）でYELLOW/RED状態を検知した際に、本APIで未割り当てシャードの原因を調査する。原因に応じてクラスタ再ルーティング（No.96）やクラスタ設定更新（No.94）で対処する。

**権限による表示制御**：クラスタレベルのモニタリング権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 56 | シャードアロケーション | 主機能 | シャードアロケーションの説明を提供する処理 |

## 画面種別

詳細（REST API レスポンス）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_cluster/allocation/explain` | アロケーション説明を取得 |
| POST | `/_cluster/allocation/explain` | 特定シャードのアロケーション説明を取得 |

## 入出力項目

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|------|------|-----------|------|
| include_yes_decisions | boolean | いいえ | false | YES判定結果をレスポンスに含めるか |
| include_disk_info | boolean | いいえ | false | ディスク使用量とシャードサイズ情報を含めるか |

### リクエストボディ（任意）

| フィールド | 型 | 必須 | 説明 |
|-----------|------|------|------|
| index | string | いいえ | 説明対象のインデックス名 |
| shard | number | いいえ | 説明対象のシャード番号 |
| primary | boolean | いいえ | プライマリシャードかレプリカか |

### リクエストボディ例

```json
{
  "index": "my-index",
  "shard": 0,
  "primary": true
}
```

## 表示項目

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

| フィールド | 型 | 説明 |
|-----------|------|------|
| index | string | 対象インデックス名 |
| shard | number | 対象シャード番号 |
| primary | boolean | プライマリシャードか |
| current_state | string | シャードの現在の状態 |
| current_node | object | 現在割り当てられているノード情報 |
| unassigned_info | object | 未割り当て情報（理由、タイムスタンプ等） |
| can_allocate | string | 割り当て可否（YES/NO/THROTTLED等） |
| allocate_explanation | string | 割り当て判断の説明 |
| node_allocation_decisions | array | ノードごとの割り当て判定結果 |

## イベント仕様

### 1-アロケーション説明取得

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

1. `RestClusterAllocationExplainAction.prepareRequest()` でリクエストを解析
2. リクエストボディがない場合、空の `ClusterAllocationExplainRequest` を構築（最初の未割り当てシャードを説明）
3. リクエストボディがある場合、`ClusterAllocationExplainRequest.parse()` でパースして対象シャードを特定
4. `include_yes_decisions` と `include_disk_info` パラメータを設定
5. トランスポートアクション経由でアロケーション説明を実行
6. `ClusterAllocationExplainResponse` の `getExplanation()` を `toXContent()` でシリアライズして返却

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| アロケーション説明取得 | - | SELECT（読み取りのみ） | クラスタ状態とアロケーション判定ロジックを読み取り。書き込みなし |

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

本APIは読み取り専用であり、データの更新は発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| - | 成功 | 200 OK + アロケーション説明JSON | 正常にアロケーション説明を取得できた場合 |
| - | エラー | 400 Bad Request | 無効なインデックス名やシャード番号が指定された場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|---------------|------|
| IllegalArgumentException | 400 | 無効なインデックス名やシャード番号の指定 |
| IndexNotFoundException | 404 | 指定されたインデックスが存在しない場合 |
| ShardNotFoundException | 404 | 指定されたシャードが存在しない場合 |

## 備考

- リクエストボディなしでリクエストした場合、最初に見つかった未割り当てシャードについて説明が返される。
- `include_yes_decisions=true` を指定すると、割り当て可能と判断されたノードの理由も含まれるが、レスポンスサイズが大きくなる。
- システムインデックスへのアクセスがデフォルトで許可されている（`allowSystemIndexAccessByDefault()` が `true`）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClusterAllocationExplainRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java` | リクエスト構成（index, shard, primary, includeYesDecisions, includeDiskInfo） |
| 1-2 | ClusterAllocationExplainResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplainResponse.java` | レスポンス構成（ClusterAllocationExplanation） |
| 1-3 | ClusterAllocationExplanation.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java` | アロケーション説明のコアデータ構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestClusterAllocationExplainAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java` | RESTハンドラ。リクエストボディの有無による分岐 |

**主要処理フロー**:
1. **行64-65**: `routes()` でGET/POSTの2パターンを登録
2. **行79-101**: `prepareRequest()` でリクエスト解析
3. **行81-88**: ボディの有無で `ClusterAllocationExplainRequest` の構築を分岐
4. **行90-91**: `include_yes_decisions` と `include_disk_info` の設定
5. **行92-100**: トランスポートアクション実行とレスポンス構築

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

```
RestClusterAllocationExplainAction.prepareRequest() [行79]
    |
    +-- リクエストボディ判定 [行81]
    |       +-- ボディなし: new ClusterAllocationExplainRequest() [行83]
    |       +-- ボディあり: ClusterAllocationExplainRequest.parse() [行86]
    |
    +-- パラメータ設定 [行90-91]
    |       +-- includeYesDecisions
    |       +-- includeDiskInfo
    |
    +-- NodeClient.admin().cluster().allocationExplain() [行92]
            |
            +-- TransportClusterAllocationExplainAction
                    +-- アロケーション判定ロジック実行
                    +-- ClusterAllocationExplainResponse構築
```

### データフロー図

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

GET/POST /_cluster/allocation/explain --> RestClusterAllocationExplainAction     --> アロケーション説明JSON
  ?include_yes_decisions=true               |                                          |
  ?include_disk_info=true                   +-- リクエスト解析                           +-- index
  Body: {index, shard, primary}             +-- アロケーション判定実行                    +-- shard
                                            +-- 各ノードの判定結果収集                   +-- primary
                                                                                       +-- current_state
                                                                                       +-- node_allocation_decisions[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestClusterAllocationExplainAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterAllocationExplainAction.java` | ソース | RESTハンドラ |
| ClusterAllocationExplainRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplainRequest.java` | ソース | リクエストデータモデル |
| ClusterAllocationExplainResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplainResponse.java` | ソース | レスポンスデータモデル |
| ClusterAllocationExplanation.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/ClusterAllocationExplanation.java` | ソース | アロケーション説明コアロジック |
| TransportClusterAllocationExplainAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/allocation/TransportClusterAllocationExplainAction.java` | ソース | トランスポートアクション |
| cluster.allocation_explain.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cluster.allocation_explain.json` | 設定 | REST API仕様定義 |
