# 画面設計書 148-Cat クラスタマネージャ

## 概要

本ドキュメントは、OpenSearchのCat クラスタマネージャAPI（GET /_cat/cluster_manager）の画面設計書である。クラスタマネージャノードの情報をテーブル形式で返すREST APIエンドポイントの仕様を定義する。

### 本画面の処理概要

本APIは、現在のクラスタマネージャ（マスター）ノードのID、ホスト名、IPアドレス、ノード名を人間が読みやすいテーブル形式で返す。

**業務上の目的・背景**：クラスタマネージャノードはOpenSearchクラスタの管理・調整を担う重要なノードである。運用時にどのノードがクラスタマネージャとして選出されているかを素早く確認する手段が必要である。特にクラスタマネージャの切り替え（フェイルオーバー）が発生した際の状況確認や、クラスタの健全性チェックに利用される。

**画面へのアクセス方法**：REST APIクライアント（curl等）から `GET /_cat/cluster_manager` エンドポイントにリクエストを送信する。旧パス `GET /_cat/master` も利用可能だが非推奨。

**主要な操作・処理内容**：
1. クライアントがGETリクエストを送信する
2. ClusterStateRequestでノード情報を取得する
3. クラスタマネージャノードIDからDiscoveryNode情報を取得する
4. テーブル形式でid、host、ip、nodeの情報を返却する

**画面遷移**：「クラスタヘルス」（No.90）でクラスタ状態を確認した後、本APIで現在のクラスタマネージャを特定する。「ノード情報」（No.107）でノードの詳細を確認する。

**権限による表示制御**：クラスタ状態の参照権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 53 | クラスタマネージャ選出 | 主機能 | クラスタマネージャノードの情報を返す処理 |

## 画面種別

詳細表示（API）

## URL/ルーティング

| メソッド | パス | 説明 | 備考 |
|---------|------|------|------|
| GET | `/_cat/cluster_manager` | クラスタマネージャノード情報を返す | 推奨 |
| GET | `/_cat/master` | クラスタマネージャノード情報を返す | 非推奨（v2.0.0） |

## 入出力項目

### クエリパラメータ

| 項目名 | 型 | 必須 | デフォルト | 説明 |
|--------|-----|------|-----------|------|
| format | string | No | - | レスポンス形式（json、yaml等） |
| local | boolean | No | false | ローカル情報を返す |
| cluster_manager_timeout | time | No | - | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | No | - | （非推奨）cluster_manager_timeoutを使用 |
| h | list | No | - | 表示するカラム名のカンマ区切りリスト |
| help | boolean | No | false | カラムヘルプ情報を返す |
| s | list | No | - | ソートするカラム名のカンマ区切りリスト |
| v | boolean | No | false | 詳細モード（カラムヘッダ表示） |

## 表示項目

### テーブルカラム

| カラム名 | エイリアス | 説明 |
|---------|----------|------|
| id | - | クラスタマネージャノードのID |
| host | h | ホスト名 |
| ip | - | IPアドレス |
| node | n | ノード名 |

## イベント仕様

### 1-クラスタマネージャ情報取得

1. クライアントがGET /_cat/cluster_managerにリクエストを送信する
2. RestClusterManagerActionがリクエストを受け付ける
3. ClusterStateRequest.clear().nodes(true)でノード情報のみ取得（行78-79）
4. localパラメータとcluster_manager_timeoutパラメータを設定（行80-84）
5. ClusterStateResponseからDiscoveryNodesを取得（行113）
6. getClusterManagerNodeId()でクラスタマネージャノードIDを取得（行116）
7. クラスタマネージャノードが存在する場合はid、hostName、hostAddress、nameを設定（行122-126）
8. クラスタマネージャノードが存在しない場合は全カラムに`-`を設定（行118-121）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| クラスタマネージャ情報取得 | ClusterState | SELECT | クラスタ状態のノード情報を参照するのみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| - | 成功 | テーブル形式のクラスタマネージャ情報 | 正常に情報が取得された場合 |
| - | 情報 | 全カラム `-` | クラスタマネージャが未選出の場合 |

## 例外処理

| 例外 | 状況 | HTTPステータス |
|------|------|---------------|
| ClusterManagerNodeTimeout | クラスタマネージャノードへの接続タイムアウト | 504 |

## 備考

- API安定性: stable
- canTripCircuitBreakerがfalse（行95-97）であり、サーキットブレーカーをトリップしない
- /_cat/masterパスはv2.0.0で非推奨。包括的言語（inclusive language）の推進のためcluster_managerに変更された
- クラスタマネージャが未選出の場合でもエラーではなく、全カラムに`-`が表示される
- ReplacedRouteを使用して旧パスとの互換性を維持している（行63）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cat.cluster_manager.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cat.cluster_manager.json` | REST API仕様。非推奨パスの定義も含めて確認する |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestClusterManagerAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestClusterManagerAction.java` | メイン実装。ReplacedRouteによるパス互換（行63）、ClusterStateRequest構築（行78-84）、テーブル構築（行100-131） |

**主要処理フロー**:
1. **行63**: ReplacedRouteで /_cat/cluster_manager と旧 /_cat/master を定義
2. **行78-79**: ClusterStateRequest.clear().nodes(true) でノード情報のみ取得
3. **行80-84**: localとcluster_manager_timeoutパラメータ設定
4. **行100-108**: テーブルヘッダ定義（id, host, ip, node）
5. **行111-131**: buildTableでクラスタマネージャノード情報を取得し1行のテーブルを構築
6. **行116-127**: クラスタマネージャnullチェック後、情報またはハイフンを設定

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

```
RestClusterManagerAction.doCatRequest() [行77-92]
    |
    +-- ClusterStateRequest.clear().nodes(true) [行78-79]
    |
    +-- client.admin().cluster().state() [行86]
            |
            +-- RestResponseListener.buildResponse() [行88]
                    |
                    +-- buildTable(request, clusterStateResponse) [行111]
                    |   +-- DiscoveryNodes取得 [行113]
                    |   +-- getClusterManagerNodeId() [行116]
                    |   +-- nullチェック→id/host/ip/node設定 [行117-127]
                    |
                    +-- RestTable.buildResponse() [行89]
```

### データフロー図

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

GET /_cat/cluster_manager --> RestClusterManagerAction
                               |
                               +-- ClusterStateRequest
                               |   (ノード情報のみ取得)
                               |
                               +-- buildTable()          --> テーブル形式レスポンス
                                   (CM NodeId→DiscoveryNode)    id | host | ip | node
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cat.cluster_manager.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cat.cluster_manager.json` | API仕様 | REST API仕様定義 |
| RestClusterManagerAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestClusterManagerAction.java` | ソース | メイン実装 |
| AbstractCatAction.java | `server/src/main/java/org/opensearch/rest/action/cat/AbstractCatAction.java` | ソース | Cat API基底クラス |
| ClusterStateRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/state/ClusterStateRequest.java` | ソース | クラスタ状態リクエスト |
| DiscoveryNode.java | `server/src/main/java/org/opensearch/cluster/node/DiscoveryNode.java` | ソース | ノード情報 |
| DiscoveryNodes.java | `server/src/main/java/org/opensearch/cluster/node/DiscoveryNodes.java` | ソース | ノード集合管理 |
