# 画面設計書 109-ノード使用状況

## 概要

本ドキュメントは、OpenSearchクラスタ内のノードにおけるRESTアクション使用状況を取得するREST APIエンドポイント `GET /_nodes/usage` の設計を記述する。

### 本画面の処理概要

本APIは、各ノードで実行されたRESTアクションの使用回数やアグリゲーション使用状況等の低レベル使用状況統計を返すエンドポイントである。

**業務上の目的・背景**：クラスタの利用パターンを分析するために、どのREST APIエンドポイントが最も頻繁に呼び出されているかを把握する必要がある。これにより、不要なAPIコールの特定、パフォーマンスチューニングのための優先順位付け、API利用状況に基づくキャパシティプランニング等が可能となる。また、非推奨APIの使用状況を確認し、マイグレーション計画の策定にも活用される。

**画面へのアクセス方法**：HTTPクライアントから `GET /_nodes/usage` または `GET /_nodes/{nodeId}/usage/{metric}` にGETリクエストを送信する。

**主要な操作・処理内容**：
1. URLパスパラメータからノードIDとメトリクスを取得する
2. メトリクスに基づいて取得する使用状況情報を選択する
3. 各ノードに使用状況情報取得リクエストを転送する
4. 収集結果をJSON形式で返却する

**画面遷移**：関連するAPIとして、ノード情報（No.107）、ノード統計（No.108）がある。

**権限による表示制御**：クラスタレベルのモニタリング権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | ノード情報・統計 | 主機能 | ノードのRESTアクション使用状況を返す処理 |

## 画面種別

情報取得（GET）API

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_nodes/usage` | 全ノードの全使用状況を取得 |
| GET | `/_nodes/{nodeId}/usage` | 指定ノードの全使用状況を取得 |
| GET | `/_nodes/usage/{metric}` | 全ノードの指定メトリクスを取得 |
| GET | `/_nodes/{nodeId}/usage/{metric}` | 指定ノードの指定メトリクスを取得 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| nodeId | list(string) | No | ノードIDのカンマ区切りリスト |
| metric | list(string) | No | メトリクスのカンマ区切りリスト（`_all`, `rest_actions`） |

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|-----|------|-----------|------|
| timeout | time | No | - | 操作タイムアウト |

## 表示項目

### レスポンスボディ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| _nodes | object | リクエスト結果概要 |
| cluster_name | string | クラスタ名 |
| nodes | object | ノードIDをキー、使用状況情報を値とするマップ |
| nodes.{id}.since | long | 統計収集開始時刻（エポックミリ秒） |
| nodes.{id}.rest_actions | object | RESTアクション名をキー、呼び出し回数を値とするマップ |
| nodes.{id}.aggregations | object | アグリゲーション使用状況 |

### レスポンス例

```json
{
  "_nodes": { "total": 1, "successful": 1, "failed": 0 },
  "cluster_name": "my-cluster",
  "nodes": {
    "node-id-1": {
      "since": 1609459200000,
      "rest_actions": {
        "org.opensearch.rest.action.search.RestSearchAction": 1523,
        "org.opensearch.rest.action.document.RestIndexAction": 845
      },
      "aggregations": {}
    }
  }
}
```

## イベント仕様

### 1-GETリクエスト受信

1. `RestNodesUsageAction.prepareRequest()` がリクエストを受信する
2. `nodeId` と `metric` パラメータを解析する
3. `NodesUsageRequest` を構築する
4. メトリクスが `_all` の場合は全情報を有効化、そうでなければ `rest_actions` と `aggregations` を個別設定する
5. Transport層経由で各ノードにリクエストを転送する
6. レスポンスを構築して返却する

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| GETリクエスト | 各ノードのメモリ内使用状況統計 | SELECT | RESTアクション使用回数等の読み取り |

## メッセージ仕様

| 種別 | メッセージ | 条件 |
|------|----------|------|
| 成功 | 200 OK + JSONレスポンス | 正常に使用状況を取得できた場合 |
| エラー | "request [...] contains _all and individual metrics [...]" | `_all` と個別メトリクスが混在指定された場合 |

## 例外処理

| 例外条件 | HTTPステータス | レスポンス内容 |
|---------|---------------|---------------|
| _allと個別メトリクス混在 | 400 Bad Request | IllegalArgumentException |
| タイムアウト | 408 Request Timeout | タイムアウトエラー |

## 備考

- レスポンスの構築は `RestBuilderListener` を使用したカスタムビルドで行われ、`NodesResponseRestListener` とは異なる
- `canTripCircuitBreaker()` が `false` を返すため、サーキットブレーカーをトリップしない
- `rest_actions` のキーはRESTアクションの完全修飾クラス名であり、APIエンドポイント名ではない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NodesUsageRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/NodesUsageRequest.java` | リクエスト構造。`restActions`, `aggregations` フラグ |
| 1-2 | NodesUsageResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/NodesUsageResponse.java` | レスポンス構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestNodesUsageAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestNodesUsageAction.java` | ルート定義（行65-74）と `prepareRequest()`（行77-114） |

**主要処理フロー**:
1. **行78-79**: nodeIdとmetricを解析
2. **行81-82**: `NodesUsageRequest` を構築、タイムアウトを設定
3. **行84-85**: `_all` の場合は全情報を有効化
4. **行96-98**: 個別メトリクスの場合、`rest_actions` と `aggregations` を個別設定
5. **行101-113**: カスタムレスポンスビルダーでNodesHeader、cluster_name、ノード使用状況を構築

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportNodesUsageAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java` | 各ノードでの使用状況情報収集 |

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

```
RestNodesUsageAction.prepareRequest()
    |
    +-- NodesUsageRequest(nodesIds)
    |       +-- .all() or .restActions() / .aggregations()
    |
    +-- NodeClient.admin().cluster().nodesUsage()
            |
            +-- TransportNodesUsageAction
            |       +-- NodeUsage [on each node]
            |
            +-- RestBuilderListener<NodesUsageResponse>
                    +-- RestActions.buildNodesHeader()
                    +-- response.toXContent()
```

### データフロー図

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

GET request           --> RestNodesUsageAction            --> NodesUsageRequest
  nodeId (opt)            .prepareRequest()
  metric (opt)

                      --> TransportNodesUsageAction       --> NodesUsageResponse
                          [各ノードに分散実行]                  { _nodes, cluster_name,
                                                                nodes: { rest_actions, ... } }

                      --> RestBuilderListener             --> HTTP 200 JSON Response
                          カスタムレスポンスビルド
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestNodesUsageAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestNodesUsageAction.java` | ソース | RESTエンドポイント定義 |
| NodesUsageRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/NodesUsageRequest.java` | ソース | リクエストオブジェクト |
| NodesUsageResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/NodesUsageResponse.java` | ソース | レスポンスオブジェクト |
| NodeUsage.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/NodeUsage.java` | ソース | 個別ノード使用状況 |
| TransportNodesUsageAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/usage/TransportNodesUsageAction.java` | ソース | Transport層ロジック |
| nodes.usage.json | `rest-api-spec/src/main/resources/rest-api-spec/api/nodes.usage.json` | 設定 | REST APIスペック定義 |
