# 画面設計書 48-インデックスロールオーバー

## 概要

本ドキュメントは、OpenSearchのインデックスロールオーバーAPI（POST /{alias}/_rollover）の設計仕様を記述する。

### 本画面の処理概要

本APIは、エイリアスが指すインデックスが指定条件（サイズ、ドキュメント数、経過時間など）を満たした場合に、新しいインデックスを作成してエイリアスを切り替えるためのエンドポイントである。

**業務上の目的・背景**：ログデータや時系列データなどを扱うシステムでは、インデックスが一定のサイズや経過時間に達した際に自動的に新しいインデックスに切り替えるライフサイクル管理が必要である。本APIは、手動またはISM（Index State Management）ポリシーから呼び出され、条件ベースのインデックスローテーションを実現する。dry_runモードで条件の事前確認も可能。データストリームのバッキングインデックスのロールオーバーにも使用される。

**画面へのアクセス方法**：`POST /{alias}/_rollover` または `POST /{alias}/_rollover/{new_index}` エンドポイントにHTTPリクエストを送信する。

**主要な操作・処理内容**：
1. クライアントがPOSTリクエストでエイリアス名（および任意で新インデックス名）を指定して送信する
2. RestRolloverIndexActionがリクエストパラメータを解析しRolloverRequestを構築する
3. リクエストボディからロールオーバー条件（conditions）を解析する
4. dry_run=trueの場合、条件のみ評価して実際のロールオーバーは行わない
5. 条件が満たされた場合、新しいインデックスを作成しエイリアスを切り替える
6. 処理結果（acknowledged, shards_acknowledged, old_index, new_index, rolled_over, dry_run, conditions）をレスポンスとして返す

**画面遷移**：エイリアス作成・更新（PUT /{index}/_alias/{name}）でエイリアスが設定されたインデックスに対してロールオーバーを実行する。ロールオーバー後は新しいインデックスが作成され、エイリアスが新インデックスを指すようになる。

**権限による表示制御**：インデックスの管理権限とエイリアスの管理権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | インデックスロールオーバー | 主機能 | エイリアスを新しいインデックスに条件付きで切り替える処理 |
| 4 | インデックスエイリアス | 補助機能 | ロールオーバー時のエイリアス切り替え処理 |

## 画面種別

実行（インデックスロールオーバー）

## URL/ルーティング

| メソッド | パス | 説明 |
|----------|------|------|
| POST | `/{alias}/_rollover` | エイリアスのロールオーバー（新インデックス名は自動生成） |
| POST | `/{alias}/_rollover/{new_index}` | エイリアスのロールオーバー（新インデックス名を指定） |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| alias | string | はい | ロールオーバー対象のエイリアス名 |
| new_index | string | いいえ | 新しいインデックス名（省略時は自動生成） |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| timeout | time | 30s | 操作タイムアウト |
| dry_run | boolean | false | trueの場合、条件のみ評価し実際のロールオーバーは行わない |
| cluster_manager_timeout | time | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | - | 非推奨（cluster_manager_timeoutを使用） |
| wait_for_active_shards | string | - | アクティブシャードの待機数 |

### リクエストボディ（任意）

| フィールド | 型 | 説明 |
|-----------|------|------|
| conditions | object | ロールオーバー条件（max_age, max_docs, max_size等） |
| settings | object | 新インデックスの設定 |
| mappings | object | 新インデックスのマッピング |
| aliases | object | 新インデックスのエイリアス |

### ロールオーバー条件

| 条件名 | 型 | 説明 |
|--------|------|------|
| max_age | time | インデックスの最大経過時間 |
| max_docs | long | インデックスの最大ドキュメント数 |
| max_size | size | インデックスの最大サイズ |

## 表示項目

### レスポンス

| 項目名 | 型 | 説明 |
|--------|------|------|
| acknowledged | boolean | クラスタ状態の更新が認識されたか |
| shards_acknowledged | boolean | 指定数のシャードコピーが開始されたか |
| old_index | string | 旧インデックス名 |
| new_index | string | 新インデックス名 |
| rolled_over | boolean | ロールオーバーが実行されたか |
| dry_run | boolean | ドライランモードか |
| conditions | object | 各条件の評価結果 |

## イベント仕様

### 1-ロールオーバーリクエスト送信

RestRolloverIndexAction.prepareRequest()（72-87行目）がリクエストを処理する。RolloverRequestを構築し、リクエストボディから条件（conditions）をパースする。dry_run、timeout、cluster_manager_timeout、wait_for_active_shardsを設定後、client.admin().indices().rolloverIndex()を呼び出す。

### 2-ドライラン実行

dry_run=trueの場合、条件の評価のみを行い、実際のインデックス作成やエイリアス切り替えは行わない。conditions フィールドに各条件の評価結果（met/unmet）が返される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| POST /{alias}/_rollover（条件一致時） | ClusterState（メモリ） | INSERT/UPDATE | 新インデックスの作成とエイリアスの切り替え |
| POST /{alias}/_rollover（dry_run=true） | なし | SELECT | 条件評価のみ、データ変更なし |

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

#### ClusterState.metadata.indices（条件一致時のみ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | IndexMetadata | 新インデックスのメタデータ | 新インデックスが作成される |
| UPDATE | AliasMetadata | エイリアスを新インデックスに切り替え | 旧インデックスからエイリアスを移動 |

## メッセージ仕様

| メッセージ種別 | 条件 | HTTPステータス | 内容 |
|--------------|------|---------------|------|
| 成功（ロールオーバー実行） | 条件一致 | 200 | {"acknowledged": true, "rolled_over": true, ...} |
| 成功（条件不一致） | 条件不一致 | 200 | {"acknowledged": true, "rolled_over": false, ...} |
| 成功（ドライラン） | dry_run=true | 200 | {"dry_run": true, "conditions": {...}} |
| エラー | エイリアスが見つからない | 404 | alias_not_found_exception |

## 例外処理

| 例外 | 条件 | 動作 |
|------|------|------|
| AliasNotFoundException | 指定エイリアスが存在しない | 404エラーを返す |
| IllegalArgumentException | 不正な条件指定 | 400エラーを返す |
| ResourceAlreadyExistsException | 新インデックス名が既に存在 | 400エラーを返す |

## 備考

- new_indexを省略した場合、現在のインデックス名の末尾に番号をインクリメントして自動生成される（例: logs-000001 -> logs-000002）。
- include_type_nameパラメータは非推奨で、次のメジャーバージョンで削除予定（58-59行目）。
- data streamに対してもロールオーバーを実行可能。
- ロールオーバー条件が指定されない場合、無条件でロールオーバーが実行される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RolloverRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/RolloverRequest.java` | alias、newIndexName、dryRun、conditions、createIndexRequestのフィールドを確認 |
| 1-2 | RolloverResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/RolloverResponse.java` | old_index、new_index、rolled_over、dry_run、conditionsのレスポンス構造を確認 |
| 1-3 | Condition.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/Condition.java` | max_age、max_docs、max_sizeの条件定義を確認 |

**読解のコツ**: RolloverRequestは内部にCreateIndexRequestを保持しており、新インデックスのsettings/mappings/aliasesはこのCreateIndexRequestに設定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestRolloverIndexAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestRolloverIndexAction.java` | 63行目: ルーティング定義、72行目: prepareRequest()の処理開始 |

**主要処理フロー**:
1. **63行目**: `POST /{index}/_rollover` と `POST /{index}/_rollover/{new_index}` のルート登録
2. **76行目**: RolloverRequestの構築（alias名とnew_indexの設定）
3. **77行目**: リクエストボディのパース（conditions含む）
4. **78行目**: dry_runの設定
5. **79-83行目**: timeout、cluster_manager_timeoutの設定
6. **84-85行目**: wait_for_active_shardsの設定
7. **86行目**: client.admin().indices().rolloverIndex()の呼び出し

#### Step 3: Transport層の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportRolloverAction.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/TransportRolloverAction.java` | 条件評価とロールオーバー実行ロジック |

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

```
RestRolloverIndexAction.prepareRequest()
    |
    +-- RolloverRequest(alias, new_index)
    +-- rolloverIndexRequest.fromXContent(parser)  // 条件パース
    +-- dryRun設定、timeout設定
    |
    +-- NodeClient.admin().indices().rolloverIndex()
            +-- TransportRolloverAction
                    |
                    +-- 条件評価（max_age, max_docs, max_size）
                    |
                    +-- [条件一致 && dry_run=false]
                    |       +-- MetadataRolloverService.rolloverClusterState()
                    |               +-- 新インデックス作成
                    |               +-- エイリアス切り替え
                    |
                    +-- [条件不一致 || dry_run=true]
                            +-- 条件評価結果のみ返却
```

### データフロー図

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

POST /{alias}/_rollover        RestRolloverIndexAction              JSON レスポンス
  +                                  |                              {acknowledged: true,
  alias名                     RolloverRequest構築                    old_index: "old",
  new_index名(任意)                  |                               new_index: "new",
  conditions(任意)            TransportRolloverAction                rolled_over: true/false,
  settings(任意)                     |                               dry_run: true/false,
  dry_run                    条件評価                                 conditions: {...}}
                                     |
                             [一致] -> インデックス作成 + エイリアス切替
                             [不一致/dry_run] -> 評価結果のみ返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| indices.rollover.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json` | API定義 | REST APIスペック定義 |
| RestRolloverIndexAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestRolloverIndexAction.java` | ソース | RESTハンドラ |
| RolloverRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/RolloverRequest.java` | ソース | リクエストデータ構造 |
| RolloverResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/RolloverResponse.java` | ソース | レスポンスデータ構造 |
| Condition.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/Condition.java` | ソース | ロールオーバー条件定義 |
| TransportRolloverAction.java | `server/src/main/java/org/opensearch/action/admin/indices/rollover/TransportRolloverAction.java` | ソース | Transport層処理 |
| MetadataRolloverService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataRolloverService.java` | ソース | ロールオーバーのクラスタ状態更新ロジック |
