# 機能設計書 96-プラグインフレームワーク

## 概要

本ドキュメントは、OpenSearchにおけるプラグインのロード・管理・ライフサイクル制御の基盤機能（Plugin Framework）の設計を記述する。

### 本機能の処理概要

プラグインフレームワークは、OpenSearchの機能を拡張するプラグインとモジュールのロード、初期化、ライフサイクル管理を行うための基盤機能を提供する。

**業務上の目的・背景**：OpenSearchは高い拡張性を持つ設計思想に基づいており、検索プラグイン、分析プラグイン、セキュリティプラグイン、クラウドプロバイダプラグインなど、多様な機能をプラグインとして追加できる。プラグインフレームワークはこの拡張性を実現するための核心的な基盤であり、サードパーティ開発者による機能追加も可能にする。

**機能の利用シーン**：ノード起動時にmodulesディレクトリとpluginsディレクトリからプラグインをロードする。また、各プラグインが提供する拡張ポイント（ActionPlugin、AnalysisPlugin、DiscoveryPlugin等）を通じて機能を登録する。

**主要な処理内容**：
1. プラグインディスカバリ - modules/pluginsディレクトリからプラグインJARを検出
2. プラグインローディング - ClassLoaderを通じたプラグインクラスのロード
3. プラグインの初期化 - コンストラクタを通じたプラグインインスタンスの生成
4. 拡張ポイントの収集 - 各種Pluginインターフェースから提供される設定・コンポーネントの収集
5. ライフサイクル管理 - createComponents()、onIndexModule()、close()の呼び出し

**関連システム・外部連携**：Node起動処理と密接に連携。Guice依存性注入フレームワークと統合されている。

**権限による制御**：プラグインのロード自体は管理者権限で行われる（ファイルシステムアクセス）。各プラグインが提供する機能の権限制御はプラグイン自身が担当する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 156 | Cat プラグイン | 主機能 | ノードにインストールされたプラグイン情報をテーブル形式で返す処理 |

## 機能種別

フレームワーク基盤（プラグイン管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| plugin.mandatory | List<String> | No | 必須プラグインのリスト | リスト内の全プラグインが存在すること |
| modulesDirectory | Path | No | モジュールのディレクトリパス | アクセス可能なディレクトリ |
| pluginsDirectory | Path | No | プラグインのディレクトリパス | アクセス可能なディレクトリ |

### 入力データソース

ファイルシステム上のmodules/pluginsディレクトリ。各プラグインのplugin-descriptor.propertiesファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PluginsAndModules | ReportingService | ロード済みプラグインとモジュールの情報 |
| pluginSettings | List<Setting<?>> | プラグインが提供する設定のリスト |
| pluginSettingsFilter | List<String> | プラグインが提供する設定フィルタ |

### 出力先

ノード情報API（Cat Plugins等）、各種設定モジュール。

## 処理フロー

### 処理シーケンス

```
1. PluginsService コンストラクタ
   └─ クラスパスプラグインのロード（テスト用）
2. モジュールのロード（modulesDirectory）
   └─ getModuleBundles()でモジュールBundleを取得
   └─ 各Bundleのプラグインを初期化
3. プラグインのロード（pluginsDirectory）
   └─ getPluginBundles()でプラグインBundleを取得
   └─ バージョン互換性チェック
   └─ JarHellチェック（クラスパス衝突検出）
4. 必須プラグインチェック
   └─ plugin.mandatoryで指定されたプラグインが全てロード済みか検証
5. 各プラグインの拡張ポイント収集
   └─ getSettings(), getNamedWriteables(), getNamedXContent()等
6. createComponents()呼び出し
   └─ プラグインが必要なコンポーネントを生成
```

### フローチャート

```mermaid
flowchart TD
    A[PluginsService生成] --> B[クラスパスプラグインロード]
    B --> C[モジュールディスカバリ]
    C --> D[モジュールロード]
    D --> E[プラグインディスカバリ]
    E --> F[プラグインロード]
    F --> G[バージョン互換性チェック]
    G --> H[JarHellチェック]
    H --> I[必須プラグインチェック]
    I --> J{全プラグインロード成功?}
    J -->|Yes| K[拡張ポイント収集]
    J -->|No| L[起動エラー]
    K --> M[PluginsService初期化完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-96-01 | モジュール優先 | modulesディレクトリのプラグインは常にロードされる | 常時 |
| BR-96-02 | 必須プラグイン | plugin.mandatoryで指定されたプラグインが不足する場合は起動エラー | plugin.mandatory設定時 |
| BR-96-03 | バージョン互換性 | プラグインのOpenSearchバージョン互換性を検証 | プラグインロード時 |
| BR-96-04 | JarHell検出 | クラスパスの衝突を検出してエラーを報告 | プラグインロード時 |
| BR-96-05 | プラグインインターフェース | Plugin基底クラスを継承し、各種インターフェースで拡張ポイントを提供 | プラグイン開発時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OpenSearchException | 起動エラー | 必須プラグインが見つからない | 必須プラグインをインストール |
| IllegalStateException | 互換性エラー | プラグインのバージョンが非互換 | 互換バージョンのプラグインを使用 |
| IOException | I/Oエラー | プラグインファイルの読み込み失敗 | ファイルパーミッションを確認 |
| ClassNotFoundException | ロードエラー | プラグインクラスが見つからない | プラグインのインストール状態を確認 |

### リトライ仕様

プラグインロードは起動時に1回のみ実行される。リトライ不要（ノード再起動が必要）。

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

該当なし。

## パフォーマンス要件

- ノード起動時のプラグインロード処理は起動時間に影響するため、効率的なスキャンが重要
- プラグイン数が増えるとクラスローダの初期化コストが増加する

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

- プラグインはJavaセキュリティマネージャの下で実行される
- プラグインJARの改ざん検出にはJarHellチェックが貢献
- プラグインのインストールは管理者権限で行う必要がある

## 備考

- Pluginクラスは@PublicApi(since = "1.0.0")としてマーク済み
- 主要な拡張インターフェース: ActionPlugin, AnalysisPlugin, ClusterPlugin, DiscoveryPlugin, IngestPlugin, MapperPlugin, NetworkPlugin, RepositoryPlugin, ScriptPlugin, SearchPlugin, ReloadablePlugin
- ExtensiblePluginインターフェースにより、プラグイン間の拡張も可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PluginInfo.java | `server/src/main/java/org/opensearch/plugins/PluginInfo.java` | プラグインのメタ情報（名前、バージョン、クラス名等） |
| 1-2 | Plugin.java | `server/src/main/java/org/opensearch/plugins/Plugin.java` | プラグインの基底クラス。拡張ポイントメソッドの定義 |

**読解のコツ**: Plugin.javaのJavadocコメント（77-89行目）に列挙された拡張インターフェースのリストが、プラグインで提供可能な機能カテゴリを網羅している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PluginsService.java | `server/src/main/java/org/opensearch/plugins/PluginsService.java` | プラグインのロード・管理サービス |

**主要処理フロー**:
1. **91行目**: PluginsService定義 - ReportingServiceを実装
2. **104-109行目**: MANDATORY_SETTING - 必須プラグイン設定
3. **126-154行目**: コンストラクタ（テスト用） - クラスパスプラグインロード
4. **164-192行目**: コンストラクタ（本番用） - モジュール・プラグインロード
5. **197-199行目**: モジュールディスカバリ - getModuleBundles()

#### Step 3: プラグイン拡張インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ActionPlugin.java | `server/src/main/java/org/opensearch/plugins/ActionPlugin.java` | REST/Transport Actionの拡張 |
| 3-2 | AnalysisPlugin.java | `server/src/main/java/org/opensearch/plugins/AnalysisPlugin.java` | テキスト解析の拡張 |
| 3-3 | DiscoveryPlugin.java | `server/src/main/java/org/opensearch/plugins/DiscoveryPlugin.java` | ノードディスカバリの拡張 |
| 3-4 | NetworkPlugin.java | `server/src/main/java/org/opensearch/plugins/NetworkPlugin.java` | ネットワークトランスポートの拡張 |

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

```
Node起動
    |
    +-- PluginsService(settings, modulesDir, pluginsDir, classpathPlugins)
         |
         +-- クラスパスプラグインロード
         |    +-- Class.forName(classname)
         |    +-- loadPlugin(pluginClazz, settings, configPath)
         |
         +-- getModuleBundles(modulesDirectory)
         |    +-- Bundle生成
         |    +-- プラグイン初期化
         |
         +-- getPluginBundles(pluginsDirectory)
         |    +-- Bundle生成
         |    +-- バージョン互換性チェック
         |    +-- JarHellチェック
         |
         +-- 必須プラグインチェック
         |
         +-- getPluginSettings() / getPluginSettingsFilter()
         |
         +-- 各プラグイン.createComponents()
```

### データフロー図

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

modules/ ─────> PluginsService ─────> PluginsAndModules
plugins/        PluginInfo解析         (プラグイン情報)
                ClassLoader生成             |
                Plugin初期化         各拡張インターフェース
                                    (Settings, Components等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PluginsService.java | `server/src/main/java/org/opensearch/plugins/PluginsService.java` | ソース | プラグインロード・管理サービス |
| Plugin.java | `server/src/main/java/org/opensearch/plugins/Plugin.java` | ソース | プラグイン基底クラス |
| PluginInfo.java | `server/src/main/java/org/opensearch/plugins/PluginInfo.java` | ソース | プラグインメタ情報 |
| ActionPlugin.java | `server/src/main/java/org/opensearch/plugins/ActionPlugin.java` | ソース | Action拡張インターフェース |
| AnalysisPlugin.java | `server/src/main/java/org/opensearch/plugins/AnalysisPlugin.java` | ソース | テキスト解析拡張 |
| DiscoveryPlugin.java | `server/src/main/java/org/opensearch/plugins/DiscoveryPlugin.java` | ソース | ディスカバリ拡張 |
| NetworkPlugin.java | `server/src/main/java/org/opensearch/plugins/NetworkPlugin.java` | ソース | ネットワーク拡張 |
| MapperPlugin.java | `server/src/main/java/org/opensearch/plugins/MapperPlugin.java` | ソース | マッパー拡張 |
| SearchPlugin.java | `server/src/main/java/org/opensearch/plugins/SearchPlugin.java` | ソース | 検索拡張 |
| ExtensiblePlugin.java | `server/src/main/java/org/opensearch/plugins/ExtensiblePlugin.java` | ソース | プラグイン間拡張 |
| ReloadablePlugin.java | `server/src/main/java/org/opensearch/plugins/ReloadablePlugin.java` | ソース | リロード可能プラグイン |
