# 画面設計書 84-リカバリ情報

## 概要

本ドキュメントは、OpenSearchのインデックスリカバリ情報（Recovery）REST APIエンドポイントの画面設計書である。進行中および完了済みのインデックスシャードリカバリの詳細情報を取得するAPIである。

### 本画面の処理概要

リカバリ情報APIは、インデックスシャードのリカバリプロセスに関する詳細情報を返す。シャードリカバリは、ノード再起動、レプリカ割り当て、スナップショットリストアなど様々な理由で発生する。

**業務上の目的・背景**：クラスタ運用において、シャードのリカバリ状態を監視することは非常に重要である。ノード障害からの復旧時やクラスタのスケーリング時にシャードのリカバリが発生し、その進捗と所要時間を把握することでクラスタの可用性管理が可能になる。リカバリの種類（ストアからの復元、ピアからのコピー、スナップショットからの復元など）を理解し、ボトルネックを特定するために本APIが使用される。

**画面へのアクセス方法**：HTTPクライアントから `GET /{index}/_recovery` または `GET /_recovery` エンドポイントへリクエストを送信する。

**主要な操作・処理内容**：
1. 全インデックスまたは特定インデックスのリカバリ情報を取得する
2. `active_only=true`で現在進行中のリカバリのみに絞り込む
3. `detailed=true`で各シャードの詳細なリカバリ進捗情報を取得する

**画面遷移**：クラスタヘルス（No.90）でyellow/redステータスを検出した場合に、リカバリの進捗確認のために本APIを呼び出す。Cat リカバリ（No.157）はテーブル形式の簡潔な表示を返す。

**権限による表示制御**：インデックスの監視権限が必要である。本APIは`allowSystemIndexAccessByDefault()`が`true`を返すため、システムインデックスへのアクセスがデフォルトで許可されている。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 120 | リカバリ | 主機能 | 進行中のインデックスシャードリカバリ情報を返す処理 |

## 画面種別

情報取得（APIエンドポイント）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_recovery` | 全インデックスのリカバリ情報を取得 |
| GET | `/{index}/_recovery` | 指定インデックスのリカバリ情報を取得 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | list | 任意 | カンマ区切りのインデックス名。`_all`または空文字で全インデックス対象 |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| detailed | boolean | false | シャードリカバリの詳細情報を表示するか |
| active_only | boolean | false | 現在進行中のリカバリのみを表示するか |

## 表示項目

### レスポンス

| フィールド | 型 | 説明 |
|-----------|------|------|
| {index_name}.shards[] | array | シャード毎のリカバリ情報配列 |
| {index_name}.shards[].id | integer | シャードID |
| {index_name}.shards[].type | string | リカバリタイプ（STORE / PEER / SNAPSHOT / EMPTY_STORE / LOCAL_SHARDS） |
| {index_name}.shards[].stage | string | リカバリステージ（INIT / INDEX / VERIFY_INDEX / TRANSLOG / FINALIZE / DONE） |
| {index_name}.shards[].primary | boolean | プライマリシャードかどうか |
| {index_name}.shards[].start_time | string | リカバリ開始日時 |
| {index_name}.shards[].stop_time | string | リカバリ完了日時 |
| {index_name}.shards[].total_time_in_millis | long | リカバリ所要時間（ミリ秒） |
| {index_name}.shards[].source | object | リカバリ元の情報（ノードまたはスナップショット） |
| {index_name}.shards[].target | object | リカバリ先のノード情報 |
| {index_name}.shards[].index | object | インデックスデータのリカバリ進捗 |
| {index_name}.shards[].translog | object | トランザクションログのリプレイ進捗 |
| {index_name}.shards[].verify_index | object | インデックス検証の進捗 |

## イベント仕様

### 1-リカバリ情報取得

クライアントがリクエストを送信すると、`RestRecoveryAction.prepareRequest()`（73行目）で`RecoveryRequest`が構築される。`detailed`と`active_only`のパラメータが設定され（76-77行目）、`client.admin().indices().recoveries()`を通じてトランスポートアクションが実行される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| リカバリ情報取得 | - | SELECT | 読み取り専用。データ更新なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 発生条件 |
|-------------|------|-----------|---------|
| - | 成功 | `{"{index_name}":{"shards":[...]}}` | リカバリ情報正常取得 |
| - | エラー | `{"error":{"type":"index_not_found_exception",...}}` | 指定インデックスが存在しない |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| IndexNotFoundException | 404 | 指定したインデックスが存在しない場合 |

## 備考

- リカバリが完了したシャードも`active_only=false`（デフォルト）では表示される。
- `detailed=true`はファイル単位の詳細情報を含むため、レスポンスサイズが大きくなる可能性がある。
- システムインデックスへのアクセスがデフォルトで許可されている（`allowSystemIndexAccessByDefault()` = true）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | indices.recovery.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.recovery.json` | REST APIの仕様定義。detailed, active_onlyパラメータを把握 |
| 1-2 | RecoveryRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/recovery/RecoveryRequest.java` | リクエストデータ構造 |

**読解のコツ**: RecoveryRequestは`BroadcastRequest`を継承し、各シャードの状態を収集するブロードキャストパターンである。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestRecoveryAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestRecoveryAction.java` | RESTハンドラ。allowSystemIndexAccessByDefault()=trueの点に注目 |

**主要処理フロー**:
1. **59行目**: `routes()`で`GET /_recovery`と`GET /{index}/_recovery`を登録
2. **68-70行目**: `allowSystemIndexAccessByDefault()`がtrueを返す
3. **73-79行目**: `prepareRequest()`でRecoveryRequestを構築し、detailed, active_onlyを設定
4. **79行目**: `client.admin().indices().recoveries()`で実行

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

```
RestRecoveryAction.prepareRequest() [L73-79]
    |
    +-- RecoveryRequest() [リクエスト構築]
    |       +-- detailed(false) [L76]
    |       +-- activeOnly(false) [L77]
    |       +-- IndicesOptions.fromRequest() [L78]
    |
    +-- client.admin().indices().recoveries() [L79]
            |
            +-- TransportRecoveryAction.execute()
                    +-- 各ノードからリカバリ状態を収集
```

### データフロー図

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

HTTP GET /{index}/_recovery  RestRecoveryAction            RecoveryResponse
  +-- index (path)      ---> .prepareRequest() [L73]  ---> {"{index}": {
  +-- detailed (query)       RecoveryRequest [構築]           "shards": [...]
  +-- active_only (query)    TransportRecoveryAction         }}
                             各ノードのリカバリ状態収集
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| indices.recovery.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.recovery.json` | API仕様 | REST APIの仕様定義 |
| RestRecoveryAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestRecoveryAction.java` | ソース | RESTハンドラ |
| RecoveryRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/recovery/RecoveryRequest.java` | ソース | リクエストデータ構造 |
| TransportRecoveryAction.java | `server/src/main/java/org/opensearch/action/admin/indices/recovery/TransportRecoveryAction.java` | ソース | トランスポートアクション |
