# 画面設計書 120-スナップショット作成

## 概要

本ドキュメントは、OpenSearchのスナップショット作成API（`PUT /_snapshot/{repository}/{snapshot}`）の画面設計書である。本APIは、指定リポジトリにクラスタデータのスナップショットを作成する。

### 本画面の処理概要

本APIは、OpenSearchクラスタのインデックスデータやクラスタ状態のバックアップスナップショットを作成するREST APIエンドポイントである。

**業務上の目的・背景**：データの保全と災害復旧（DR）のために、定期的なスナップショット取得が重要である。本APIにより、クラスタ全体または特定インデックスのデータをリポジトリに保存し、障害発生時に復元可能な状態を維持する。データマイグレーション、テスト環境の構築、本番データの保護など、多様な運用シナリオで利用される。

**画面へのアクセス方法**：HTTPクライアントから `PUT /_snapshot/{repository}/{snapshot}` または `POST /_snapshot/{repository}/{snapshot}` にリクエストを送信する。リクエストボディでスナップショットの範囲を指定できる。

**主要な操作・処理内容**：
1. クライアントからPUT/POSTリクエストを受信し、リポジトリ名、スナップショット名、定義をパースする
2. スナップショット対象のインデックスを決定する
3. 各シャードのデータをリポジトリにコピーする（インクリメンタル方式）
4. スナップショットメタデータをリポジトリに保存する
5. wait_for_completionに応じて即座に応答するか、完了まで待機する

**画面遷移**：リポジトリ作成API（`PUT /_snapshot/{repository}`）でリポジトリを用意した後に呼び出す。スナップショット取得API（`GET /_snapshot/{repository}/{snapshot}`）でスナップショットの状態を確認する。スナップショットリストアAPI（`POST /_snapshot/{repository}/{snapshot}/_restore`）でデータを復元する。

**権限による表示制御**：クラスタ管理権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 63 | スナップショット作成・管理 | 主機能 | リポジトリにスナップショットを作成する処理 |

## 画面種別

登録（スナップショット作成）

## URL/ルーティング

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

## 入出力項目

### パスパラメータ

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

### クエリパラメータ

| 項目名 | 型 | 必須 | デフォルト | 説明 |
|--------|-----|------|-----------|------|
| cluster_manager_timeout | time | いいえ | - | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | いいえ | - | （非推奨）cluster_manager_timeoutを使用 |
| wait_for_completion | boolean | いいえ | false | スナップショット完了を待つかどうか |

### リクエストボディ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| indices | string/array | いいえ | スナップショット対象のインデックス名（デフォルトは全インデックス） |
| ignore_unavailable | boolean | いいえ | 存在しないインデックスを無視するかどうか |
| include_global_state | boolean | いいえ | クラスタのグローバル状態を含めるかどうか |
| partial | boolean | いいえ | 一部シャードが利用不可でもスナップショットを作成するかどうか |

## 表示項目

### レスポンス（wait_for_completion=false の場合）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| accepted | boolean | スナップショット要求が受け入れられたか |

### レスポンス（wait_for_completion=true の場合）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| snapshot.snapshot | string | スナップショット名 |
| snapshot.uuid | string | スナップショットUUID |
| snapshot.version_id | integer | バージョンID |
| snapshot.version | string | バージョン文字列 |
| snapshot.indices | array | 含まれるインデックス一覧 |
| snapshot.state | string | スナップショットの状態（SUCCESS等） |
| snapshot.start_time | string | 開始日時 |
| snapshot.end_time | string | 終了日時 |
| snapshot.duration_in_millis | long | 所要時間（ミリ秒） |
| snapshot.shards.total | integer | 総シャード数 |
| snapshot.shards.successful | integer | 成功シャード数 |
| snapshot.shards.failed | integer | 失敗シャード数 |

## イベント仕様

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

1. クライアントがPUT/POSTリクエストを送信する
2. `RestCreateSnapshotAction.prepareRequest`がリクエストをパースし、`CreateSnapshotRequest`を生成する（行番号73-81）
3. リポジトリ名とスナップショット名を設定する（行番号74）
4. リクエストボディから`source`を設定する（行番号75）
5. `wait_for_completion`を設定する（行番号80）
6. `client.admin().cluster().createSnapshot`が呼び出される（行番号81）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| スナップショット作成 | ClusterState（メタデータ） | UPDATE | スナップショット進行状態をクラスタ状態に記録 |
| スナップショット作成 | リポジトリストレージ | INSERT | インデックスデータとメタデータをリポジトリに書き込み |

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

#### ClusterState メタデータ

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|----------------|------|
| UPDATE | SnapshotsInProgress | スナップショットの進行状態 | 作成中に一時記録 |

#### リポジトリストレージ

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|----------------|------|
| INSERT | スナップショットメタデータ | スナップショット名、インデックス一覧、状態 | snap-{uuid}.dat |
| INSERT | インデックスデータ | 各シャードのセグメントファイル | インクリメンタル方式 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 条件 |
|-------------|------|----------|------|
| - | 成功 | HTTP 200 OK + {"accepted": true} | wait_for_completion=false時の正常受付 |
| - | 成功 | HTTP 200 OK + スナップショット情報 | wait_for_completion=true時の正常完了 |
| - | エラー | リポジトリが見つからない | 指定名のリポジトリが存在しない場合 |
| - | エラー | スナップショット名が既に存在する | 同名のスナップショットが存在する場合 |

## 例外処理

| 例外条件 | HTTPステータス | 処理内容 |
|---------|--------------|---------|
| リポジトリが存在しない | 404 | RepositoryMissingException |
| 同名スナップショットが存在 | 400 | InvalidSnapshotNameException |
| 他のスナップショット操作が進行中 | 500 | ConcurrentSnapshotExecutionException |
| シャードの一部が利用不可（partial=false） | 500 | SnapshotException |

## 備考

- スナップショットはインクリメンタル方式であり、前回のスナップショットから変更されたセグメントのみが保存される
- `wait_for_completion=false`の場合、スナップショットはバックグラウンドで実行される
- `master_timeout`パラメータはv2.0.0で非推奨となり、`cluster_manager_timeout`に置き換えられた
- 大規模インデックスのスナップショットは長時間かかる可能性がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | snapshot.create.json | `rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.create.json` | APIのURL、パラメータ、ボディの定義を確認 |
| 1-2 | CreateSnapshotRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java` | リクエストの構造 |
| 1-3 | CreateSnapshotResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java` | レスポンスの構造 |

**読解のコツ**: `source(Map)`メソッドでリクエストボディの各フィールドがパースされる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestCreateSnapshotAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestCreateSnapshotAction.java` | RESTリクエストの受付 |

**主要処理フロー**:
1. **行番号62-63**: ルート定義（PUT/POST /_snapshot/{repository}/{snapshot}）
2. **行番号73-81**: リクエストパース処理とcreateSnapshot呼び出し

#### Step 3: Transport層の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportCreateSnapshotAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/TransportCreateSnapshotAction.java` | スナップショット作成処理 |
| 3-2 | SnapshotsService.java | `server/src/main/java/org/opensearch/snapshots/SnapshotsService.java` | スナップショット管理サービス |
| 3-3 | BlobStoreRepository.java | `server/src/main/java/org/opensearch/repositories/blobstore/BlobStoreRepository.java` | データ書き込み処理 |

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

```
RestCreateSnapshotAction.prepareRequest (行番号73)
    |
    +-- createSnapshotRequest(repository, snapshot) (行番号74)
    +-- source(p.mapOrdered()) (行番号75) -- ボディパース
    +-- waitForCompletion設定 (行番号80)
    |
    +-- client.admin().cluster().createSnapshot (行番号81)
            |
            +-- TransportCreateSnapshotAction.execute
                    |
                    +-- SnapshotsService.createSnapshot
                            |
                            +-- ClusterState更新（SnapshotsInProgress追加）
                            +-- BlobStoreRepository.snapshotShard（各シャード）
                                    |
                                    +-- セグメントファイルのコピー
                                    +-- メタデータの保存
```

### データフロー図

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

PUT /_snapshot/{repo}/{snap}    RestCreateSnapshotAction         JSON レスポンス
  repository (path)   -------->  CreateSnapshotRequest生成        accepted: true
  snapshot (path)                |                               または
  indices (body)                 v                               snapshot (詳細情報)
  wait_for (query)         TransportCreateSnapshotAction
                                 |
                                 v
                           SnapshotsService.createSnapshot
                                 |
                           +-----+-----+
                           |           |
                           v           v
                    ClusterState   BlobStoreRepository
                      更新           .snapshotShard
                                       |
                                       v
                                 リポジトリストレージ書き込み
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| snapshot.create.json | `rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.create.json` | API定義 | REST APIスペック定義 |
| RestCreateSnapshotAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestCreateSnapshotAction.java` | ソース | RESTリクエストハンドラ |
| TransportCreateSnapshotAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/TransportCreateSnapshotAction.java` | ソース | Transport層の作成処理 |
| CreateSnapshotRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java` | ソース | リクエストモデル |
| CreateSnapshotResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/snapshots/create/CreateSnapshotResponse.java` | ソース | レスポンスモデル |
| SnapshotsService.java | `server/src/main/java/org/opensearch/snapshots/SnapshotsService.java` | ソース | スナップショット管理サービス |
| BlobStoreRepository.java | `server/src/main/java/org/opensearch/repositories/blobstore/BlobStoreRepository.java` | ソース | BlobStoreリポジトリ実装 |
