# 画面設計書 90-クラスタヘルス

## 概要

本ドキュメントは、OpenSearchのクラスタヘルス（Cluster Health）REST APIエンドポイントの画面設計書である。クラスタの健全性情報（green/yellow/red）を取得し、待機条件を指定して状態変化を監視するAPIである。

### 本画面の処理概要

クラスタヘルスAPIは、クラスタ全体またはインデックス単位のヘルス情報を返す。ヘルスステータス（green/yellow/red）、ノード数、シャード数、未割り当てシャード数などの基本的なクラスタ状態指標を提供する。さらに、`wait_for_*`パラメータ群によりクラスタが特定の状態になるまで待機するポーリング機能も備えている。

**業務上の目的・背景**：クラスタヘルスの監視はOpenSearch運用の最も基本的かつ重要な操作である。ヘルスステータスがgreenであれば全シャードが正常に割り当てられており、yellowはレプリカの一部が未割り当て、redはプライマリシャードの一部が利用不可であることを示す。本APIは監視ツールからの定期的なヘルスチェック、デプロイメントパイプラインでのクラスタ準備完了確認、障害検知の第一段階として広く使用される。また、`level`パラメータで`awareness_attributes`を指定することで、アウェアネス属性に基づくヘルス情報も取得可能である。

**画面へのアクセス方法**：HTTPクライアントから `GET /_cluster/health` または `GET /_cluster/health/{index}` エンドポイントへリクエストを送信する。

**主要な操作・処理内容**：
1. クラスタ全体のヘルスステータス（green/yellow/red）を取得する
2. 特定インデックスのヘルス情報に絞り込んで取得する
3. `level`パラメータで詳細度を制御する（cluster/indices/shards/awareness_attributes）
4. `wait_for_status`で特定のヘルスステータスになるまで待機する
5. `wait_for_nodes`で特定のノード数になるまで待機する
6. `wait_for_active_shards`で特定のアクティブシャード数になるまで待機する
7. `wait_for_no_relocating_shards`でリロケーション完了を待機する
8. `wait_for_no_initializing_shards`で初期化完了を待機する
9. `wait_for_events`で特定優先度のイベント処理完了を待機する

**画面遷移**：クラスタ状態（No.91）で詳細な状態情報を確認する。クラスタ統計（No.92）で統計概要を取得する。アロケーション説明（No.95）でシャード割り当て問題を診断する。Cat ヘルス（No.151）はテーブル形式の簡潔な表示を返す。リカバリ情報（No.84）でシャードリカバリの進捗を確認する。

**権限による表示制御**：クラスタの監視権限が必要である。本APIは`allowSystemIndexAccessByDefault()`が`true`を返すため、システムインデックスへのアクセスがデフォルトで許可されている。サーキットブレーカーをトリップさせない（`canTripCircuitBreaker()` = false）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 47 | クラスタヘルス | 主機能 | クラスタのヘルス情報（green/yellow/red）を返す処理 |
| 55 | Awareness Health | 補助機能 | アウェアネス属性に基づくヘルス監視情報の付加処理 |

## 画面種別

情報取得（APIエンドポイント）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_cluster/health` | クラスタ全体のヘルス情報を取得 |
| GET | `/_cluster/health/{index}` | 指定インデックスのヘルス情報を取得 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | list | 任意 | ヘルス情報を限定するインデックス名 |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| level | enum | cluster | 返却情報の詳細レベル（cluster/indices/shards/awareness_attributes） |
| local | boolean | false | ローカルノードの情報のみを返すか（クラスタマネージャから取得しない） |
| timeout | time | 30s | 明示的な操作タイムアウト |
| cluster_manager_timeout | time | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | 30s | 非推奨（cluster_manager_timeoutを使用すること） |
| wait_for_status | enum | - | 指定したヘルスステータスになるまで待機（green/yellow/red） |
| wait_for_nodes | string | - | 指定したノード数になるまで待機（例：`>=3`） |
| wait_for_active_shards | string | - | 指定したアクティブシャード数になるまで待機 |
| wait_for_events | enum | - | 指定優先度のキューイベント処理完了まで待機（immediate/urgent/high/normal/low/languid） |
| wait_for_no_relocating_shards | boolean | false | リロケーション中のシャードがなくなるまで待機するか |
| wait_for_no_initializing_shards | boolean | false | 初期化中のシャードがなくなるまで待機するか |
| expand_wildcards | enum | all | ワイルドカード展開の対象（open/closed/hidden/none/all） |
| awareness_attribute | string | - | ヘルスが必要なアウェアネス属性 |
| ensure_node_weighed_in | boolean | false | ローカルノードがコミッションされウェイトインされているか確認するか |

## 表示項目

### レスポンス

| フィールド | 型 | 説明 |
|-----------|------|------|
| cluster_name | string | クラスタ名 |
| status | string | ヘルスステータス（green/yellow/red） |
| timed_out | boolean | wait_for_*のタイムアウトが発生したか |
| number_of_nodes | integer | クラスタ内のノード数 |
| number_of_data_nodes | integer | データノード数 |
| discovered_master | boolean | クラスタマネージャが検出されているか |
| discovered_cluster_manager | boolean | クラスタマネージャが検出されているか |
| active_primary_shards | integer | アクティブなプライマリシャード数 |
| active_shards | integer | アクティブなシャード総数 |
| relocating_shards | integer | リロケーション中のシャード数 |
| initializing_shards | integer | 初期化中のシャード数 |
| unassigned_shards | integer | 未割り当てシャード数 |
| delayed_unassigned_shards | integer | 遅延未割り当てシャード数 |
| number_of_pending_tasks | integer | 保留中のクラスタタスク数 |
| number_of_in_flight_fetch | integer | 進行中のフェッチ数 |
| task_max_waiting_in_queue_millis | long | タスクキュー内の最大待機時間（ミリ秒） |
| active_shards_percent_as_number | double | アクティブシャードの割合（%） |

## イベント仕様

### 1-ヘルス情報取得（即時）

wait_for_*パラメータが指定されない場合、クライアントのリクエストに対して即座にクラスタヘルス情報が返却される。`RestClusterHealthAction.prepareRequest()`（83行目）で`ClusterHealthRequest`が構築され、`client.admin().cluster().health()`を通じて実行される。

### 2-ヘルス情報取得（待機）

wait_for_*パラメータが指定された場合、指定条件が満たされるかタイムアウトするまでブロッキングで待機する。`timed_out`フィールドでタイムアウトの有無を確認できる。

### 3-レベル制御

`level`パラメータにより返却情報の粒度が変わる。`cluster`（デフォルト）はクラスタ全体、`indices`は各インデックスのヘルス、`shards`は各シャードのヘルス、`awareness_attributes`はアウェアネス属性別のヘルスが追加される。`setApplyLevelAtTransportLayer(true)`（108行目）によりトランスポート層でフィルタリングが適用される。

### 4-非推奨パラメータ警告

`master_timeout`パラメータが使用された場合、98行目の`parseDeprecatedMasterTimeoutParameter()`により非推奨警告が出力される。代わりに`cluster_manager_timeout`を使用すべきである。

### 5-wait_for_relocating_shardsエラー

旧パラメータ`wait_for_relocating_shards`が使用された場合、119-123行目で`IllegalArgumentException`がスローされる。`wait_for_no_relocating_shards`を使用すべきである。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ヘルス情報取得 | - | SELECT | 読み取り専用。データ更新なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ | 発生条件 |
|-------------|------|-----------|---------|
| - | 成功 | `{"cluster_name":"...","status":"green",...}` | ヘルス情報正常取得 |
| - | 成功（タイムアウト） | `{"cluster_name":"...","timed_out":true,...}` | wait_for_*条件がタイムアウト |
| - | エラー | `wait_for_relocating_shards has been removed` | 旧パラメータ使用時 |
| - | 警告 | master_timeout非推奨警告 | master_timeoutパラメータ使用時 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| IllegalArgumentException | 400 | wait_for_relocating_shardsパラメータ使用時 |
| IllegalArgumentException | 400 | 無効なwait_for_statusまたはwait_for_events値 |
| ClusterManagerNotDiscoveredException | 503 | クラスタマネージャが未検出の場合 |

## 備考

- クラスタヘルスAPIは最も基本的な監視APIであり、運用監視ツールから最も頻繁に呼び出される。
- `expand_wildcards`のデフォルト値は`all`であり、他のインデックスAPI（通常は`open`）とは異なる。
- `wait_for_status`等のポーリング機能は、デプロイメントパイプラインでのクラスタ準備完了確認に便利。
- `master_timeout`は非推奨であり、`cluster_manager_timeout`を使用すること。
- `wait_for_relocating_shards`は削除済みであり、`wait_for_no_relocating_shards`を使用すること。
- レスポンスのHTTPステータスコードは`RestStatusToXContentListener`を使用するため、ヘルスステータスに応じたHTTPステータスが返される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cluster.health.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json` | REST APIの仕様定義。wait_for_*パラメータ群とlevelの選択肢を把握 |
| 1-2 | ClusterHealthRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthRequest.java` | リクエストデータ構造。待機条件の各フィールドを確認 |
| 1-3 | ClusterHealthResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthResponse.java` | レスポンスデータ構造。各ヘルス指標フィールドを確認 |

**読解のコツ**: `ClusterHealthRequest`には多数のwait_for_*フィールドがあり、これらはすべてポーリング条件として使用される。`RestStatusToXContentListener`を使用しているため、レスポンスのHTTPステータスコードがヘルスステータスに連動する点に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestClusterHealthAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterHealthAction.java` | RESTハンドラ。fromRequest()メソッド（88-134行目）が核心。多数のパラメータ解析ロジック |

**主要処理フロー**:
1. **69行目**: `routes()`で`GET /_cluster/health`と`GET /_cluster/health/{index}`を登録
2. **78-80行目**: `allowSystemIndexAccessByDefault()`がtrueを返す
3. **83-86行目**: `prepareRequest()`で`fromRequest()`を呼び出し、`RestStatusToXContentListener`でレスポンス返却
4. **88-134行目**: `fromRequest()`で全パラメータを解析
   - **89行目**: indexパラメータからClusterHealthRequestを構築
   - **90行目**: indicesOptionsを設定
   - **91行目**: localフラグ設定
   - **92-94行目**: ensure_node_weighed_inフラグ設定
   - **95-98行目**: cluster_manager_timeout設定と非推奨master_timeout処理
   - **99行目**: timeout設定
   - **100-103行目**: awareness_attribute設定
   - **104-107行目**: level設定
   - **108行目**: setApplyLevelAtTransportLayer(true)
   - **109-112行目**: wait_for_status設定（ClusterHealthStatus列挙値に変換）
   - **113-118行目**: wait_for_no_relocating_shards/wait_for_no_initializing_shards設定
   - **119-124行目**: 旧パラメータwait_for_relocating_shardsのエラー処理
   - **125-128行目**: wait_for_active_shards設定
   - **129行目**: wait_for_nodes設定
   - **130-132行目**: wait_for_events設定

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

```
RestClusterHealthAction.prepareRequest() [L83-86]
    |
    +-- fromRequest() [L88-134]
    |       +-- clusterHealthRequest() [L89]
    |       +-- IndicesOptions.fromRequest() [L90]
    |       +-- local() [L91]
    |       +-- ensureNodeWeighedIn() [L92-94]
    |       +-- clusterManagerNodeTimeout() [L95-97]
    |       +-- parseDeprecatedMasterTimeoutParameter() [L98]
    |       +-- timeout() [L99]
    |       +-- setAwarenessAttribute() [L100-103]
    |       +-- setLevel() [L104-107]
    |       +-- setApplyLevelAtTransportLayer(true) [L108]
    |       +-- waitForStatus() [L109-112]
    |       +-- waitForNoRelocatingShards() [L113-115]
    |       +-- waitForNoInitializingShards() [L116-118]
    |       +-- [旧パラメータエラー] [L119-124]
    |       +-- waitForActiveShards() [L125-128]
    |       +-- waitForNodes() [L129]
    |       +-- waitForEvents() [L130-132]
    |
    +-- client.admin().cluster().health() [L85]
            |
            +-- RestStatusToXContentListener [HTTPステータス連動レスポンス]
            |
            +-- TransportClusterHealthAction.execute()
                    +-- ClusterStateObserver [待機条件の監視]
```

### データフロー図

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

HTTP GET /_cluster/health/{index}    RestClusterHealthAction             ClusterHealthResponse
  +-- index (path)              ---> .fromRequest() [L88]           ---> {cluster_name,
  +-- level (query)                  ClusterHealthRequest [構築]          status,
  +-- wait_for_status (query)        TransportClusterHealthAction         number_of_nodes,
  +-- wait_for_nodes (query)         ClusterStateObserver [待機]           active_shards,
  +-- timeout (query)                RestStatusToXContentListener          unassigned_shards,
  +-- awareness_attribute                                                  ...}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cluster.health.json | `rest-api-spec/src/main/resources/rest-api-spec/api/cluster.health.json` | API仕様 | REST APIの仕様定義 |
| RestClusterHealthAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterHealthAction.java` | ソース | RESTハンドラ（パラメータ解析ロジック） |
| ClusterHealthRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthRequest.java` | ソース | リクエストデータ構造 |
| ClusterHealthResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthResponse.java` | ソース | レスポンスデータ構造 |
| TransportClusterHealthAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/TransportClusterHealthAction.java` | ソース | トランスポートアクション |
| ClusterHealthStatus.java | `server/src/main/java/org/opensearch/cluster/health/ClusterHealthStatus.java` | ソース | ヘルスステータス列挙値 |
| RestClusterHealthActionTests.java | `server/src/test/java/org/opensearch/rest/action/admin/cluster/RestClusterHealthActionTests.java` | テスト | RESTハンドラのテスト |
