# 画面設計書 62-インデックステンプレート作成（レガシー）

## 概要

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

### 本画面の処理概要

**業務上の目的・背景**：インデックステンプレートは、インデックスパターンに一致するインデックスが新規作成される際に、定義済みの設定（settings）・マッピング（mappings）・エイリアス（aliases）を自動的に適用する仕組みである。これにより、運用者は個別のインデックスごとに設定を繰り返す必要がなくなり、一貫性のあるインデックス構成を維持できる。本APIはレガシー形式のテンプレートを作成・更新する。

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

**主要な操作・処理内容**：
1. クライアントからPUT/POSTリクエストを受信し、テンプレート名とリクエストボディを解析する
2. リクエストボディからインデックスパターン、設定、マッピング、エイリアスの定義を抽出する
3. `create`パラメータがtrueの場合、既存テンプレートが存在するとエラーを返す
4. order パラメータで複数テンプレートの適用優先順位を指定する
5. クラスタ状態を更新し、テンプレート定義を永続化する

**画面遷移**：テンプレート取得API（No.61）で既存定義を確認した後に本APIで作成・更新を行う運用フローが一般的。作成されたテンプレートはインデックス作成API（No.38）実行時に自動適用される。テンプレートが不要になった場合はテンプレート削除API（No.63）で削除する。

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

## 関連機能

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

## 画面種別

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

## URL/ルーティング

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

## 入出力項目

### パスパラメータ

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

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|------|------|-----------|------|
| order | number | 任意 | - | テンプレートの適用優先順位（大きい値が後から適用され上書き） |
| create | boolean | 任意 | false | trueの場合、テンプレートが既に存在する場合にエラーを返す |
| cluster_manager_timeout | time | 任意 | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | 任意 | 30s | 非推奨（v2.0.0）。cluster_manager_timeoutを使用すること |

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

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| index_patterns | array[string] | 必須 | テンプレートを適用するインデックスパターン |
| template | string | 非推奨 | 旧形式のインデックスパターン（index_patternsで置換） |
| settings | object | 任意 | インデックス設定（シャード数、レプリカ数等） |
| mappings | object | 任意 | フィールドマッピング定義 |
| aliases | object | 任意 | エイリアス定義 |
| order | integer | 任意 | テンプレートの適用優先順位 |
| version | integer | 任意 | テンプレートのバージョン番号 |

## 表示項目

### レスポンスボディ

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

## イベント仕様

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

1. クライアントがPUT/POSTリクエストをリクエストボディ付きで送信する
2. `RestPutIndexTemplateAction.prepareRequest()`がリクエストを解析する
3. `template`パラメータ使用時は非推奨警告を出力し、`index_patterns`として扱う（77-84行目）
4. `order`, `cluster_manager_timeout`, `create`, `cause`パラメータを設定する（85-89行目）
5. リクエストボディをMapに変換し、マッピング定義を正規化する（91-93行目）
6. `client.admin().indices().putTemplate()`でクラスタ状態の更新を実行する（95行目）
7. クラスタマネージャノードでMetadataIndexTemplateServiceがテンプレートを検証・保存する
8. `create=true`で既存テンプレートが存在する場合はエラーレスポンスを返す

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

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

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

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

#### ClusterState.Metadata.templates

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | IndexTemplateMetadata | リクエストボディの内容（patterns, settings, mappings, aliases, order, version） | create=trueの場合、既存テンプレートが存在するとエラー |

## メッセージ仕様

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

## 例外処理

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

## 備考

- 本APIはレガシーテンプレートAPIであり、Composableインデックステンプレート（`_index_template`）の使用が推奨される。
- `template`パラメータは`index_patterns`に置き換えられ非推奨となっている。
- 複数のテンプレートが同一インデックスに一致する場合、`order`の値に基づいて順にマージされる（大きい値が後から適用され上書き）。
- マッピング定義は`RestCreateIndexAction.prepareMappings()`で正規化される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PutIndexTemplateRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/template/put/PutIndexTemplateRequest.java` | リクエストの構造（patterns, settings, mappings, aliases, order等）を理解する |
| 1-2 | IndexTemplateMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexTemplateMetadata.java` | テンプレートの永続化データモデルを理解する |

**読解のコツ**: `PutIndexTemplateRequest`の`source(Map)`メソッドがリクエストボディの各フィールドをどう処理するかに注目する。

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

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

**主要処理フロー**:
1. **64-65行目**: `routes()`でPOSTとPUTの`/_template/{name}`ルートを登録
2. **75行目**: テンプレート名をパスパラメータから取得し`PutIndexTemplateRequest`を生成
3. **76-84行目**: `template`パラメータ（非推奨）と`index_patterns`の処理分岐
4. **91-93行目**: リクエストボディをMap変換し、マッピング定義をprepareMappings()で正規化
5. **95行目**: `client.admin().indices().putTemplate()`でテンプレート作成を実行

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MetadataIndexTemplateService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataIndexTemplateService.java` | テンプレートの検証・クラスタ状態への保存ロジック |

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

```
RestPutIndexTemplateAction.prepareRequest()
    |
    +-- new PutIndexTemplateRequest(name)
    |
    +-- XContentHelper.convertToMap(body)
    |
    +-- RestCreateIndexAction.prepareMappings(sourceAsMap)
    |
    +-- putRequest.source(sourceAsMap)
    |
    +-- client.admin().indices().putTemplate()
            |
            +-- TransportPutIndexTemplateAction.clusterManagerOperation()
                    |
                    +-- MetadataIndexTemplateService.putTemplate()
                            |
                            +-- validate(request)
                            |
                            +-- ClusterState.builder().metadata(updatedTemplates).build()
```

### データフロー図

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

PUT /_template/{name}      --> RestPutIndexTemplateAction.prepareRequest()
  + JSON body                       |
                            パラメータ解析・ボディ変換
                                    |
                            PutIndexTemplateRequest生成
                                    |
                            TransportPutIndexTemplateAction実行
                                    |
                            MetadataIndexTemplateService.putTemplate()  --> {"acknowledged": true}
                                    |
                            ClusterState更新（テンプレート追加/置換）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestPutIndexTemplateAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestPutIndexTemplateAction.java` | ソース | RESTエンドポイントハンドラ |
| PutIndexTemplateRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/template/put/PutIndexTemplateRequest.java` | ソース | リクエストオブジェクト |
| MetadataIndexTemplateService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataIndexTemplateService.java` | ソース | テンプレート管理サービス |
| IndexTemplateMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexTemplateMetadata.java` | ソース | テンプレートメタデータモデル |
| RestCreateIndexAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestCreateIndexAction.java` | ソース | prepareMappings()メソッド提供 |
| indices.put_template.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.put_template.json` | API定義 | REST API仕様定義 |
