# 画面設計書 45-インデックスクローン

## 概要

本ドキュメントは、OpenSearchのインデックスクローンAPI（PUT/POST /{index}/_clone/{target}）の設計仕様を記述する。

### 本画面の処理概要

本APIは、既存のインデックスを同一の設定・マッピング・データで新しいインデックスにクローンするためのエンドポイントである。

**業務上の目的・背景**：インデックスの完全なコピーを作成する必要がある場合に使用する。テスト環境の構築、データのバックアップ、インデックス設定の変更前のスナップショット作成などのユースケースがある。Reindex APIとは異なり、ファイルシステムレベルでのハードリンクを使用するため、高速かつストレージ効率が良い。クローン元のインデックスは読み取り専用（read_only）に設定されている必要がある。

**画面へのアクセス方法**：`PUT /{index}/_clone/{target}` または `POST /{index}/_clone/{target}` エンドポイントにHTTPリクエストを送信する。

**主要な操作・処理内容**：
1. クライアントがPUT/POSTリクエストでソースインデックス名とターゲットインデックス名を指定して送信する
2. RestResizeHandler.RestCloneIndexAction がリクエストを処理し、ResizeRequestを構築する
3. ResizeType.CLONEが設定される
4. オプションでリクエストボディにsettingsとaliasesを指定可能
5. クラスタマネージャノードでクローン処理が実行される
6. 非同期実行（wait_for_completion=false）の場合、タスクIDが即時返却される
7. 処理結果（acknowledged, shards_acknowledged, index）をレスポンスとして返す

**画面遷移**：インデックス作成（PUT /{index}）で作成されたインデックスをクローンする。クローン先は新しいインデックスとして作成される。前提条件として、ソースインデックスにread_onlyブロック（PUT /{index}/_block/read_only）が設定されている必要がある。

**権限による表示制御**：インデックスの管理権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | インデックス作成 | 主機能 | インデックスをクローンする処理 |
| 56 | シャードアロケーション | 補助機能 | クローン時のシャード配置処理 |

## 画面種別

実行（インデックスクローン作成）

## URL/ルーティング

| メソッド | パス | 説明 |
|----------|------|------|
| PUT | `/{index}/_clone/{target}` | インデックスのクローン |
| POST | `/{index}/_clone/{target}` | インデックスのクローン |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | string | はい | ソースインデックス名 |
| target | string | はい | ターゲットインデックス名 |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| timeout | time | 30s | 操作タイムアウト |
| cluster_manager_timeout | time | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | - | 非推奨（cluster_manager_timeoutを使用） |
| wait_for_active_shards | string | - | アクティブシャードの待機数 |
| wait_for_completion | boolean | true | falseの場合、タスクを即時返却しバックグラウンド実行 |
| task_execution_timeout | time | 1h | タスク実行タイムアウト（wait_for_completion=false時のみ有効） |

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

| フィールド | 型 | 説明 |
|-----------|------|------|
| settings | object | ターゲットインデックスの設定 |
| aliases | object | ターゲットインデックスのエイリアス |

## 表示項目

### 同期レスポンス（wait_for_completion=true）

| 項目名 | 型 | 説明 |
|--------|------|------|
| acknowledged | boolean | クラスタ状態の更新が認識されたか |
| shards_acknowledged | boolean | 指定数のシャードコピーが開始されたか |
| index | string | 作成されたインデックス名 |

### 非同期レスポンス（wait_for_completion=false）

| 項目名 | 型 | 説明 |
|--------|------|------|
| task | string | タスクID |

## イベント仕様

### 1-インデックスクローンリクエスト送信（同期）

RestResizeHandler.prepareRequest()（77-131行目）がリクエストを処理する。ResizeRequestを構築し、ResizeType.CLONEを設定する。リクエストボディからsettings/aliasesを解析し、パラメータ（timeout、cluster_manager_timeout、wait_for_active_shards）を設定する。wait_for_completionがtrue（デフォルト）の場合、client.admin().indices().resizeIndex()を呼び出す。

### 2-インデックスクローンリクエスト送信（非同期）

wait_for_completion=falseの場合（110-130行目）、setShouldStoreResult(true)を設定し、task_execution_timeout（デフォルト1h）をタイムアウトとして設定後、タスクとして非同期実行する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| PUT /{index}/_clone/{target} | ClusterState（メモリ） | INSERT | 新しいインデックスメタデータをクラスタ状態に追加 |

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

#### ClusterState.metadata.indices

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | IndexMetadata | ソースインデックスの設定・マッピングをコピーした新インデックス | ターゲット名で新規作成 |

## メッセージ仕様

| メッセージ種別 | 条件 | HTTPステータス | 内容 |
|--------------|------|---------------|------|
| 成功 | クローンが完了 | 200 | {"acknowledged": true, "shards_acknowledged": true, "index": "target_name"} |
| 成功（タスク） | 非同期実行開始 | 200 | {"task": "node_id:task_id"} |
| エラー | ソースインデックスが読み取り専用でない | 400 | illegal_state_exception |
| エラー | ターゲットインデックスが既に存在 | 400 | resource_already_exists_exception |

## 例外処理

| 例外 | 条件 | 動作 |
|------|------|------|
| IndexNotFoundException | ソースインデックスが存在しない | 404エラーを返す |
| IllegalStateException | ソースインデックスが読み取り専用でない | 400エラーを返す |
| ResourceAlreadyExistsException | ターゲットインデックスが既に存在 | 400エラーを返す |
| IllegalArgumentException | copy_settingsにfalseを明示的に設定 | 400エラーを返す |

## 備考

- ソースインデックスは事前にread_onlyブロックが設定されている必要がある。
- RestResizeHandlerは共通の抽象クラスで、クローン・縮小・分割の3つのリサイズ操作を処理する。
- copy_settingsパラメータは非推奨（3.0.0で削除予定）で、明示的にfalseを設定するとエラーとなる（92行目）。
- クローンはファイルシステムレベルのハードリンクを使用するため、Reindexより高速である。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ResizeRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeRequest.java` | resizeType、targetIndex、copySettings等のフィールドを確認 |
| 1-2 | ResizeType.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeType.java` | SHRINK, SPLIT, CLONE の列挙値を確認 |
| 1-3 | ResizeResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeResponse.java` | acknowledged, shards_acknowledged, indexのレスポンス構造を確認 |

**読解のコツ**: ResizeRequestは CreateIndexRequest をターゲットインデックス用に内包しており、settingsとaliasesの設定はこのCreateIndexRequestに適用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestResizeHandler.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestResizeHandler.java` | 186-203行目: RestCloneIndexAction内部クラスの定義 |

**主要処理フロー**:
1. **189-190行目**: `PUT/POST /{index}/_clone/{target}` のルート登録
2. **199-200行目**: getResizeType()がResizeType.CLONEを返す
3. **77-131行目**: 共通のprepareRequest()でResizeRequestを構築
4. **78行目**: ResizeRequest(target, index)でターゲットとソースを設定
5. **79行目**: setResizeType(CLONE)でリサイズ種別を設定
6. **101行目**: リクエストボディのパース（settings, aliases）
7. **108-130行目**: 同期/非同期実行の分岐

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportResizeAction.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/TransportResizeAction.java` | リサイズ処理の共通ロジック |

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

```
RestResizeHandler.RestCloneIndexAction
    |
    +-- RestResizeHandler.prepareRequest()
            |
            +-- ResizeRequest(target, index)
            +-- setResizeType(ResizeType.CLONE)
            +-- request.applyContentParser(resizeRequest::fromXContent)
            |
            +-- [wait_for_completion=true]
            |       +-- NodeClient.admin().indices().resizeIndex()
            |               +-- TransportResizeAction
            |
            +-- [wait_for_completion=false]
                    +-- NodeClient.executeLocally(ResizeAction.INSTANCE, ...)
                            +-- TransportResizeAction（タスクとして実行）
```

### データフロー図

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

PUT /{index}/_clone/{target}   RestResizeHandler.RestCloneIndexAction  JSON レスポンス
  +                                  |                                {acknowledged: true,
  ソースindex名                 ResizeRequest構築                       shards_acknowledged: true,
  ターゲットindex名             (type=CLONE)                            index: "target"}
  settings(任意)                      |                                    or
  aliases(任意)                TransportResizeAction                    {task: "id"}
                                     |
                              クローン処理実行
                                     |
                              新インデックス作成（ハードリンク）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| indices.clone.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.clone.json` | API定義 | REST APIスペック定義 |
| RestResizeHandler.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestResizeHandler.java` | ソース | RESTハンドラ（共通基底 + RestCloneIndexAction内部クラス） |
| ResizeRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeRequest.java` | ソース | リクエストデータ構造 |
| ResizeType.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeType.java` | ソース | リサイズ種別列挙型 |
| ResizeAction.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeAction.java` | ソース | アクション定義 |
| TransportResizeAction.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/TransportResizeAction.java` | ソース | Transport層処理 |
