# 画面設計書 134-パイプラインシミュレーション

## 概要

本ドキュメントは、OpenSearchのIngestパイプラインシミュレーションAPI（`GET/POST /_ingest/pipeline/_simulate`）の画面設計書である。サンプルドキュメントを使用してパイプラインの動作を事前にテストするためのREST APIエンドポイントの仕様を定義する。

### 本画面の処理概要

本APIは、サンプルドキュメントに対してインジェストパイプラインの処理をシミュレーション実行し、各プロセッサの処理結果を返却するエンドポイントである。実際のインデックスへの登録は行わず、パイプラインの動作検証を安全に行うことができる。

**業務上の目的・背景**：インジェストパイプラインを本番環境に適用する前に、サンプルデータで動作を確認することは品質保証において不可欠である。特にGrokプロセッサによるログパース、日付変換、スクリプトプロセッサなどの複雑な変換ロジックを含むパイプラインでは、シミュレーションによる事前検証が運用ミスの防止に貢献する。

**画面へのアクセス方法**：HTTPクライアントから `GET/POST /_ingest/pipeline/_simulate` または `GET/POST /_ingest/pipeline/{id}/_simulate` へサンプルドキュメントを含むリクエストボディとともに送信する。

**主要な操作・処理内容**：
1. クライアントがパイプラインID（任意）とサンプルドキュメントを含むリクエストを送信する
2. RestSimulatePipelineActionがリクエストを受け取り、SimulatePipelineRequestを構築する
3. 指定パイプライン（またはリクエストボディ内で定義されたパイプライン）を使用してサンプルドキュメントを処理する
4. 各プロセッサの処理結果をJSON形式でレスポンスとして返却する

**画面遷移**：パイプライン作成・更新API（132）で作成したパイプラインの動作を本APIで検証する。Grokパターン一覧API（135）で利用可能なGrokパターンを確認した上でシミュレーションを行うケースもある。

**権限による表示制御**：クラスタのインジェストパイプライン管理権限が必要。権限不足の場合は403エラーが返却される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | インジェストパイプライン | 主機能 | サンプルドキュメントでパイプラインの処理結果をシミュレーションする処理 |
| 37 | インジェスト共通プロセッサ | 補助機能 | シミュレーション時の各プロセッサ実行処理 |

## 画面種別

実行（REST API GET/POSTエンドポイント）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_ingest/pipeline/_simulate` | パイプラインをシミュレーション（ボディ内にパイプライン定義を含む） |
| POST | `/_ingest/pipeline/_simulate` | パイプラインをシミュレーション（ボディ内にパイプライン定義を含む） |
| GET | `/_ingest/pipeline/{id}/_simulate` | 既存パイプラインでシミュレーション |
| POST | `/_ingest/pipeline/{id}/_simulate` | 既存パイプラインでシミュレーション |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| id | string | いいえ | パイプラインID（省略時はリクエストボディ内にパイプライン定義が必要） |

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|-----|------|-----------|------|
| verbose | boolean | いいえ | false | 各プロセッサの出力データを表示するか |

### リクエストボディ（必須）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| pipeline | object | 条件付き | パイプライン定義（IDが指定されていない場合は必須） |
| docs | array | はい | シミュレーション対象のサンプルドキュメント配列 |
| docs[]._index | string | いいえ | ドキュメントのインデックス名 |
| docs[]._id | string | いいえ | ドキュメントID |
| docs[]._source | object | はい | ドキュメントのソースデータ |

## 表示項目

### レスポンスボディ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| docs | array | シミュレーション結果の配列 |
| docs[].doc | object | 処理後のドキュメント |
| docs[].doc._index | string | インデックス名 |
| docs[].doc._id | string | ドキュメントID |
| docs[].doc._source | object | 処理後のソースデータ |
| docs[].doc._ingest | object | インジェストメタデータ（タイムスタンプ等） |
| docs[].processor_results | array | verbose=true時の各プロセッサの処理結果 |

## イベント仕様

### 1-パイプラインシミュレーションリクエスト

クライアントからGET/POSTリクエストを受信すると、RestSimulatePipelineActionの`prepareRequest`メソッドが呼び出される。リクエストボディからコンテンツとメディアタイプを抽出し、SimulatePipelineRequestオブジェクトを生成する。パスパラメータ`id`とクエリパラメータ`verbose`を設定した後、`client.admin().cluster().simulatePipeline()`を呼び出す。シミュレーション実行エンジンは、指定されたパイプラインの各プロセッサをサンプルドキュメントに順次適用し、verbose=trueの場合は各ステップの中間結果も収集する。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| パイプラインシミュレーション | なし | なし | シミュレーション専用のためデータ更新は発生しない |

## メッセージ仕様

| メッセージID | メッセージ内容 | 種別 | 発生条件 |
|-------------|--------------|------|---------|
| 200 | シミュレーション結果のJSONレスポンス | 成功 | シミュレーションが正常に完了した場合 |
| 400 | リクエスト形式不正 | エラー | リクエストボディの構造が不正な場合 |
| 404 | パイプラインが見つからない | エラー | 指定IDのパイプラインが存在しない場合 |

## 例外処理

- **パイプラインが存在しない場合**: IDを指定したが対応するパイプラインがクラスタ状態に存在しない場合、ResourceNotFoundExceptionがスローされる
- **不正なリクエストボディ**: docsフィールドが欠如している場合やパイプライン定義が不正な場合、パースエラーが返却される
- **プロセッサ実行エラー**: シミュレーション中にプロセッサでエラーが発生した場合、エラー情報がレスポンスに含まれる（on_failureハンドラがある場合はそちらが実行される）

## 備考

- `verbose` パラメータをtrueに設定すると、各プロセッサの入力・出力データが詳細に表示されるため、デバッグに有用
- パイプラインIDを指定しない場合、リクエストボディ内にパイプライン定義を含める必要がある（アドホックシミュレーション）
- シミュレーション実行はインデックスへの実際の書き込みを伴わないため、安全にテストが可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SimulatePipelineRequest.java | `server/src/main/java/org/opensearch/action/ingest/SimulatePipelineRequest.java` | シミュレーションリクエストの構造。source, id, verboseフィールド |
| 1-2 | SimulatePipelineResponse.java | `server/src/main/java/org/opensearch/action/ingest/SimulatePipelineResponse.java` | シミュレーション結果のレスポンス構造 |
| 1-3 | SimulateDocumentResult.java | `server/src/main/java/org/opensearch/action/ingest/SimulateDocumentResult.java` | 個別ドキュメントのシミュレーション結果 |

**読解のコツ**: verboseモードとnon-verboseモードでレスポンス構造が異なる点に注意。

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

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

**主要処理フロー**:
1. **行61-68**: ルート定義 - 4パス（GET/POST x ID有無）を登録
2. **行78**: リクエストボディからコンテンツを取得
3. **行79**: SimulatePipelineRequest(source, mediaType)を生成
4. **行80**: パスパラメータ`id`を設定
5. **行81**: クエリパラメータ`verbose`を設定（デフォルト: false）
6. **行82**: `client.admin().cluster().simulatePipeline()` を呼び出し

#### Step 3: シミュレーション実行エンジンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SimulateExecutionService.java | `server/src/main/java/org/opensearch/action/ingest/SimulateExecutionService.java` | パイプラインシミュレーションの実行ロジック |

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

```
RestSimulatePipelineAction.prepareRequest()
    |
    +-- SimulatePipelineRequest(source, mediaType)
    |       +-- setId(id)
    |       +-- setVerbose(verbose)
    |
    +-- client.admin().cluster().simulatePipeline()
            |
            +-- SimulatePipelineTransportAction
                    |
                    +-- SimulateExecutionService.execute()
                            |
                            +-- Pipeline.execute() (各プロセッサを順次適用)
                            |       |
                            |       +-- Processor.execute() (個別プロセッサ)
                            |
                            +-- SimulatePipelineResponse -> JSONレスポンス
```

### データフロー図

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

POST /_ingest/pipeline/{id}/_simulate
    |
    +-- id (パスパラメータ)   --> RestSimulatePipelineAction         --> SimulatePipelineRequest
    +-- verbose               |                                           |
    +-- リクエストボディ             v                                           v
        {docs: [...]}        SimulateExecutionService              サンプルドキュメント処理
                                     |                                        |
                                     v                                        v
                              各Processor実行                       SimulatePipelineResponse
                                                                            |
                                                                            v
                                                                  {docs: [{doc: {...}}]}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestSimulatePipelineAction.java | `server/src/main/java/org/opensearch/rest/action/ingest/RestSimulatePipelineAction.java` | ソース | RESTエントリーポイント |
| SimulatePipelineRequest.java | `server/src/main/java/org/opensearch/action/ingest/SimulatePipelineRequest.java` | ソース | リクエストデータ構造 |
| SimulatePipelineResponse.java | `server/src/main/java/org/opensearch/action/ingest/SimulatePipelineResponse.java` | ソース | レスポンスデータ構造 |
| SimulateExecutionService.java | `server/src/main/java/org/opensearch/action/ingest/SimulateExecutionService.java` | ソース | シミュレーション実行サービス |
| SimulateDocumentResult.java | `server/src/main/java/org/opensearch/action/ingest/SimulateDocumentResult.java` | ソース | ドキュメント単位の結果 |
| IngestService.java | `server/src/main/java/org/opensearch/ingest/IngestService.java` | ソース | パイプライン管理サービス |
| ingest.simulate.json | `rest-api-spec/src/main/resources/rest-api-spec/api/ingest.simulate.json` | API仕様 | REST API仕様定義 |
