# 画面設計書 124-スナップショットリストア

## 概要

本ドキュメントは、OpenSearchのスナップショットリストアAPI（POST /_snapshot/{repository}/{snapshot}/_restore）の画面設計書である。スナップショットからインデックスを復元するREST APIエンドポイントの仕様を定義する。

### 本画面の処理概要

**業務上の目的・背景**：スナップショットリストアはバックアップからのデータ復旧において最も重要な操作である。障害発生時のデータ復旧、テスト環境へのデータ展開、異なるクラスタへのデータ移行など、多様な運用シナリオで利用される。本APIはスナップショットに保存されたインデックスデータをクラスタに復元し、選択的なインデックスリストア、リネーム、設定変更など柔軟なオプションを提供する。

**画面へのアクセス方法**：REST APIクライアントから `POST /_snapshot/{repository}/{snapshot}/_restore` エンドポイントにHTTP POSTリクエストを送信してアクセスする。

**主要な操作・処理内容**：
1. クライアントがリポジトリ名、スナップショット名、リストアオプション（対象インデックス、リネームパターン等）を指定してPOSTリクエストを送信する
2. クラスタマネージャノードがリストア処理を開始する
3. RestoreServiceがスナップショットからインデックスメタデータを読み取り、新しいインデックスを作成する
4. 各データノードがリポジトリからシャードデータを復元する
5. wait_for_completionオプションにより同期/非同期動作を選択可能

**画面遷移**：スナップショット取得（GET /_snapshot/{repository}/{snapshot}）で対象を確認し、本APIでリストアを実行する。リストア後はインデックス情報取得（GET /{index}）やクラスタヘルス（GET /_cluster/health）でリストア結果を確認する。スナップショット作成（PUT /_snapshot/{repository}/{snapshot}）で作成したバックアップの復元操作として位置づけられる。

**権限による表示制御**：クラスタレベルの管理権限およびインデックス作成権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 64 | スナップショットリストア | 主機能 | スナップショットからインデックスを復元する処理 |

## 画面種別

登録（REST API - データ復元）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| POST | `/_snapshot/{repository}/{snapshot}/_restore` | スナップショットをリストア |

## 入出力項目

### パスパラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| repository | string | Yes | リポジトリ名 |
| snapshot | string | Yes | スナップショット名 |

### クエリパラメータ

| 項目名 | 型 | 必須 | デフォルト | 説明 |
|--------|------|------|-----------|------|
| cluster_manager_timeout | time | No | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | No | 30s | （非推奨）cluster_manager_timeout を使用すること |
| wait_for_completion | boolean | No | false | リストア完了まで待機するかどうか |
| source_remote_store_repository | string | No | - | リモートストアインデックスのリモートストアリポジトリ名 |

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

| 項目名 | 型 | 説明 |
|--------|------|------|
| indices | string/array | リストア対象のインデックス名 |
| ignore_unavailable | boolean | 利用不可能なインデックスを無視するか |
| include_global_state | boolean | グローバルステートを復元するか |
| rename_pattern | string | リネーム対象のインデックス名パターン（正規表現） |
| rename_replacement | string | リネーム後のインデックス名 |
| include_aliases | boolean | エイリアスを復元するか |
| partial | boolean | 部分的なリストアを許可するか |
| index_settings | object | リストア時に上書きするインデックス設定 |
| ignore_index_settings | array | リストア時に無視するインデックス設定 |
| storage_type | string | ストレージタイプ |

## 表示項目

### レスポンスボディ

| 項目名 | 型 | 説明 |
|--------|------|------|
| snapshot | object | リストア情報 |
| snapshot.snapshot | string | スナップショット名 |
| snapshot.indices | array | リストアされたインデックス名の配列 |
| snapshot.shards | object | シャード統計 |
| snapshot.shards.total | integer | 総シャード数 |
| snapshot.shards.successful | integer | 成功シャード数 |
| snapshot.shards.failed | integer | 失敗シャード数 |
| accepted | boolean | wait_for_completion=falseの場合のみ。リクエストが受理されたか |

## イベント仕様

### 1-スナップショットリストアリクエスト

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

1. RestRestoreSnapshotActionがリクエストパラメータとボディを解析し、RestoreSnapshotRequestを生成する
2. wait_for_completionパラメータを設定する（デフォルト: false）
3. リクエストボディからリストアオプション（indices, rename_pattern等）を読み取る
4. TransportRestoreSnapshotActionがクラスタマネージャノードで実行される
5. RestoreService#restoreSnapshot()が呼び出される
6. スナップショットからインデックスメタデータを読み取り、クラスタ状態に新しいインデックスを作成する
7. 各データノードがリポジトリからシャードデータをコピーしてリカバリする
8. wait_for_completion=trueの場合はリストア完了後にレスポンスを返却、falseの場合は即座にaccepted応答を返却

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| POST リクエスト | クラスタ状態（RestoreInProgress） | INSERT | リストア進行中の状態を記録 |
| POST リクエスト | クラスタ状態（Metadata） | INSERT | 新しいインデックスメタデータを追加 |
| POST リクエスト | クラスタ状態（RoutingTable） | INSERT | 新しいシャードのルーティング情報を追加 |
| POST リクエスト | データノード（シャードデータ） | INSERT | リポジトリからシャードデータを復元 |

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

#### クラスタ状態

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| INSERT | IndexMetadata | スナップショットから読み取ったインデックスメタデータ | rename_patternによるリネーム適用 |
| INSERT | RoutingTable | リストアされるインデックスのシャードルーティング | INITIALIZING状態で作成 |

## メッセージ仕様

| HTTPステータス | 条件 | メッセージ例 |
|---------------|------|-------------|
| 200 OK | リストア完了（wait_for_completion=true） | リストア情報のJSONレスポンス |
| 200 OK | リストア受理（wait_for_completion=false） | `{"accepted": true}` |
| 404 Not Found | スナップショットが存在しない | `SnapshotMissingException` |
| 404 Not Found | リポジトリが存在しない | `RepositoryMissingException` |
| 500 Internal Server Error | リストア処理中のエラー | `SnapshotRestoreException` |

## 例外処理

| 例外 | 条件 | 対処 |
|------|------|------|
| SnapshotMissingException | スナップショットが存在しない | 404を返却 |
| RepositoryMissingException | リポジトリが存在しない | 404を返却 |
| SnapshotRestoreException | リストア処理中にエラーが発生 | 500を返却 |
| ClusterBlockException | METADATA_WRITEまたはWRITEブロックが設定されている | 処理をブロック |

## 備考

- wait_for_completion=falseの場合、リストアは非同期で実行される。進捗はクラスタヘルスAPIやインデックスリカバリAPIで確認可能
- rename_patternとrename_replacementを使用してリストア時にインデックス名を変更できる
- index_settingsで一部の設定をリストア時に上書き可能（例：レプリカ数の変更）
- source_remote_store_repositoryパラメータはリモートストアインデックスのリストア時に使用
- `master_timeout` パラメータはバージョン2.0.0で非推奨

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RestoreSnapshotRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java` | リクエストパラメータ（indices, renamePattern, includeGlobalState等）の定義 |
| 1-2 | RestoreSnapshotResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/RestoreSnapshotResponse.java` | レスポンス構造（RestoreInfo） |
| 1-3 | RestoreInfo.java | `server/src/main/java/org/opensearch/snapshots/RestoreInfo.java` | リストア結果情報（スナップショット名、インデックス一覧、シャード統計） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestRestoreSnapshotAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestRestoreSnapshotAction.java` | ルーティング定義（60行目）とリクエスト解析（69-77行目） |

**主要処理フロー**:
1. **60行目**: `POST /_snapshot/{repository}/{snapshot}/_restore` のルーティング定義
2. **70行目**: RestoreSnapshotRequestを生成（repository, snapshot指定）
3. **75行目**: wait_for_completionパラメータを設定（デフォルトfalse）
4. **76行目**: リクエストボディからリストアオプションを読み取り（source()メソッド）
5. **77行目**: NodeClient経由でrestoreSnapshotアクションを実行

#### Step 3: Transport層・サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportRestoreSnapshotAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/TransportRestoreSnapshotAction.java` | RestoreServiceへの委譲 |
| 3-2 | RestoreService.java | `server/src/main/java/org/opensearch/snapshots/RestoreService.java` | リストアのコアロジック（インデックス作成、シャードリカバリ開始） |

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

```
RestRestoreSnapshotAction#prepareRequest()
    |
    +-- NodeClient#admin().cluster().restoreSnapshot()
            |
            +-- TransportRestoreSnapshotAction#clusterManagerOperation()
                    |
                    +-- RestoreService#restoreSnapshot()
                            |
                            +-- Repository#getSnapshotInfo()
                            |       (スナップショットメタデータ読み取り)
                            |
                            +-- ClusterState更新
                            |       (IndexMetadata/RoutingTable作成)
                            |
                            +-- RestoreClusterStateListener
                                    (リストア完了監視)
```

### データフロー図

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

POST /_snapshot/           RestRestoreSnapshotAction       RestoreSnapshotResponse
  /{repository}/           (パラメータ+ボディ解析)            (JSON)
  /{snapshot}/_restore           |
                                 v
Body: {                    TransportRestoreSnapshotAction
  "indices": "...",        (クラスタマネージャノード)
  "rename_pattern": "...",       |
  ...                            v
}                          RestoreService
                           (リストアロジック)
                                 |
                    +------------+------------+
                    |            |            |
              メタデータ読取  ClusterState更新  シャードリカバリ
              (Repository)   (IndexMetadata)   (データノード)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestRestoreSnapshotAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestRestoreSnapshotAction.java` | ソース | RESTハンドラ |
| TransportRestoreSnapshotAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/TransportRestoreSnapshotAction.java` | ソース | Transportアクション |
| RestoreSnapshotRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/RestoreSnapshotRequest.java` | ソース | リクエストモデル |
| RestoreSnapshotResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/restore/RestoreSnapshotResponse.java` | ソース | レスポンスモデル |
| RestoreService.java | `server/src/main/java/org/opensearch/snapshots/RestoreService.java` | ソース | リストアコアロジック |
| RestoreInfo.java | `server/src/main/java/org/opensearch/snapshots/RestoreInfo.java` | ソース | リストア結果データクラス |
| snapshot.restore.json | `rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.restore.json` | API定義 | REST API仕様定義 |
