# 画面設計書 129-Danglingインデックスインポート

## 概要

本ドキュメントは、OpenSearchのDanglingインデックスインポートAPI（POST /_dangling/{index_uuid}）の画面設計書である。指定されたDanglingインデックスをクラスタ状態にインポート（復旧）するREST APIエンドポイントの仕様を定義する。

### 本画面の処理概要

**業務上の目的・背景**：Danglingインデックスはノードのローカルディスクに存在するがクラスタ状態に登録されていないインデックスである。ノードの再参加やクラスタ状態の不整合により発生する。データの復旧が必要な場合、Danglingインデックスをクラスタにインポートしてデータを復元する。本APIはデータロスを防ぐために重要な復旧操作を提供するが、潜在的なデータ損失のリスクを伴うため、accept_data_loss=trueの明示的な同意が必要である。

**画面へのアクセス方法**：REST APIクライアントから `POST /_dangling/{index_uuid}?accept_data_loss=true` エンドポイントにHTTP POSTリクエストを送信してアクセスする。事前にDanglingインデックス一覧API（GET /_dangling）でUUIDを確認する。

**主要な操作・処理内容**：
1. クライアントがDanglingインデックスのUUIDとaccept_data_loss=trueを指定してPOSTリクエストを送信する
2. FindDanglingIndexActionで全ノードからDanglingインデックスを検索する
3. 最も新しいメタデータ（最大バージョン）を持つノードのインデックスメタデータを選択する
4. LocalAllocateDangledIndicesを使用してインデックスをクラスタ状態に割り当てる
5. インポート完了後、インデックスがクラスタで利用可能になる

**画面遷移**：Danglingインデックス一覧（GET /_dangling）でUUIDを確認し、本APIでインポートを実行する。インポート後はインデックス情報取得（GET /{index}）でインデックスの状態を確認する。

**権限による表示制御**：クラスタレベルの管理権限が必要。データ損失の可能性があるため、accept_data_lossパラメータの明示的な指定が必須。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | インデックス作成 | 主機能 | 指定したDanglingインデックスをインポートする処理 |

## 画面種別

登録（REST API - データインポート）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| POST | `/_dangling/{index_uuid}` | 指定したDanglingインデックスをインポート |

## 入出力項目

### パスパラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| index_uuid | string | Yes | DanglingインデックスのUUID |

### クエリパラメータ

| 項目名 | 型 | 必須 | デフォルト | 説明 |
|--------|------|------|-----------|------|
| accept_data_loss | boolean | Yes | false | データ損失を許容するか。trueに設定しないとインポート不可 |
| timeout | time | No | 30s | 操作タイムアウト |
| cluster_manager_timeout | time | No | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | No | 30s | （非推奨）cluster_manager_timeout を使用すること |

## 表示項目

### レスポンスボディ

| 項目名 | 型 | 説明 |
|--------|------|------|
| acknowledged | boolean | リクエストが受理されたかどうか |

## イベント仕様

### 1-Danglingインデックスインポートリクエスト

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

1. RestImportDanglingIndexActionがリクエストパラメータを解析し、ImportDanglingIndexRequestを生成する（index_uuid, accept_data_loss）
2. timeout、cluster_manager_timeoutパラメータを設定する
3. TransportImportDanglingIndexAction（HandledTransportAction）が実行される
4. FindDanglingIndexActionを使用して全ノードからUUIDに一致するDanglingインデックスを検索する
5. 複数ノードで見つかった場合、最大バージョンのメタデータを選択する
6. accept_data_loss=falseの場合はエラーを返却する
7. LocalAllocateDangledIndicesを使用してインデックスをクラスタ状態に割り当てる
8. 成功時にHTTP 202 Acceptedで応答する

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| POST リクエスト | クラスタ状態（Metadata） | INSERT | Danglingインデックスのメタデータをクラスタ状態に追加 |
| POST リクエスト | クラスタ状態（RoutingTable） | INSERT | インデックスのシャードルーティング情報を追加 |

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

#### クラスタ状態

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| INSERT | IndexMetadata | Danglingインデックスから復元したメタデータ（最大バージョン） | 複数ノードに存在する場合は最新を選択 |
| INSERT | RoutingTable | インデックスのシャードルーティング | INITIALIZING状態で作成 |

## メッセージ仕様

| HTTPステータス | 条件 | メッセージ例 |
|---------------|------|-------------|
| 202 Accepted | インポート受理 | `{"acknowledged": true}` |
| 400 Bad Request | accept_data_loss=falseまたは未指定 | `must accept data loss` |
| 404 Not Found | 指定UUIDのDanglingインデックスが見つからない | Danglingインデックスが存在しない |
| 500 Internal Server Error | インポート処理中のエラー | 内部エラー |

## 例外処理

| 例外 | 条件 | 対処 |
|------|------|------|
| IllegalArgumentException | accept_data_loss=falseまたは未指定 | 400を返却 |
| OpenSearchException | Danglingインデックスが見つからない | 404を返却 |
| FailedNodeException | ノード通信失敗 | エラー情報をログに記録し処理継続 |

## 備考

- accept_data_loss=trueの指定は必須。これはデータ損失のリスクがあることをユーザーが明示的に了承するためのセーフティガードである
- HTTPレスポンスは202 Accepted（通常の200 OKではない）で返却される
- 複数ノードに同一UUIDのDanglingインデックスが存在する場合、最も新しいメタデータバージョンを持つノードのものが採用される
- TransportImportDanglingIndexActionはHandledTransportAction（TransportClusterManagerNodeActionではない）を継承しており、任意のノードで実行される
- `master_timeout` パラメータはバージョン2.0.0で非推奨

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ImportDanglingIndexRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/import_index/ImportDanglingIndexRequest.java` | リクエストパラメータ（indexUUID, acceptDataLoss）の定義 |
| 1-2 | DanglingIndexInfo.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/DanglingIndexInfo.java` | Danglingインデックス情報構造 |

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

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

**主要処理フロー**:
1. **61行目**: `POST /_dangling/{index_uuid}` のルーティング定義
2. **71-74行目**: ImportDanglingIndexRequestを生成（index_uuid, accept_data_loss）
3. **76-78行目**: timeout、cluster_manager_timeoutを設定
4. **80-87行目**: NodeClient経由でimportDanglingIndexアクションを実行。レスポンスステータスは202 ACCEPTED

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportImportDanglingIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java` | HandledTransportActionを継承。FindDanglingIndexActionでUUIDを検索し、LocalAllocateDangledIndicesでクラスタに割り当て |

#### Step 4: Danglingインデックス検索と割り当てを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | FindDanglingIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/find/FindDanglingIndexAction.java` | UUID指定でDanglingインデックスを全ノードから検索 |
| 4-2 | LocalAllocateDangledIndices.java | `server/src/main/java/org/opensearch/gateway/LocalAllocateDangledIndices.java` | Danglingインデックスのクラスタ状態への割り当て |

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

```
RestImportDanglingIndexAction#prepareRequest()
    |
    +-- NodeClient#admin().cluster().importDanglingIndex()
            |
            +-- TransportImportDanglingIndexAction#doExecute()
                    |
                    +-- FindDanglingIndexAction (全ノードからUUID検索)
                    |       |
                    |       +-- 各ノード: DanglingIndicesState
                    |
                    +-- accept_data_lossチェック
                    |
                    +-- 最大バージョンのメタデータ選択
                    |
                    +-- LocalAllocateDangledIndices#allocateDangled()
                            |
                            +-- ClusterState更新タスク投入
                                    (IndexMetadata + RoutingTable追加)
```

### データフロー図

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

POST /_dangling/           RestImportDanglingIndexAction    AcknowledgedResponse
  {index_uuid}             (パラメータ解析)                    (HTTP 202)
  ?accept_data_loss=true          |                          {"acknowledged": true}
                                  v
                        TransportImportDanglingIndexAction
                                  |
                        FindDanglingIndexAction
                        (全ノードからUUID検索)
                                  |
                        IndexMetadata選択
                        (最大バージョン)
                                  |
                        LocalAllocateDangledIndices
                        (クラスタ状態に割り当て)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestImportDanglingIndexAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/dangling/RestImportDanglingIndexAction.java` | ソース | RESTハンドラ |
| TransportImportDanglingIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/import_index/TransportImportDanglingIndexAction.java` | ソース | Transportアクション |
| ImportDanglingIndexRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/import_index/ImportDanglingIndexRequest.java` | ソース | リクエストモデル |
| FindDanglingIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/dangling/find/FindDanglingIndexAction.java` | ソース | UUID検索アクション |
| LocalAllocateDangledIndices.java | `server/src/main/java/org/opensearch/gateway/LocalAllocateDangledIndices.java` | ソース | Danglingインデックス割り当て |
| DanglingIndicesState.java | `server/src/main/java/org/opensearch/gateway/DanglingIndicesState.java` | ソース | Danglingインデックス状態管理 |
| dangling_indices.import_dangling_index.json | `rest-api-spec/src/main/resources/rest-api-spec/api/dangling_indices.import_dangling_index.json` | API定義 | REST API仕様定義 |
