# 画面設計書 44-インデックスブロック追加

## 概要

本ドキュメントは、OpenSearchのインデックスブロック追加API（PUT /{index}/_block/{block}）の設計仕様を記述する。

### 本画面の処理概要

本APIは、インデックスに対してブロック（読み取り専用、書き込み禁止等）を追加するためのエンドポイントである。インデックスを完全にクローズせずに、特定の操作のみを制限することができる。

**業務上の目的・背景**：インデックスの保全やメンテナンスにおいて、データの完全なクローズではなく、部分的な操作制限が必要な場合がある。例えば、データの整合性を保つために書き込みを禁止しつつ読み取りは許可する、メタデータの変更を防止する、などのユースケースがある。インデックスクローン・縮小・分割の前提条件としてread_onlyブロックが必要となる場合もある。

**画面へのアクセス方法**：`PUT /{index}/_block/{block}` エンドポイントにHTTPリクエストを送信する。blockパラメータにはread、write、read_only、metadataのいずれかを指定する。

**主要な操作・処理内容**：
1. クライアントがPUTリクエストでインデックス名とブロック種別を指定して送信する
2. RestAddIndexBlockActionがリクエストパラメータを解析しAddIndexBlockRequestを構築する
3. IndexMetadata.APIBlock.fromName()でブロック種別を解析する
4. クラスタマネージャノードでクラスタ状態の更新（ブロックの追加）が実行される
5. 処理結果（acknowledged, shards_acknowledged, indices）をレスポンスとして返す

**画面遷移**：インデックス作成（PUT /{index}）後にブロックを追加できる。ブロック追加後、インデックスクローン（PUT /{index}/_clone/{target}）やインデックス縮小（PUT /{index}/_shrink/{target}）の前提条件として使用されることがある。

**権限による表示制御**：インデックスの管理権限が必要。クラスタブロックが設定されている場合は操作が拒否される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 124 | インデックスリードオンリー | 主機能 | インデックスにブロック（読み取り専用等）を追加する処理 |

## 画面種別

実行（インデックスブロック設定）

## URL/ルーティング

| メソッド | パス | 説明 |
|----------|------|------|
| PUT | `/{index}/_block/{block}` | 指定インデックスにブロックを追加 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | list(string) | はい | カンマ区切りのインデックス名リスト |
| block | string | はい | ブロック種別（read, write, read_only, metadata） |

### ブロック種別

| ブロック名 | 説明 |
|-----------|------|
| read | 読み取り操作をブロック |
| write | 書き込み操作をブロック |
| read_only | 読み取り専用（書き込みとメタデータ変更をブロック） |
| metadata | メタデータ操作をブロック |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| timeout | time | 30s | 操作タイムアウト |
| cluster_manager_timeout | time | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | - | 非推奨（cluster_manager_timeoutを使用） |
| ignore_unavailable | boolean | false | 利用不可能なインデックスを無視する |
| allow_no_indices | boolean | false | ワイルドカードが解決されない場合に無視する |
| expand_wildcards | enum (open, closed, hidden, none, all) | open | ワイルドカード式の展開対象 |

## 表示項目

### レスポンス

| 項目名 | 型 | 説明 |
|--------|------|------|
| acknowledged | boolean | クラスタ状態の更新が認識されたか |
| shards_acknowledged | boolean | 指定数のシャードコピーが確認されたか |
| indices | array | インデックスごとのブロック追加結果 |

## イベント仕様

### 1-インデックスブロック追加リクエスト送信

RestAddIndexBlockAction.prepareRequest()（71-83行目）がリクエストを処理する。AddIndexBlockRequestを構築し、IndexMetadata.APIBlock.fromName()でブロック種別をパースする。パラメータ（cluster_manager_timeout、timeout、indicesOptions）を設定後、client.admin().indices().addBlock()を呼び出す。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| PUT /{index}/_block/{block} | ClusterState（メモリ） | UPDATE | クラスタ状態にインデックスブロックを追加 |

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

#### ClusterState.blocks

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | ClusterBlock | 指定されたブロック種別に応じたClusterBlock | read/write/read_only/metadataのいずれか |

## メッセージ仕様

| メッセージ種別 | 条件 | HTTPステータス | 内容 |
|--------------|------|---------------|------|
| 成功 | ブロックの追加が完了 | 200 | {"acknowledged": true, "shards_acknowledged": true, "indices": [...]} |
| エラー | インデックスが見つからない | 404 | index_not_found_exception |
| エラー | 不正なブロック種別 | 400 | illegal_argument_exception |

## 例外処理

| 例外 | 条件 | 動作 |
|------|------|------|
| IndexNotFoundException | 指定インデックスが存在しない | 404エラーを返す |
| IllegalArgumentException | 不正なブロック種別を指定 | 400エラーを返す |
| ClusterBlockException | クラスタブロックが設定されている | 409エラーを返す |

## 備考

- ブロック種別はIndexMetadata.APIBlock列挙型で定義されている。
- read_onlyブロックはインデックスクローン・縮小・分割の前提条件として必要になることがある。
- master_timeoutパラメータはOpenSearch 2.0.0で非推奨。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AddIndexBlockRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/readonly/AddIndexBlockRequest.java` | APIBlockとindicesのフィールドを確認 |
| 1-2 | IndexMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexMetadata.java` | APIBlock列挙型（read, write, read_only, metadata）の定義を確認 |

**読解のコツ**: IndexMetadata.APIBlockにはfromName()静的メソッドがあり、文字列からブロック種別を解決する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestAddIndexBlockAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestAddIndexBlockAction.java` | 62行目: ルーティング定義、71行目: prepareRequest()の処理開始 |

**主要処理フロー**:
1. **62行目**: `PUT /{index}/_block/{block}` のルート登録
2. **72-75行目**: AddIndexBlockRequestの構築（APIBlock.fromName()でブロック種別パース）
3. **76-81行目**: cluster_manager_timeout、timeout、indicesOptionsの設定
4. **82行目**: client.admin().indices().addBlock()の呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportAddIndexBlockAction.java | `server/src/main/java/org/opensearch/action/admin/indices/readonly/TransportAddIndexBlockAction.java` | クラスタ状態にブロックを追加する処理 |

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

```
RestAddIndexBlockAction.prepareRequest()
    |
    +-- IndexMetadata.APIBlock.fromName(block)
    |
    +-- NodeClient.admin().indices().addBlock()
            +-- TransportAddIndexBlockAction
                    +-- MetadataIndexStateService.addIndexBlock()
                            +-- ClusterState更新（ブロック追加）
```

### データフロー図

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

PUT /{index}/_block/{block}  RestAddIndexBlockAction            JSON レスポンス
  +                               |                            {acknowledged: true,
  index名                   APIBlock.fromName()                 shards_acknowledged: true,
  block種別                       |                             indices: [...]}
  timeout               TransportAddIndexBlockAction
                               |
                    MetadataIndexStateService.addIndexBlock()
                               |
                    ClusterState更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| indices.add_block.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.add_block.json` | API定義 | REST APIスペック定義 |
| RestAddIndexBlockAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestAddIndexBlockAction.java` | ソース | RESTハンドラ |
| AddIndexBlockRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/readonly/AddIndexBlockRequest.java` | ソース | リクエストデータ構造 |
| IndexMetadata.java | `server/src/main/java/org/opensearch/cluster/metadata/IndexMetadata.java` | ソース | APIBlock列挙型定義 |
| TransportAddIndexBlockAction.java | `server/src/main/java/org/opensearch/action/admin/indices/readonly/TransportAddIndexBlockAction.java` | ソース | Transport層処理 |
| MetadataIndexStateService.java | `server/src/main/java/org/opensearch/cluster/metadata/MetadataIndexStateService.java` | ソース | ブロック追加ロジック |
