# 帳票設計書 5-Allocation Report

## 概要

本ドキュメントは、OpenSearchの `_cat/allocation` APIが出力するAllocation Reportの帳票設計書である。ノードごとのディスク使用量とシャード割り当て状況をテキストテーブル形式で出力するCat APIエンドポイントの仕様を定義する。

### 本帳票の処理概要

Allocation Reportは、各ノードに割り当てられたシャード数、ディスク使用量（インデックス、全体、利用可能）をノードごとに一覧表示する帳票である。未割り当てシャードがある場合は"UNASSIGNED"行も出力する。

**業務上の目的・背景**：ノード間のシャード配分とディスク使用量のバランスを把握し、ディスク容量の逼迫やシャード偏りの検出に利用する。ディスク使用率が高いノードを特定し、シャードのリバランスやノード追加の判断材料とする。

**帳票の利用シーン**：ディスク容量監視、シャード配分の確認、キャパシティプランニング、ノード追加の判断に利用される。

**主要な出力内容**：
1. ノードごとのシャード数
2. インデックスが使用するディスクサイズ
3. ノード全体のディスク使用量・空き容量・合計容量
4. ディスク使用率（パーセンテージ）
5. 未割り当てシャード数（UNASSIGNED行）

**帳票の出力タイミング**：ユーザーが `GET /_cat/allocation` または `GET /_cat/allocation/{nodes}` エンドポイントにHTTPリクエストを送信した時点で出力される。

**帳票の利用者**：クラスタ管理者、SRE、インフラエンジニア。

## 帳票種別

一覧表（テキストテーブル形式のノード別ディスク使用量一覧）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Cat アロケーション | `GET /_cat/allocation` | HTTP GETリクエスト |
| - | Cat アロケーション（指定） | `GET /_cat/allocation/{nodes}` | HTTP GETリクエスト |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（text/plain）/ JSON（application/json） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A |
| 出力方法 | HTTPレスポンス |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

ノード数分の行 + 未割り当てシャードがある場合は追加行を出力する。

```
┌──────────────────────────────────────────────────────────┐
│ shards  disk.indices  disk.used  disk.avail  disk.total  │
├──────────────────────────────────────────────────────────┤
│ 10      2gb           50gb       450gb       500gb       │
│ 8       1.5gb         48gb       452gb       500gb       │
│ 5       -             -          -           -           │ (UNASSIGNED)
└──────────────────────────────────────────────────────────┘
```

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | shards | ノード上のシャード数 | allocs Map (ルーティングテーブルから集計) | 右寄せ数値 |
| 2 | disk.indices | インデックスが使用するディスク | NodeStats.getIndices().getStore().getSize() | 右寄せバイト値 |
| 3 | disk.used | ディスク使用量（全体） | total.getBytes() - avail.getBytes() | 右寄せバイト値 |
| 4 | disk.avail | ディスク空き容量 | FsInfo.getTotal().getAvailable() | 右寄せバイト値 |
| 5 | disk.total | ディスク合計容量 | FsInfo.getTotal().getTotal() | 右寄せバイト値 |
| 6 | disk.percent | ディスク使用率 | used * 100 / (used + avail) | 右寄せパーセンテージ |
| 7 | host | ホスト名 | DiscoveryNode.getHostName() | 文字列 |
| 8 | ip | IPアドレス | DiscoveryNode.getHostAddress() | 文字列 |
| 9 | node | ノード名 | DiscoveryNode.getName() | 文字列 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| nodes | ノードフィルタ（デフォルト: "data:true" でデータノードのみ） | No |
| local | ローカルクラスタ状態を使用 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| - | `s` パラメータで任意指定可能 | 任意 |

### 改ページ条件

改ページは発生しない。

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

### 参照テーブル一覧

| データソース | 用途 | 取得方法 |
|-----------|------|---------|
| ClusterStateResponse | ルーティングテーブル（シャード割り当て情報） | ClusterStateRequest（routingTable=true） |
| NodesStatsResponse | ノード統計（FS、Store情報） | NodesStatsRequest（FS + Store フラグ） |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| shards | allShards() を反復し nodeId ごとにカウント | なし | 未割り当ては "UNASSIGNED" キーで集計 |
| disk.used | total.getBytes() - avail.getBytes() | なし | バイト単位 |
| disk.percent | (short)(used * 100 / (used + avail)) | short型切り捨て | total が0以下の場合は -1（非表示） |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[GET /_cat/allocation リクエスト受信] --> B[doCatRequest]
    B --> C[ClusterStateRequest 実行 - ルーティングテーブル取得]
    C --> D[NodesStatsRequest 実行 - FS/Store統計取得]
    D --> E[buildTable でテーブル構築]
    E --> F{未割り当てシャードあり?}
    F -->|Yes| G[UNASSIGNED行を追加]
    F -->|No| H[RestTable.buildResponse]
    G --> H
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ディスク情報不明 | total が0以下の場合 | disk.percent が null表示 | 正常動作（非データノード等） |
| 負の値 | used または avail が負の場合 | null表示 | ファイルシステム情報の確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ノード数分 + UNASSIGNED行（通常数個～数十） |
| 目標出力時間 | 数百ミリ秒（2段階の内部API呼び出し） |
| 同時出力数上限 | 制限なし |

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

- ノードのホスト名、IPアドレス、ディスク使用量等のインフラ情報が含まれる。
- nodesパラメータのデフォルト値は "data:true" であり、データノードのみが対象。

## 備考

- 未割り当てシャードがある場合、最後の行に "UNASSIGNED" ノード名で出力される。この行のディスク関連カラムはすべてnull。
- ノードフィルタのデフォルトは `data:true` であり、データノード以外は通常表示されない。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RestAllocationAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestAllocationAction.java` | 行119-133: getTableWithHeader() で9カラムの定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestAllocationAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestAllocationAction.java` | 行86-116: doCatRequest() で2段階のAPI呼び出し |

**主要処理フロー**:
1. **行87**: ノードフィルタ取得（デフォルト "data:true"）
2. **行88-89**: ClusterStateRequest（routingTable=true）
3. **行99-103**: NodesStatsRequest（FS + Store）
4. **行109**: buildTable() 呼び出し

#### Step 3: テーブル構築ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RestAllocationAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestAllocationAction.java` | 行135-196: buildTable() でシャードカウント集計とノード行構築 |

**主要処理フロー**:
- **行136-146**: allShards() を反復してノードIDごとのシャード数を集計
- **行150-178**: ノードごとにディスク情報を取得して行構築
- **行180-193**: UNASSIGNED シャードがある場合の追加行

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

```
AbstractCatAction.prepareRequest()
    |
    +-- RestAllocationAction.doCatRequest() [行86]
           |
           +-- client.admin().cluster().state() [行96]
           |      |
           |      +-- client.admin().cluster().nodesStats() [行106]
           |             |
           |             +-- buildTable() [行135]
           |                    |
           |                    +-- allShards() 反復 → allocs Map 構築 [行138]
           |                    +-- ノード行構築 [行150-178]
           |                    +-- UNASSIGNED行 [行180-193]
           |
           +-- RestTable.buildResponse()
```

### データフロー図

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

GET /_cat/allocation    --->  ClusterStateRequest         --->  テキストテーブル
                                 |                              (ノード数 + UNASSIGNED行)
                                 v
                          RoutingTable → allShards()
                          → ノードIDごとのシャード数集計
                                 |
                          NodesStatsRequest (FS + Store)
                                 |
                                 v
                          ノードごとのディスク情報
                                 |
                                 v
                          buildTable() → Table
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestAllocationAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestAllocationAction.java` | ソース | Allocation Report メイン処理 |
| AbstractCatAction.java | `server/src/main/java/org/opensearch/rest/action/cat/AbstractCatAction.java` | ソース | Cat API共通基底クラス |
| ShardRouting.java | `server/src/main/java/org/opensearch/cluster/routing/ShardRouting.java` | ソース | シャードルーティング情報 |
| FsInfo.java | `server/src/main/java/org/opensearch/monitor/fs/FsInfo.java` | ソース | ファイルシステム情報 |
