# 機能設計書 1-インデックス作成

## 概要

本ドキュメントは、OpenSearchにおけるインデックス作成機能の設計を記述する。インデックスはRDBにおけるデータベース/テーブルに相当し、ドキュメントの格納先となる基本単位である。

### 本機能の処理概要

インデックス作成機能は、OpenSearchクラスタ上に新しいインデックスを作成する。マッピング定義（フィールドの型指定）、シャード数・レプリカ数などの設定、エイリアスの同時指定が可能である。

**業務上の目的・背景**：データの格納先としてインデックスを作成することは、OpenSearchを利用する上で最も基本的な操作である。適切なマッピング定義やシャード数の設定により、データの検索性能やストレージ効率を最適化する。

**機能の利用シーン**：新しいアプリケーションのデータ格納先を準備する場合、時系列データの新しい期間用インデックスを手動作成する場合、テスト環境でのインデックス構築時などに利用される。

**主要な処理内容**：
1. REST APIからのリクエスト受信とバリデーション
2. 日付数式（date math）によるインデックス名の解決
3. マッピングトランスフォーマーによるマッピング変換
4. クラスタ状態更新リクエストの作成
5. MetadataCreateIndexServiceを介したクラスタ状態の更新（インデックスメタデータの追加）
6. シャードのアロケーションとアクティブシャードの待機

**関連システム・外部連携**：インデックステンプレート機能と連携し、テンプレートに一致するパターンの場合は自動的にテンプレートの設定が適用される。エイリアス機能と連携し、作成時に同時にエイリアスを付与できる。

**権限による制御**：`indices:admin/create`アクションに対する権限が必要。エイリアスを同時作成する場合は`indices:admin/aliases`アクションに対する権限も必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 38 | インデックス作成 | 主画面 | オプションの設定とマッピングでインデックスを作成する主処理 |
| 40 | インデックス情報取得 | 参照画面 | 1つ以上のインデックスの情報（設定・マッピング・エイリアス）を返す処理 |
| 41 | インデックス存在確認 | 参照画面 | インデックスが存在するかをHEADリクエストで確認する処理 |
| 45 | インデックスクローン | 参照画面 | インデックスをクローンする処理 |

## 機能種別

CRUD操作（Create）/ クラスタ状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| index | String | Yes | 作成するインデックス名 | nullでないこと。日付数式の使用可。小文字のみ。 |
| settings | Settings | No | インデックス設定（シャード数、レプリカ数等） | JSON/YAMLオブジェクト形式 |
| mappings | String | No | フィールドマッピング定義 | JSON形式。デフォルトは`{}` |
| aliases | Set\<Alias\> | No | 同時作成するエイリアスの集合 | エイリアス名の妥当性 |
| context | Context | No | インデックスコンテキスト情報 | V2.17.0以降で利用可能 |
| wait_for_active_shards | ActiveShardCount | No | アクティブシャード待機数 | デフォルトはDEFAULT（プライマリ1つ） |
| timeout | TimeValue | No | Ack待機タイムアウト | デフォルト30秒 |
| cluster_manager_timeout | TimeValue | No | クラスタマネージャノード待機タイムアウト | デフォルト30秒 |

### 入力データソース

REST API（PUT /{index}）からのHTTPリクエスト。リクエストボディにはsettings、mappings、aliasesをJSON形式で指定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| acknowledged | boolean | クラスタ状態の更新が全ノードで承認されたか |
| shards_acknowledged | boolean | 必要なアクティブシャード数が開始されたか |
| index | String | 作成されたインデックス名 |

### 出力先

REST APIレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. REST APIリクエスト受信
   └─ CreateIndexRequestの生成とバリデーション
2. TransportCreateIndexAction.clusterManagerOperation()実行
   └─ クラスタマネージャノードへの転送
3. インデックス名の日付数式解決
   └─ indexNameExpressionResolver.resolveDateMathExpression()
4. マッピング変換
   └─ mappingTransformerRegistry.applyTransformers()
5. CreateIndexClusterStateUpdateRequestの構築
   └─ cause, index, settings, mappings, aliases, contextの設定
6. MetadataCreateIndexService.createIndex()呼び出し
   └─ クラスタ状態の更新（インデックスメタデータの追加、シャード割り当て）
7. アクティブシャードの待機
   └─ waitForActiveShardsに基づく待機処理
8. CreateIndexResponseの返却
   └─ acknowledged, shards_acknowledged, indexの設定
```

### フローチャート

```mermaid
flowchart TD
    A[REST API リクエスト受信] --> B[CreateIndexRequest バリデーション]
    B -->|index == null| ERR1[バリデーションエラー]
    B -->|OK| C[クラスタブロックチェック]
    C -->|ブロックあり| ERR2[ClusterBlockException]
    C -->|OK| D[インデックス名の日付数式解決]
    D --> E[マッピングトランスフォーマー適用]
    E --> F[CreateIndexClusterStateUpdateRequest構築]
    F --> G[MetadataCreateIndexService.createIndex]
    G --> H[クラスタ状態更新]
    H --> I[アクティブシャード待機]
    I --> J[CreateIndexResponse返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | インデックス名必須 | インデックス名はnullであってはならない | 常時 |
| BR-02 | クラスタブロックチェック | METADATA_WRITEレベルのブロック及びCREATE_INDEXレベルのブロックがないこと | 常時 |
| BR-03 | cause設定 | causeが空文字の場合は"api"に設定 | API経由の場合 |
| BR-04 | テンプレート自動適用 | インデックス名がテンプレートパターンに一致する場合、テンプレートの設定が自動適用される | テンプレートが存在する場合 |
| BR-05 | アクティブシャード待機 | デフォルトではプライマリシャード1つがアクティブになるまで待機 | 常時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| インデックス作成 | ClusterState.metadata | INSERT | インデックスメタデータの追加 |
| インデックス作成 | ClusterState.routingTable | INSERT | シャードルーティング情報の追加 |

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

#### ClusterState.metadata（IndexMetadata）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | index | 指定されたインデックス名 | 日付数式解決後の名前 |
| INSERT | settings | リクエストのsettings + テンプレートのsettings | テンプレートとマージ |
| INSERT | mappings | リクエストのmappings | マッピングトランスフォーマー適用後 |
| INSERT | aliases | リクエストのaliases | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | ActionRequestValidationException | インデックス名がnull | インデックス名を指定する |
| 400 | InvalidIndexNameException | インデックス名が不正（大文字含む等） | インデックス命名規則に従う |
| 400 | ResourceAlreadyExistsException | 同名インデックスが既存 | 別名を使用するかインデックスを削除 |
| 403 | ClusterBlockException | クラスタブロック中 | ブロック解除後に再実行 |
| 408 | - | タイムアウト | タイムアウト値を延長して再実行 |

### リトライ仕様

クラスタマネージャノードへの転送に失敗した場合、TransportClusterManagerNodeActionの標準リトライ機構が適用される。

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

クラスタ状態の更新はアトミックに行われる。ClusterStateUpdateTaskとして実行され、クラスタ状態の変更はall-or-nothingで適用される。タイムアウト（ackTimeout）内に全ノードからの承認を待つ。

## パフォーマンス要件

インデックス作成はクラスタ状態の更新を伴うため、クラスタマネージャノードでの処理がボトルネックとなる。大量のインデックスを同時に作成する場合は、クラスタマネージャの負荷を考慮する必要がある。

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

- `indices:admin/create`アクション権限が必要
- エイリアス同時作成時は`indices:admin/aliases`アクション権限も必要
- インデックス名に対するワイルドカードは使用不可（strictSingleIndexNoExpandForbidClosed）

## 備考

- CreateIndexActionのアクション名は`indices:admin/create`
- AutoCreateAction（自動インデックス作成）は別のアクションとして存在し、ドキュメント登録時に自動的にトリガーされる
- V2.17.0以降でContextフィールドがサポートされた

---

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

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

### 推奨読解順序

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

まず、リクエスト/レスポンスのデータ構造を把握することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CreateIndexRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexRequest.java` | インデックス作成リクエストのデータ構造。index, settings, mappings, aliases, context, waitForActiveShardsの各フィールドを確認 |
| 1-2 | CreateIndexClusterStateUpdateRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexClusterStateUpdateRequest.java` | クラスタ状態更新用リクエスト。recoverFrom, resizeType等のリサイズ関連フィールドも含む |
| 1-3 | CreateIndexResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexResponse.java` | レスポンスのデータ構造。acknowledged, shardsAcknowledged, indexの3フィールド |

**読解のコツ**: CreateIndexRequestはAcknowledgedRequestを継承しており、timeout（ackTimeout）とclusterManagerNodeTimeoutの2つのタイムアウトを持つ。IndicesRequestインターフェースの実装により、インデックス名の解決オプションが定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CreateIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexAction.java` | アクション定義。NAME="indices:admin/create"の定数定義 |
| 2-2 | TransportCreateIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/create/TransportCreateIndexAction.java` | メインのトランスポートアクション。処理の起点 |

**主要処理フロー**:
1. **104-112行目**: checkBlock()メソッド -- METADATA_WRITEとCREATE_INDEXレベルのブロックチェック
2. **115-151行目**: clusterManagerOperation()メソッド -- メイン処理ロジック
3. **125行目**: resolveIndexName() -- 日付数式の解決
4. **128-148行目**: マッピングトランスフォーマー適用とCreateIndexClusterStateUpdateRequestの構築
5. **141-147行目**: createIndexService.createIndex()呼び出し
6. **150行目**: mappingTransformerRegistry.applyTransformers() -- マッピング変換の開始

#### Step 3: クラスタ状態更新処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MetadataCreateIndexService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataCreateIndexService.java` | 実際のインデックス作成処理。テンプレートの適用、設定のバリデーション、シャード割り当て等の詳細ロジック |

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

```
REST API (PUT /{index})
    |
    +-- TransportCreateIndexAction
          |
          +-- checkBlock() -- クラスタブロックチェック
          |
          +-- clusterManagerOperation()
                |
                +-- resolveIndexName() -- 日付数式解決
                |
                +-- mappingTransformerRegistry.applyTransformers()
                |     |
                |     +-- (callback) CreateIndexClusterStateUpdateRequest構築
                |
                +-- MetadataCreateIndexService.createIndex()
                      |
                      +-- applyCreateIndexRequest() -- クラスタ状態更新
                      |
                      +-- waitForActiveShards() -- シャード待機
```

### データフロー図

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

CreateIndexRequest -----> TransportCreateIndexAction -------> CreateIndexResponse
 (index, settings,        |                                    (acknowledged,
  mappings, aliases,       +-> resolveIndexName()               shards_acknowledged,
  context,                 +-> applyTransformers()              index)
  waitForActiveShards)     +-> CreateIndexClusterStateUpdateRequest
                           +-> MetadataCreateIndexService.createIndex()
                                |
                                +-> ClusterState更新
                                     (IndexMetadata追加,
                                      RoutingTable更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CreateIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexAction.java` | ソース | アクション型定義 |
| CreateIndexRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexRequest.java` | ソース | リクエストデータ構造 |
| CreateIndexRequestBuilder.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexRequestBuilder.java` | ソース | リクエストビルダー |
| CreateIndexResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexResponse.java` | ソース | レスポンスデータ構造 |
| CreateIndexClusterStateUpdateRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/create/CreateIndexClusterStateUpdateRequest.java` | ソース | クラスタ状態更新リクエスト |
| TransportCreateIndexAction.java | `server/src/main/java/org/opensearch/action/admin/indices/create/TransportCreateIndexAction.java` | ソース | トランスポートアクション（メイン処理） |
| AutoCreateAction.java | `server/src/main/java/org/opensearch/action/admin/indices/create/AutoCreateAction.java` | ソース | 自動インデックス作成アクション |
| MetadataCreateIndexService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataCreateIndexService.java` | ソース | インデックス作成のクラスタ状態更新ロジック |
