# 帳票設計書 13-Templates Report

## 概要

本ドキュメントは、OpenSearchのCat API「/_cat/templates」エンドポイントが出力するTemplates Reportの設計仕様を定義する。本帳票はクラスタに定義されたインデックステンプレート（レガシーテンプレートおよびコンポーザブルインデックステンプレート）の一覧をテキストテーブル形式にて出力するものである。

### 本帳票の処理概要

本帳票は、OpenSearchクラスタのメタデータに登録されたインデックステンプレートの構成情報を一覧化する。レガシーテンプレート（IndexTemplateMetadata）とコンポーザブルインデックステンプレート（ComposableIndexTemplate）の両方を統合して表示する。

**業務上の目的・背景**：インデックステンプレートはインデックス作成時に自動適用されるマッピング・設定のひな形であり、クラスタ運用においてテンプレートの構成把握は必須である。テンプレートの重複・競合確認やバージョン管理に本帳票が活用される。

**帳票の利用シーン**：テンプレート作成・変更後の確認、テンプレート適用順序（order/priority）の確認、特定パターンに一致するテンプレートの検索、コンポーザブルテンプレートの構成要素確認に利用される。

**主要な出力内容**：
1. テンプレート名
2. インデックスパターン（どのインデックス名に適用されるか）
3. 適用順序/優先度
4. バージョン
5. 構成テンプレート一覧（コンポーザブルテンプレートの場合）

**帳票の出力タイミング**：ユーザーがREST APIエンドポイント `GET /_cat/templates` または `GET /_cat/templates/{name}` にHTTPリクエストを送信した際にリアルタイムで生成・出力される。

**帳票の利用者**：OpenSearchクラスタ管理者、開発者、インデックス設計担当者。

## 帳票種別

一覧表（インデックステンプレート一覧）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | REST API | `GET /_cat/templates` | HTTPリクエスト送信 |
| - | REST API | `GET /_cat/templates/{name}` | HTTPリクエスト送信（名前フィルタ指定） |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | text/plain（テキストテーブル）またはJSON/YAML（format指定時） |
| 用紙サイズ | N/A（API応答） |
| 向き | N/A |
| ファイル名 | N/A（HTTPレスポンスボディ） |
| 出力方法 | HTTPレスポンス |
| 文字コード | UTF-8 |

### PDF固有設定

該当なし

### Excel固有設定

該当なし

## 帳票レイアウト

### レイアウト概要

テキストテーブル形式で、1行が1テンプレートに対応する一覧を出力する。レガシーテンプレートとコンポーザブルテンプレートが混在して表示される。

```
┌──────────────────────────────────────────────────────┐
│  ヘッダー部（カラム名: name, index_patterns, order,   │
│             version, composed_of）                    │
├──────────────────────────────────────────────────────┤
│  明細部（テンプレートごとに1行）                         │
│  例: my_template  [my-index-*]  0  1                  │
│      v2_template  [logs-*]      100  2  [comp1,comp2] │
└──────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | name | テンプレート名 | IndexTemplateMetadata.name() / Map.Entry.getKey() | 文字列（alias: n） |
| 2 | index_patterns | インデックスパターン | IndexTemplateMetadata.patterns() / ComposableIndexTemplate.indexPatterns() | 文字列リスト（alias: t） |
| 3 | order | 適用順序/優先度 | IndexTemplateMetadata.getOrder() / ComposableIndexTemplate.priorityOrZero() | 数値（alias: o, p） |
| 4 | version | バージョン | IndexTemplateMetadata.getVersion() / ComposableIndexTemplate.version() | 数値（alias: v） |
| 5 | composed_of | コンポーネントテンプレート | ComposableIndexTemplate.composedOf() | 文字列リスト（alias: c） |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | name | テンプレート名 | 上記参照 | 文字列 | 可変 |
| 2 | index_patterns | パターン | 上記参照 | "[pattern1, pattern2]" 形式 | 可変 |
| 3 | order | 優先度 | 上記参照 | 整数値 | 可変 |
| 4 | version | バージョン | 上記参照 | 整数値またはnull | 可変 |
| 5 | composed_of | 構成要素 | 上記参照 | "[comp1, comp2]" 形式。レガシーは空文字 | 可変 |

### フッター部

フッター部は存在しない。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| name | テンプレート名のワイルドカードマッチフィルタ | No |
| local | ローカルノードのクラスタステートのみ参照するか | No（デフォルト: false） |
| cluster_manager_timeout | クラスタマネージャへのタイムアウト | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | レガシーテンプレート | Metadataのtemplates()イテレーション順 |
| 2 | コンポーザブルテンプレート | Metadataのtemplates V2()イテレーション順 |

### 改ページ条件

改ページなし。

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| ClusterState.metadata（内部API） | テンプレート情報取得 | ClusterStateRequest.clear().metadata(true) |

### テーブル別参照項目詳細

#### Metadata - IndexTemplateMetadata（レガシーテンプレート）

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| name() | name | Regex.simpleMatch(patternString, name) | テンプレート名 |
| patterns() | index_patterns | - | インデックスパターンリスト |
| getOrder() | order | - | 適用順序 |
| getVersion() | version | - | バージョン（null可） |

#### Metadata - ComposableIndexTemplate（V2テンプレート）

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| Map.Entry.getKey() | name | Regex.simpleMatch(patternString, name) | テンプレート名 |
| indexPatterns() | index_patterns | - | インデックスパターンリスト |
| priorityOrZero() | order | - | 優先度（未設定時0） |
| version() | version | - | バージョン（null可） |
| composedOf() | composed_of | - | コンポーネントテンプレートリスト |

## 計算仕様

### 計算項目一覧

本帳票に特別な計算項目は存在しない。

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| index_patterns表示 | "[" + String.join(", ", patterns) + "]" | - | リストをカンマ区切り文字列に変換 |
| composed_of表示 | "[" + String.join(", ", composedOf) + "]" | - | リストをカンマ区切り文字列に変換 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[クライアントからGETリクエスト受信] --> B[RestTemplatesAction.doCatRequest]
    B --> C[nameパラメータ取得]
    C --> D[ClusterStateRequest生成 - metadata=true]
    D --> E[NodeClient.admin.cluster.state実行]
    E --> F[ClusterStateResponse受信]
    F --> G[buildTable: レガシーテンプレートをループ]
    G --> H[nameパターンマッチフィルタ適用]
    H --> I[コンポーザブルテンプレートをループ]
    I --> J[nameパターンマッチフィルタ適用]
    J --> K[RestTable.buildResponse]
    K --> L[HTTPレスポンス返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | マッチするテンプレートが存在しない場合 | 空のテーブル（ヘッダーのみ） | 正常動作 |
| クラスタステート取得失敗 | クラスタマネージャ応答なし | フレームワーク標準エラー | タイムアウト設定で制御 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | テンプレート数（典型的には数個〜数百個） |
| 目標出力時間 | クラスタステート取得依存（通常1秒以内） |
| 同時出力数上限 | REST APIスレッドプールに依存 |

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

テンプレート情報にはマッピングや設定情報が含まれる可能性があるため、cluster:monitor/state 権限を持つユーザーのみアクセス可能とすべきである。

## 備考

- レガシーテンプレート（_template API）とコンポーザブルテンプレート（_index_template API）の両方が出力される
- name パラメータはワイルドカード（*）を使用したパターンマッチングに対応（Regex.simpleMatch）
- レガシーテンプレートのcomposed_ofカラムは空文字が出力される
- `master_timeout` は非推奨。`cluster_manager_timeout` を使用すべき

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IndexTemplateMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexTemplateMetadata.java` | レガシーテンプレートの構造（name, patterns, order, version） |
| 1-2 | ComposableIndexTemplate.java | `server/src/main/java/org/opensearch/cluster/metadata/ComposableIndexTemplate.java` | V2テンプレートの構造（indexPatterns, priority, version, composedOf） |
| 1-3 | Metadata.java | `server/src/main/java/org/opensearch/cluster/metadata/Metadata.java` | templates()とtemplatesV2()メソッド |

**読解のコツ**: レガシーテンプレートはtemplates()で、V2テンプレートはtemplatesV2()で別々に管理されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestTemplatesAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTemplatesAction.java` | 帳票メインクラス。141行 |

**主要処理フロー**:
1. **行65-67**: routes()で2つのルートを定義（名前指定あり/なし）
2. **行80-96**: doCatRequest()でClusterStateRequest（metadata=true）を発行
3. **行81**: matchPatternの取得。nameパラメータ未指定時はnull
4. **行99-109**: getTableWithHeader()で5カラム定義
5. **行111-140**: buildTable()でレガシーとV2テンプレートを順次ループ
6. **行114-124**: レガシーテンプレートのループとフィルタリング
7. **行126-138**: V2テンプレートのループとフィルタリング

#### Step 3: パターンマッチングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Regex.java | `server/src/main/java/org/opensearch/common/regex/Regex.java` | simpleMatch()メソッド。ワイルドカードパターンマッチング |

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

```
HTTP GET /_cat/templates[/{name}]
    |
    +-- AbstractCatAction.prepareRequest() [行68]
        |
        +-- RestTemplatesAction.doCatRequest() [行80]
            |
            +-- ClusterStateRequest.clear().metadata(true) [行82-83]
            +-- NodeClient.admin().cluster().state() [行90]
                |
                +-- RestResponseListener.buildResponse() [行92]
                    |
                    +-- buildTable(request, response, matchPattern) [行111]
                    |   +-- metadata.templates() loop [行114]
                    |   |   +-- Regex.simpleMatch() [行115]
                    |   |   +-- table.addCell() x 5 [行117-121]
                    |   +-- metadata.templatesV2() loop [行126]
                    |       +-- Regex.simpleMatch() [行129]
                    |       +-- table.addCell() x 5 [行131-135]
                    |
                    +-- RestTable.buildResponse() [行93]
```

### データフロー図

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

HTTP GET Request    --> RestTemplatesAction              --> HTTP Response
  /_cat/templates        |                                   (text/plain
  /{name}               +-> ClusterStateRequest              or JSON)
                        |   (metadata only)
                        +-> ClusterStateResponse
                        |   (Metadata)
                        +-> Metadata.templates()
                        |   (legacy templates)
                        +-> Metadata.templatesV2()
                        |   (composable templates)
                        +-> buildTable() with filter
                        |   (Table object)
                        +-> RestTable.buildResponse()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestTemplatesAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTemplatesAction.java` | ソース | 帳票メインクラス（141行） |
| AbstractCatAction.java | `server/src/main/java/org/opensearch/rest/action/cat/AbstractCatAction.java` | ソース | Cat API基底クラス |
| RestTable.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTable.java` | ソース | テーブルレスポンス構築 |
| IndexTemplateMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexTemplateMetadata.java` | ソース | レガシーテンプレートメタデータ |
| ComposableIndexTemplate.java | `server/src/main/java/org/opensearch/cluster/metadata/ComposableIndexTemplate.java` | ソース | V2テンプレートメタデータ |
| Metadata.java | `server/src/main/java/org/opensearch/cluster/metadata/Metadata.java` | ソース | クラスタメタデータ |
| Regex.java | `server/src/main/java/org/opensearch/common/regex/Regex.java` | ソース | パターンマッチングユーティリティ |
| ActionModule.java | `server/src/main/java/org/opensearch/action/ActionModule.java` | ソース | アクション登録 |
