# 機能設計書 37-インジェスト共通プロセッサ

## 概要

本ドキュメントは、OpenSearchのインジェスト共通プロセッサ機能の設計を記述する。Grok、Rename、Set、Remove、Convert等の標準インジェストプロセッサ群を提供するモジュールである。

### 本機能の処理概要

インジェスト共通プロセッサは、ドキュメントの前処理で頻繁に利用される標準的なデータ変換プロセッサ群を提供する。テキストパターンマッチング（Grok）、フィールド名変更（Rename）、値の設定（Set）、フィールド削除（Remove）、型変換（Convert）、日付パース（Date）、文字列操作（Lowercase, Uppercase, Trim）等、約30種類のプロセッサを含む。

**業務上の目的・背景**：ドキュメントの前処理において共通的に必要となるデータ変換操作をプラグインなしで利用可能にする。ログデータの構造化解析（Grok, Dissect）、フィールドの正規化、データ型変換等の基本的なETL操作を標準で提供。

**機能の利用シーン**：インジェストパイプラインのprocessors配列内で各プロセッサタイプを指定して利用する。複数のプロセッサを組み合わせてパイプラインを構成する。

**主要な処理内容**：
1. IngestCommonModulePluginでプロセッサファクトリを登録
2. パイプライン定義時にファクトリがプロセッサインスタンスを生成
3. ドキュメント処理時にIngestDocument上で各種変換を実行
4. プロセッサ許可リスト（PROCESSORS_ALLOWLIST_SETTING）による制御

**関連システム・外部連携**：Grokパターンライブラリ。MatcherWatchdogによるGrok実行タイムアウト制御。

**権限による制御**：インジェストパイプラインの管理権限に従う。プロセッサ許可リスト設定でノードレベルの制御が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 134 | パイプラインシミュレーション | 補助機能 | シミュレーション時の各プロセッサ実行処理 |
| 135 | Grokパターン一覧 | 主機能 | 組み込みGrokパターンの一覧を返す処理 |

## 機能種別

データ連携（データ変換プロセッサ群）

## 入力仕様

### 入力パラメータ

主要プロセッサ共通パラメータ：

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tag | String | No | プロセッサのタグ（識別子） | - |
| description | String | No | プロセッサの説明 | - |
| if | String | No | 条件式（Painlessスクリプト） | 有効なスクリプト |
| ignore_failure | Boolean | No | エラー時に無視するか（デフォルトfalse） | - |
| on_failure | Array | No | エラー時のフォールバックプロセッサ | - |

代表的なプロセッサの個別パラメータ：

| プロセッサ | パラメータ名 | 型 | 必須 | 説明 |
|-----------|-------------|-----|-----|------|
| grok | field | String | Yes | パターンマッチ対象フィールド |
| grok | patterns | String[] | Yes | Grokパターン配列 |
| rename | field | String | Yes | 変更元フィールド |
| rename | target_field | String | Yes | 変更先フィールド |
| set | field | String | Yes | 設定先フィールド |
| set | value | Object | Yes | 設定する値 |
| remove | field | String/String[] | Yes | 削除するフィールド |
| convert | field | String | Yes | 変換対象フィールド |
| convert | type | String | Yes | 変換先型（integer, long, float, double, string, boolean, auto） |
| date | field | String | Yes | 日付パース対象フィールド |
| date | formats | String[] | Yes | 日付フォーマット配列 |
| script | source | String | Yes | Painlessスクリプト |

### 入力データソース

インジェストパイプライン定義内のプロセッサ設定。IngestDocumentのフィールド値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IngestDocument | Object | 変換後のドキュメント（フィールド追加・変更・削除済み） |

### 出力先

IngestDocumentへのインプレース変更。パイプライン処理後にインデックスへ格納。

## 処理フロー

### 処理シーケンス

```
1. IngestCommonModulePlugin.getProcessors()でファクトリ登録
   └─ 約30種類のプロセッサファクトリを返却
2. パイプライン定義時
   └─ ファクトリのcreate()でプロセッサインスタンスを生成
3. ドキュメント処理時
   └─ Processor.execute(IngestDocument)で変換処理を実行
4. 各プロセッサの処理内容
   └─ IngestDocumentのフィールド値を読取・変換・書込
```

### フローチャート

```mermaid
flowchart TD
    A[IngestDocument受信] --> B[プロセッサタイプ判定]
    B --> C{Grok?}
    C -->|Yes| D[パターンマッチング]
    C -->|No| E{Rename?}
    E -->|Yes| F[フィールド名変更]
    E -->|No| G{Set?}
    G -->|Yes| H[値設定]
    G -->|No| I{Convert?}
    I -->|Yes| J[型変換]
    I -->|No| K[その他プロセッサ]
    D --> L[IngestDocument更新]
    F --> L
    H --> L
    J --> L
    K --> L
    L --> M[次のプロセッサへ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | プロセッサ許可リスト | ingest.common.processors.allowedで利用可能なプロセッサを制限 | ノード設定 |
| BR-37-02 | Grokウォッチドッグ | ingest.grok.watchdog.max_execution_timeでGrokタイムアウトを制御 | Grokプロセッサ |
| BR-37-03 | Grokウォッチドッグ間隔 | ingest.grok.watchdog.intervalでチェック間隔を設定（デフォルト1秒） | Grokプロセッサ |
| BR-37-04 | ForEachプロセッサ | 配列フィールドの各要素に対してサブプロセッサを実行 | ForEachプロセッサ |

### 計算ロジック

- **Grok**: 正規表現ベースのパターンマッチング。名前付きキャプチャグループでフィールドを抽出
- **Convert**: Java型変換（Integer.parseInt, Double.parseDouble等）
- **Date**: Java DateTimeFormatterによる日付文字列パース
- **Fingerprint**: SHA-256等のハッシュアルゴリズムによるドキュメントフィンガープリント

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロセッサ実行 | なし（インメモリ） | 変換 | IngestDocumentに対するインプレース変換 |

### テーブル別操作詳細

プロセッサはIngestDocumentに対してインメモリで変換処理を行うため、直接的なデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 500 | ingest_process_exception | プロセッサ実行時のエラー | on_failureで処理またはignore_failureをtrue |
| 400 | illegal_argument_exception | プロセッサパラメータ不正 | 正しいパラメータを指定 |
| 500 | timeout_exception | Grokパターンマッチがタイムアウト | パターンを最適化 |

### リトライ仕様

プロセッサのエラーはon_failureハンドラで処理。ignore_failure=trueでエラーを無視して次のプロセッサへ進行可能。

## トランザクション仕様

IngestDocument単位での処理。各プロセッサはIngestDocumentを直接変更するため、エラー時のロールバックはon_failureハンドラで対応。

## パフォーマンス要件

- Grokプロセッサは正規表現のバックトラッキングにより高コストになりうる（ウォッチドッグで制御）
- ScriptプロセッサはPainlessスクリプトのコンパイルキャッシュを活用
- 文字列操作プロセッサ（Lowercase, Uppercase, Trim等）は低コスト

## セキュリティ考慮事項

- ScriptプロセッサのPainlessスクリプト実行にはスクリプト権限が必要
- プロセッサ許可リストでノードレベルでプロセッサを制限可能

## 備考

- 提供されるプロセッサ一覧：Append, Bytes, CommunityId, Convert, Copy, Csv, Date, DateIndexName, Dissect, DotExpander, Drop, Fail, Fingerprint, ForEach, Grok, Gsub, HierarchicalRouting, HtmlStrip, Join, Json, KeyValue, Lowercase, Pipeline, AclRouting, Remove, RemoveByPattern, Rename, Script, Set, Sort, Split, TemporalRouting, Trim, Uppercase, URLDecode

---

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

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

### 推奨読解順序

#### Step 1: モジュールプラグイン登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IngestCommonModulePlugin.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/IngestCommonModulePlugin.java` | モジュールプラグイン。getProcessors()で全プロセッサファクトリを返却 |

**読解のコツ**: getProcessors()メソッドがプロセッサ名→ファクトリのマッピングを返す。PROCESSORS_ALLOWLIST_SETTINGで許可リスト制御。WATCHDOG_INTERVAL, WATCHDOG_MAX_EXECUTION_TIMEでGrokタイムアウト制御。

**主要処理フロー**:
- **66行目**: IngestCommonModulePluginクラス定義。Plugin, ActionPlugin, IngestPluginを実装
- **68-73行目**: PROCESSORS_ALLOWLIST_SETTING定義
- **75-79行目**: WATCHDOG_INTERVAL設定（デフォルト1秒）
- **80行目**: WATCHDOG_MAX_EXECUTION_TIME設定

#### Step 2: 代表的なプロセッサ（Grok）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GrokProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/GrokProcessor.java` | Grokプロセッサ。正規表現パターンマッチング |
| 2-2 | GrokProcessorGetAction.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/GrokProcessorGetAction.java` | Grokパターン一覧取得API |

#### Step 3: 基本的なフィールド操作プロセッサを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SetProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/SetProcessor.java` | フィールド値設定 |
| 3-2 | RemoveProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/RemoveProcessor.java` | フィールド削除 |
| 3-3 | RenameProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/RenameProcessor.java` | フィールド名変更 |
| 3-4 | ConvertProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/ConvertProcessor.java` | 型変換 |

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

```
IngestCommonModulePlugin
    |
    +-- getProcessors() -> Map<String, Processor.Factory>
          |
          +-- "grok" -> GrokProcessor.Factory
          +-- "set" -> SetProcessor.Factory
          +-- "remove" -> RemoveProcessor.Factory
          +-- "rename" -> RenameProcessor.Factory
          +-- "convert" -> ConvertProcessor.Factory
          +-- "date" -> DateProcessor.Factory
          +-- "lowercase" -> LowercaseProcessor.Factory
          +-- "uppercase" -> UppercaseProcessor.Factory
          +-- "trim" -> TrimProcessor.Factory
          +-- "join" -> JoinProcessor.Factory
          +-- "split" -> SplitProcessor.Factory
          +-- "sort" -> SortProcessor.Factory
          +-- "foreach" -> ForEachProcessor.Factory
          +-- "script" -> ScriptProcessor.Factory
          +-- ... (約30種類)

各Processor.Factory.create() -> Processor
    |
    +-- Processor.execute(IngestDocument)
          +-- IngestDocument.getFieldValue()
          +-- IngestDocument.setFieldValue()
          +-- IngestDocument.removeField()
```

### データフロー図

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

IngestDocument       +--> Processor.execute()
(フィールド値)       |
                     +--> [Grok] パターンマッチ → 新フィールド追加
                     +--> [Set] フィールド値設定
                     +--> [Remove] フィールド削除
                     +--> [Rename] フィールド名変更
                     +--> [Convert] 型変換
                     +--> [Date] 日付パース
                     +--> [Lowercase] 小文字変換
                     |
                     +--> 変換済みIngestDocument   +--> 次のプロセッサ
                                                       またはインデックス処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IngestCommonModulePlugin.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/IngestCommonModulePlugin.java` | ソース | モジュールプラグイン |
| GrokProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/GrokProcessor.java` | ソース | Grokプロセッサ |
| SetProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/SetProcessor.java` | ソース | 値設定プロセッサ |
| RemoveProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/RemoveProcessor.java` | ソース | フィールド削除プロセッサ |
| RenameProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/RenameProcessor.java` | ソース | リネームプロセッサ |
| ConvertProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/ConvertProcessor.java` | ソース | 型変換プロセッサ |
| DateProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/DateProcessor.java` | ソース | 日付プロセッサ |
| ForEachProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/ForEachProcessor.java` | ソース | ForEachプロセッサ |
| ScriptProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/ScriptProcessor.java` | ソース | スクリプトプロセッサ |
| DissectProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/DissectProcessor.java` | ソース | Dissectプロセッサ |
| CsvProcessor.java | `modules/ingest-common/src/main/java/org/opensearch/ingest/common/CsvProcessor.java` | ソース | CSVプロセッサ |
