# 機能設計書 66-S3リポジトリ

## 概要

本ドキュメントは、OpenSearchのS3リポジトリプラグインに関する機能設計書である。本プラグインはAmazon S3をスナップショットリポジトリとして使用するための機能を提供し、S3RepositoryPlugin/S3Repository/S3BlobStore/S3BlobContainerの各クラスで実装されている。

### 本機能の処理概要

**業務上の目的・背景**：Amazon S3はクラウド環境で最も広く使用されるオブジェクトストレージサービスの1つである。S3リポジトリプラグインにより、OpenSearchのスナップショットデータをS3に保存し、高耐久性・高可用性のバックアップを実現する。

**機能の利用シーン**：AWS環境でのOpenSearchクラスタのバックアップ・リストア、クロスリージョンでのデータ複製、災害復旧（DR）用のデータ保管等に利用される。

**主要な処理内容**：
1. S3バケットへのスナップショットデータの書き込み（同期・非同期マルチパートアップロード対応）
2. S3バケットからのスナップショットデータの読み取り
3. S3クライアント設定の管理（認証情報、リージョン、エンドポイント等）
4. サーバーサイド暗号化（SSE-S3、SSE-KMS）のサポート
5. ACL（アクセス制御リスト）の設定
6. ストレージクラスの指定
7. 非同期転送マネージャーによる大容量ファイルのマルチパートアップロード
8. プロキシ設定のサポート

**関連システム・外部連携**：Amazon S3 API（AWS SDK for Java v2）を使用してS3と通信する。IAMロール、アクセスキー、STS一時認証情報等の認証方法をサポート。

**権限による制御**：S3バケットへのアクセスはAWS IAMポリシーで制御される。プラグイン設定でアクセスキー・シークレットキーを管理する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 115 | リポジトリ作成 | 補助機能 | type=s3でS3リポジトリを作成する処理 |

## 機能種別

データ連携 / プラグイン

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| bucket | String | Yes | S3バケット名 | 存在するS3バケット |
| base_path | String | No | バケット内のベースパス | 有効なパス文字列 |
| client | String | No | クライアント名（デフォルト: "default"） | 設定済みクライアント名 |
| chunk_size | ByteSizeValue | No | チャンクサイズ（最大5TB） | 正のバイトサイズ値 |
| compress | boolean | No | メタデータ圧縮の有効化 | true/false |
| server_side_encryption | boolean | No | SSE-S3の有効化 | true/false |
| canned_acl | String | No | Canned ACL（private, public-read等） | 有効なACL値 |
| storage_class | String | No | ストレージクラス（STANDARD, STANDARD_IA等） | 有効なストレージクラス |
| access_key | SecureString | No | AWSアクセスキー | SecureSetting |
| secret_key | SecureString | No | AWSシークレットキー | SecureSetting |

### 入力データソース

リポジトリ設定（PUT /_snapshot/{repository}）、opensearch.yml（クライアント設定）、opensearch-keystore（認証情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| S3 Objects | Binary | スナップショットデータファイル |
| StatsMetricPublisher | Object | S3操作の統計メトリクス |

### 出力先

Amazon S3バケット

## 処理フロー

### 処理シーケンス

```
1. S3Repositoryインスタンスの生成
   └─ MeteredBlobStoreRepositoryを継承
2. S3BlobStoreの生成
   └─ S3Service経由でS3クライアントを取得
3. データ書き込み
   └─ S3BlobContainer.writeBlobWithMetadata()
   └─ AsyncTransferManager（マルチパートアップロード）
4. データ読み取り
   └─ S3BlobContainer.readBlob()
   └─ S3RetryingInputStream（リトライ対応InputStream）
5. 統計メトリクスの収集
   └─ StatsMetricPublisher / GenericStatsMetricPublisher
```

### フローチャート

```mermaid
flowchart TD
    A[リポジトリ操作要求] --> B{操作種別}
    B -->|書込| C[S3BlobContainer.writeBlobWithMetadata]
    B -->|読取| D[S3BlobContainer.readBlob]
    B -->|削除| E[S3BlobContainer.deleteBlobsIgnoringIfNotExists]
    C --> F{ファイルサイズ}
    F -->|小| G[PutObject API]
    F -->|大| H[AsyncTransferManager / マルチパート]
    D --> I[S3RetryingInputStream]
    G --> J[S3バケット]
    H --> J
    I --> K[データ返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | バケット名必須 | bucketパラメータは必須 | リポジトリ登録時 |
| BR-66-02 | チャンクサイズ上限 | チャンクサイズは最大5TB | リポジトリ設定時 |
| BR-66-03 | 認証情報優先順位 | keystore > opensearch.yml > IAMロール > インスタンスプロファイル | S3クライアント認証時 |

### 計算ロジック

特になし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スナップショット保存 | S3バケット | WRITE | PutObject/MultipartUpload API |
| スナップショット読取 | S3バケット | READ | GetObject API |
| スナップショット削除 | S3バケット | DELETE | DeleteObjects API |
| オブジェクト一覧 | S3バケット | READ | ListObjects API |

### テーブル別操作詳細

#### S3バケット

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| WRITE | {base_path}/indices/{indexId}/{shardId}/* | Luceneセグメントデータ | マルチパートアップロード対応 |
| WRITE | {base_path}/index-N | RepositoryData | アトミック更新 |
| READ | {base_path}/snap-{uuid}.dat | SnapshotInfo | スナップショットメタデータ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| BlobStoreException | ストアエラー | S3 API呼び出しの失敗 | S3設定・権限の確認 |
| S3TransferRejectedException | 転送拒否 | 非同期転送キューの満杯 | リトライまたは設定調整 |
| RepositoryException | リポジトリエラー | リポジトリ設定の不正 | 設定の修正 |

### リトライ仕様

S3RetryingInputStreamにより、読み取り操作のリトライが自動的に行われる。非同期転送はSizeBasedBlockingQにより制御される。

## トランザクション仕様

S3操作はオブジェクト単位でのアトミック操作。マルチパートアップロードはComplete/Abortで一貫性を保証する。

## パフォーマンス要件

- AsyncTransferManagerによる非同期マルチパートアップロードで大容量ファイルの高速転送
- SizeBasedBlockingQによるメモリ使用量の制御
- 並行ストリーム数の設定（concurrent_streams）
- JVMヒープサイズに基づく最適なバッファサイズ計算

## セキュリティ考慮事項

- 認証情報はSecureSettingを使用してkeystoreに保存
- サーバーサイド暗号化（SSE-S3、SSE-KMS）をサポート
- HTTPSによる通信暗号化
- プロキシ設定によるネットワーク制御

## 備考

- S3RepositoryのTYPE定数は"s3"
- AWS SDK for Java v2（software.amazon.awssdk）を使用
- ObjectCannedACL、ServerSideEncryption、StorageClassの各AWS列挙型を使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | S3ClientSettings.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3ClientSettings.java` | S3クライアント設定のデータ構造（認証情報、リージョン、エンドポイント等） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | S3RepositoryPlugin.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3RepositoryPlugin.java` | プラグインエントリーポイント、リポジトリファクトリ登録 |
| 2-2 | S3Repository.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3Repository.java` | S3リポジトリ実装クラス |

**主要処理フロー**:
1. **95行目**: S3Repositoryクラス宣言、MeteredBlobStoreRepositoryを継承
2. **99行目**: TYPE = "s3"

#### Step 3: BlobStore層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | S3BlobStore.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3BlobStore.java` | S3 BlobStore実装 |
| 3-2 | S3BlobContainer.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3BlobContainer.java` | S3 BlobContainer実装（読み書き操作） |

#### Step 4: 非同期転送を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AsyncTransferManager.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/async/AsyncTransferManager.java` | 非同期マルチパートアップロード |
| 4-2 | SizeBasedBlockingQ.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/async/SizeBasedBlockingQ.java` | サイズベースのブロッキングキュー |

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

```
S3RepositoryPlugin (プラグイン登録)
    |
    +-- S3Repository (MeteredBlobStoreRepository)
            |
            +-- S3BlobStore
            |       |
            |       +-- S3Service / S3AsyncService
            |       |       +-- AmazonS3WithCredentials
            |       |       +-- AmazonAsyncS3WithCredentials
            |       |
            |       +-- S3BlobContainer
            |               +-- writeBlob() -> PutObject / MultipartUpload
            |               +-- readBlob() -> S3RetryingInputStream
            |
            +-- AsyncTransferManager
            |       +-- AsyncExecutorContainer
            |       +-- SizeBasedBlockingQ
            |
            +-- StatsMetricPublisher / GenericStatsMetricPublisher
```

### データフロー図

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

スナップショットデータ ──> S3Repository ──> S3BlobStore ──> S3BlobContainer ──> S3バケット
                                              |
                                              +-- S3Service ──> AWS S3 API
                                              +-- AsyncTransferManager ──> マルチパートアップロード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| S3RepositoryPlugin.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3RepositoryPlugin.java` | ソース | プラグインエントリーポイント |
| S3Repository.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3Repository.java` | ソース | S3リポジトリ実装 |
| S3BlobStore.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3BlobStore.java` | ソース | S3 BlobStore実装 |
| S3BlobContainer.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3BlobContainer.java` | ソース | S3 BlobContainer実装 |
| S3Service.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3Service.java` | ソース | S3クライアント管理 |
| S3AsyncService.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3AsyncService.java` | ソース | 非同期S3クライアント管理 |
| S3ClientSettings.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3ClientSettings.java` | ソース | クライアント設定 |
| S3RetryingInputStream.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3RetryingInputStream.java` | ソース | リトライ対応InputStream |
| AsyncTransferManager.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/async/AsyncTransferManager.java` | ソース | 非同期転送マネージャー |
| ProxySettings.java | `plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/ProxySettings.java` | ソース | プロキシ設定 |
