# 画面設計書 9-Environment（環境情報）

## 概要

本ドキュメントは、Apache Spark Web UIの「Environment（環境情報）」画面の設計書である。JVM情報・Sparkプロパティ・Hadoopプロパティ・システムプロパティ・メトリクスプロパティ・クラスパス・リソースプロファイルを表示する。

### 本画面の処理概要

**業務上の目的・背景**：Sparkアプリケーションの実行環境情報を一元的に確認するための画面である。JVMバージョン、Sparkの設定値、Hadoopの設定値、JVMシステムプロパティ、メトリクス設定、クラスパスエントリー、リソースプロファイルを確認できる。設定ミスの検出やデバッグ時の環境確認に使用される。セキュリティ上、機密情報を含む設定値はマスク処理（Utils.redact）されて表示される。

**画面へのアクセス方法**：SparkアプリケーションWeb UIのナビゲーションバーから「Environment」タブを選択してアクセスする。

**主要な操作・処理内容**：
1. Runtime Information テーブル表示（Java Version、Java Home、Scala Version）
2. Spark Properties テーブル表示（機密情報マスク済み、ソート可能）
3. Resource Profiles テーブル表示（Executor/Taskリソース要求）
4. Hadoop Properties テーブル表示（デフォルト折りたたみ、機密情報マスク済み）
5. System Properties テーブル表示（デフォルト折りたたみ、機密情報マスク済み）
6. Metrics Properties テーブル表示（デフォルト折りたたみ、機密情報マスク済み）
7. Classpath Entries テーブル表示（デフォルト折りたたみ）

**画面遷移**：
- この画面からの遷移先：なし
- この画面への遷移元：全画面からのナビゲーションバー経由

**権限による表示制御**：機密情報（パスワード、トークン等）を含むプロパティ値はUtils.redactによりマスク処理される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Spark Web UI | 主機能 | JVM情報・Sparkプロパティ・Hadoopプロパティ・システムプロパティ等を分類表示する主処理 |
| 12 | メトリクスシステム | 補助機能 | メトリクスプロパティ（metrics.properties）をテーブル表示 |
| 14 | セキュリティ管理 | 補助機能 | セキュリティ関連のSparkプロパティ値を機密情報マスク処理（Utils.redact）して表示 |
| 95 | KVStore | API連携 | AppStatusStore.environmentInfo()経由で環境情報を非同期取得 |

## 画面種別

一覧（参照専用）

## URL/ルーティング

- パス: `/environment/`
- クラス: `EnvironmentPage` (WebUIPage(""))
- タブ: `EnvironmentTab` (SparkUITab(parent, "environment"))

## 入出力項目

本画面はURLパラメータを受け取らない。

## 表示項目

### Runtime Information テーブル（デフォルト展開）

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| Java Version | appEnv.runtime.javaVersion | JDKのバージョン |
| Java Home | appEnv.runtime.javaHome | JDKのホームディレクトリパス |
| Scala Version | appEnv.runtime.scalaVersion | Scalaのバージョン |

### Spark Properties テーブル（デフォルト展開）

| カラム名 | 説明 |
|----------|------|
| Name | Sparkプロパティ名（spark.*） |
| Value | プロパティ値（機密情報はUtils.redactでマスク済み） |

ソート可能（両カラムともsorttable_alpha）。

### Resource Profiles テーブル（デフォルト展開）

| カラム名 | 説明 |
|----------|------|
| Resource Profile Id | リソースプロファイルID（sorttable_numeric） |
| Resource Profile Contents | Executor/Taskリソース要求の詳細（pre表示、sorttable_nosort） |

Resource Profile Contentsは以下の形式で表示される:
```
Executor Reqs:
    {resourceName}: [amount: {amount}, discovery: {discoveryScript}, vendor: {vendor}]
Task Reqs:
    {resourceName}: [amount: {amount}]
```

### Hadoop Properties テーブル（デフォルト折りたたみ）

| カラム名 | 説明 |
|----------|------|
| Name | Hadoopプロパティ名 |
| Value | プロパティ値（機密情報マスク済み） |

### System Properties テーブル（デフォルト折りたたみ）

| カラム名 | 説明 |
|----------|------|
| Name | JVMシステムプロパティ名 |
| Value | プロパティ値（機密情報マスク済み） |

### Metrics Properties テーブル（デフォルト折りたたみ）

| カラム名 | 説明 |
|----------|------|
| Name | メトリクスプロパティ名 |
| Value | プロパティ値（機密情報マスク済み） |

### Classpath Entries テーブル（デフォルト折りたたみ）

| カラム名 | 説明 |
|----------|------|
| Resource | クラスパスリソース名 |
| Source | ソース情報 |

## イベント仕様

### 1-テーブルセクションの折りたたみ/展開

各テーブルセクションのヘッダーをクリックすると、テーブルの表示/非表示が切り替わる。デフォルト状態は以下の通り：
- **展開（arrow-open）**: Runtime Information、Spark Properties、Resource Profiles
- **折りたたみ（arrow-closed）**: Hadoop Properties、System Properties、Metrics Properties、Classpath Entries

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | KVStore (AppStatusStore) | SELECT | 環境情報・リソースプロファイル情報の読み取り |

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

本画面はデータの読み取り専用である。

## メッセージ仕様

特記すべきメッセージはない。

## 例外処理

特記すべき例外処理はない。Hadoopプロパティやメトリクスプロパティが存在しない場合はOption(...)でemptyPropertiesが使用される。

## 備考

- 全てのプロパティテーブルはUtils.redact(conf, ...)による機密情報マスク処理を経由して表示される
- Hadoop Properties / Metrics Propertiesはnullの可能性があるためOption()でラップされている（82行目、88行目）
- 各プロパティテーブルのデータはsortedで名前順にソートされて表示される
- Resource ProfileのContentsは`<pre>`タグで整形表示される（184行目: jvmRowDataPre）
- environmentpage.jsがページに読み込まれる（172行目）
- EnvironmentTabクラスはEnvironmentPage.scalaファイル内に同居して定義されている（191-195行目）
- プロパティテーブルのヘッダーCSSクラスは"sorttable_alpha"（文字列ソート対応）
- リソースプロファイルテーブルのContentsカラムは"sorttable_nosort"（ソート不可）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | api.scala | `core/src/main/scala/org/apache/spark/status/api/v1/api.scala` | ApplicationEnvironmentInfo（runtime, sparkProperties, hadoopProperties, systemProperties, metricsProperties, classpathEntries）の構造 |
| 1-2 | AppStatusStore.scala | `core/src/main/scala/org/apache/spark/status/AppStatusStore.scala` | environmentInfo(), resourceProfileInfo()のAPI |

**読解のコツ**: ApplicationEnvironmentInfoのプロパティフィールドはSeq[(String, String)]型のキーバリューペア。RuntimeInfoはjavaVersion, javaHome, scalaVersionのケースクラス。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | EnvironmentPage.scala | `core/src/main/scala/org/apache/spark/ui/env/EnvironmentPage.scala` | renderメソッド（36行目）が主処理 |

**主要処理フロー**:
1. **37行目**: `store.environmentInfo()` で環境情報を取得
2. **38-41行目**: JVM情報をMap形式で構築（Java Version, Java Home, Scala Version）
3. **43-56行目**: constructExecutorRequestString/constructTaskRequestStringでリソースプロファイルの文字列表現を構築
4. **64-69行目**: `store.resourceProfileInfo()` でリソースプロファイル一覧を取得し、文字列表現に変換
5. **71-73行目**: resourceProfileInformationTableを生成
6. **74-76行目**: runtimeInformationTableを生成
7. **77-78行目**: sparkPropertiesTableを生成（Utils.redact適用）
8. **81-83行目**: hadoopPropertiesTableを生成（null安全処理+Utils.redact）
9. **84-86行目**: systemPropertiesTableを生成（Utils.redact適用）
10. **87-89行目**: metricsPropertiesTableを生成（null安全処理+Utils.redact）
11. **90-92行目**: classpathEntriesTableを生成
12. **93-173行目**: 全テーブルをHTMLに結合（折りたたみ制御付き）
13. **175行目**: UIUtils.headerSparkPageでページをラップ

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

```
EnvironmentPage.render(request)
    |
    +-- store.environmentInfo()                ... 環境情報取得
    |     +-- .runtime                         ... JVM情報
    |     +-- .sparkProperties                 ... Sparkプロパティ
    |     +-- .hadoopProperties                ... Hadoopプロパティ
    |     +-- .systemProperties                ... システムプロパティ
    |     +-- .metricsProperties               ... メトリクスプロパティ
    |     +-- .classpathEntries                ... クラスパスエントリ
    |
    +-- store.resourceProfileInfo()            ... リソースプロファイル取得
    |     +-- constructExecutorRequestString() ... Executor要求文字列化
    |     +-- constructTaskRequestString()     ... Task要求文字列化
    |
    +-- Utils.redact(conf, properties)         ... 機密情報マスク処理
    |     （sparkProperties, hadoopProperties, systemProperties, metricsProperties）
    |
    +-- UIUtils.listingTable()                 ... 各テーブルHTML生成（7回）
    |
    +-- UIUtils.headerSparkPage()              ... ページラップ
```

### データフロー図

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

HttpServletRequest ---> EnvironmentPage.render()
                            |
KVStore              --> environmentInfo()          --> runtime / properties
                     --> resourceProfileInfo()       --> リソースプロファイル
                            |
SparkConf            --> Utils.redact()             --> マスク済みプロパティ
                            |
                            v
                        HTML(Seq[Node])             --> 7つの折りたたみテーブル
                            |
                        environmentpage.js          --> ブラウザ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| EnvironmentPage.scala | `core/src/main/scala/org/apache/spark/ui/env/EnvironmentPage.scala` | ソース | 画面のメインページクラスとEnvironmentTab定義 |
| AppStatusStore.scala | `core/src/main/scala/org/apache/spark/status/AppStatusStore.scala` | ソース | データアクセス層 |
| api.scala | `core/src/main/scala/org/apache/spark/status/api/v1/api.scala` | ソース | ApplicationEnvironmentInfo, RuntimeInfoデータモデル |
| Utils.scala | `core/src/main/scala/org/apache/spark/util/Utils.scala` | ソース | redact関数（機密情報マスク） |
| environmentpage.js | `core/src/main/resources/org/apache/spark/ui/static/environmentpage.js` | JavaScript | 環境情報ページ用JavaScript |
| UIUtils.scala | `core/src/main/scala/org/apache/spark/ui/UIUtils.scala` | ソース | HTML生成ユーティリティ |
