# 画面設計書 70-コンポーネントテンプレート作成

## 概要

本ドキュメントは、OpenSearchのコンポーネントテンプレート作成・更新API（`PUT/POST /_component_template/{name}`）の画面設計書である。コンポーネントテンプレートの新規作成および既存テンプレートの更新を行うREST APIエンドポイントについて、入出力仕様・処理フロー・エラーハンドリングを定義する。

### 本画面の処理概要

**業務上の目的・背景**：コンポーネントテンプレートは、Composableインデックステンプレートの構成要素として使用される再利用可能な設定ブロックである。共通のマッピング定義や設定を一箇所にまとめることで、複数のComposableテンプレートで再利用できる。例えば、共通のタイムスタンプフィールドマッピングやログ用の設定をコンポーネントテンプレートとして定義し、複数のインデックステンプレートで`composed_of`で参照する運用が可能である。

**画面へのアクセス方法**：HTTPクライアント（curl、OpenSearch Dashboards Dev Tools等）から `PUT /_component_template/{name}` または `POST /_component_template/{name}` へリクエストボディ付きでリクエストを送信する。

**主要な操作・処理内容**：
1. クライアントからPUT/POSTリクエストを受信し、テンプレート名とリクエストボディを解析する
2. リクエストボディを`ComponentTemplate.parse()`でパースする
3. `create`パラメータがtrueの場合、既存テンプレートが存在するとエラーを返す
4. `cause`パラメータで作成・更新理由を記録する（デフォルト: "api"）
5. クラスタ状態を更新し、コンポーネントテンプレート定義を永続化する

**画面遷移**：本APIでコンポーネントテンプレートを作成した後、Composableインデックステンプレート作成API（No.66）の`composed_of`で参照する運用フローが一般的である。コンポーネントテンプレート取得API（No.69）で作成したテンプレートの確認が可能である。コンポーネントテンプレート削除API（No.71）で不要なテンプレートを削除できる。

**権限による表示制御**：クラスタレベルのメタデータ書き込み権限が必要である。セキュリティプラグイン有効時はコンポーネントテンプレートの作成・更新権限が求められる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | インデックステンプレート | 主機能 | コンポーネントテンプレートを作成または更新する処理 |

## 画面種別

登録・編集（コンポーネントテンプレート定義の作成・更新）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| PUT | `/_component_template/{name}` | テンプレートを作成または更新 |
| POST | `/_component_template/{name}` | テンプレートを作成または更新 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| name | string | 必須 | テンプレート名 |

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|------|------|-----------|------|
| create | boolean | 任意 | false | trueの場合、テンプレートが既に存在する場合にエラーを返す |
| timeout | time | 任意 | 30s | 操作タイムアウト |
| cluster_manager_timeout | time | 任意 | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | 任意 | 30s | 非推奨（v2.0.0）。cluster_manager_timeoutを使用すること |

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

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| template | object | 必須 | テンプレート設定 |
| template.settings | object | 任意 | インデックス設定（シャード数、レプリカ数等） |
| template.mappings | object | 任意 | フィールドマッピング定義 |
| template.aliases | object | 任意 | エイリアス定義 |
| version | integer | 任意 | テンプレートのバージョン番号 |
| _meta | object | 任意 | ユーザー定義メタデータ |

## 表示項目

### レスポンスボディ

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

## イベント仕様

### 1-コンポーネントテンプレート作成・更新リクエスト

1. クライアントがPUT/POSTリクエストをリクエストボディ付きで送信する
2. `RestPutComponentTemplateAction.prepareRequest()`がリクエストを解析する
3. `name`パスパラメータから`PutComponentTemplateAction.Request`を生成する（72行目）
4. `cluster_manager_timeout`, `create`, `cause`パラメータを設定する（73-76行目）
5. リクエストボディを`ComponentTemplate.parse(request.contentParser())`でパースする（77行目）
6. `client.execute(PutComponentTemplateAction.INSTANCE, putRequest)`でテンプレート作成を実行する（79行目）
7. クラスタマネージャノードでMetadataIndexTemplateServiceがテンプレートを検証・保存する

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| テンプレート作成 | ClusterState（メモリ上） | INSERT | クラスタ状態のメタデータに新規コンポーネントテンプレートを追加 |
| テンプレート更新 | ClusterState（メモリ上） | UPDATE | クラスタ状態のメタデータの既存コンポーネントテンプレートを置換 |

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

#### ClusterState.Metadata.componentTemplates（ComponentTemplateMetadata）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | ComponentTemplate | リクエストボディの内容をパースしたComponentTemplateオブジェクト | create=trueの場合、既存テンプレートが存在するとエラー |

## メッセージ仕様

| メッセージID | 種別 | HTTPステータス | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------------|---------|
| - | 成功 | 200 OK | {"acknowledged": true} | テンプレートが正常に作成・更新された場合 |
| - | エラー | 400 Bad Request | バリデーションエラー | マッピング定義が不正等 |
| - | エラー | 400 Bad Request | テンプレート既存エラー | create=trueで既存テンプレートが存在する場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|---------------|------|
| マッピング不正 | 400 | マッピング定義の構文が不正 |
| テンプレート既存（create=true） | 400 | create=trueで既にテンプレートが存在する |
| タイムアウト | 408/500 | クラスタマネージャノードへの接続がタイムアウトした |
| 権限不足 | 403 | テンプレートの作成・更新権限がない |

## 備考

- 本APIはexperimental安定性レベルで提供されている。
- コンポーネントテンプレートはComposableインデックステンプレートの`composed_of`フィールドで参照されることで使用される。
- コンポーネントテンプレートを更新しても、既に作成済みのインデックスには影響しない。新しいインデックスが作成される際に更新後の定義が適用される。
- コンポーネントテンプレートを更新する場合、そのテンプレートを参照するComposableテンプレートの結合結果が有効かどうか自動的に検証される。
- `cause`パラメータのデフォルト値は"api"である（ソースコード76行目）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ComponentTemplate.java | `server/src/main/java/org/opensearch/cluster/metadata/ComponentTemplate.java` | コンポーネントテンプレートのデータ構造（template, version, metadata）とparse()メソッドを理解する |
| 1-2 | PutComponentTemplateAction.java | `server/src/main/java/org/opensearch/action/admin/indices/template/put/PutComponentTemplateAction.java` | リクエスト/レスポンスの内部クラス構造を理解する |

**読解のコツ**: `ComponentTemplate.parse()`がリクエストボディをどのようにパースするかに注目する。`PARSER`フィールドのObjectParser定義がフィールド名と型のマッピングを示す。コンポーネントテンプレートにはindex_patternsがなく、templateオブジェクト（settings, mappings, aliases）が主要なコンテンツである。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestPutComponentTemplateAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestPutComponentTemplateAction.java` | RESTリクエストの受信・パラメータ解析・ボディパース |

**主要処理フロー**:
1. **60-61行目**: `routes()`でPOSTとPUTの`/_component_template/{name}`ルートを登録
2. **72行目**: テンプレート名からPutComponentTemplateAction.Requestを生成
3. **73-76行目**: cluster_manager_timeout, create, causeパラメータを設定
4. **77行目**: `ComponentTemplate.parse(request.contentParser())`でリクエストボディをパース
5. **79行目**: `client.execute(PutComponentTemplateAction.INSTANCE, putRequest)`でテンプレート作成を実行

#### Step 3: テンプレート管理サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MetadataIndexTemplateService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataIndexTemplateService.java` | addComponentTemplate()メソッドでコンポーネントテンプレートを検証・保存するロジック。参照元のComposableテンプレートとの整合性チェックも行われる |

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

```
RestPutComponentTemplateAction.prepareRequest()
    |
    +-- new PutComponentTemplateAction.Request(name)
    |
    +-- ComponentTemplate.parse(contentParser)
    |
    +-- client.execute(PutComponentTemplateAction.INSTANCE, putRequest)
            |
            +-- TransportPutComponentTemplateAction.clusterManagerOperation()
                    |
                    +-- MetadataIndexTemplateService.addComponentTemplate()
                            |
                            +-- validate(template)
                            |
                            +-- 参照元Composableテンプレートとの整合性チェック
                            |
                            +-- ClusterState.builder().metadata(updated).build()
```

### データフロー図

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

PUT /_component_template/{name}  --> RestPutComponentTemplateAction.prepareRequest()
  + JSON body                              |
                                  ComponentTemplate.parse(body)
                                           |
                                  PutComponentTemplateAction.Request生成
                                           |
                                  TransportPutComponentTemplateAction実行
                                           |
                                  MetadataIndexTemplateService.addComponentTemplate()  --> {"acknowledged": true}
                                           |
                                  ClusterState更新（テンプレート追加/置換）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestPutComponentTemplateAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestPutComponentTemplateAction.java` | ソース | RESTエンドポイントハンドラ |
| PutComponentTemplateAction.java | `server/src/main/java/org/opensearch/action/admin/indices/template/put/PutComponentTemplateAction.java` | ソース | アクション定義 |
| ComponentTemplate.java | `server/src/main/java/org/opensearch/cluster/metadata/ComponentTemplate.java` | ソース | テンプレートデータモデル |
| ComponentTemplateMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/ComponentTemplateMetadata.java` | ソース | テンプレートメタデータ |
| MetadataIndexTemplateService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataIndexTemplateService.java` | ソース | テンプレート管理サービス |
| cluster.put_component_template.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cluster.put_component_template.json` | API定義 | REST API仕様定義 |
