[Cloud Storage API(V2)] JavaでCloud Storageを使う

Googleが提供しているCloud Storage API V2をJavaで使ってみました。

***Cloud Storage APIとは***
Googleが提供しているAPIで、Cloud Storageに関する操作ができます。

下記にCloud Storageで出現する用語について簡単にまとめました。
|用語|概要|
|---|---|
|バケット|データを格納する基本的なコンテナ|
|オブジェクト|Cloud Storage内に保存する個々のデータ|
|アクセス制御リスト（ACL）|アクセスのレベルを定義するために使用できるメカニズム|
|HMACキー|アカウントに関連付けられた認証情報の一種|

料金は、Cloud Storage APIの実行するAPIによって異なります。
当然ですが、ストレージへの保存容量によっても料金が発生します。

詳細は[公式ドキュメントの「Cloud Storage の料金」](https://cloud.google.com/storage/pricing?hl=ja)を参照ください。

|No|||目次|
|---|---|---|---|
|1|||[Cloud Storage APIを使用するための準備](#1-cloud-storage-apiを使用するための準備)|
||1||[プロジェクトの作成](#11-プロジェクトの作成)|
||2||[APIを使用するためのキー取得](#13-apiを使用するためのキー取得)|
|2|||[Cloud Storage APIを使ってみる](#2-cloud-storage-apiを使ってみる)|
||1||[googleライブラリの読み込み](#21-googleライブラリの読み込み)|
||2||[Storageインスタンスを取得](#22-storageインスタンスを取得)|
|||1|[サービスアカウントを利用する場合](#221-サービスアカウントを利用する場合)|
|||2|[OAuth 2.0 クライアントIDを利用する場合](#222-oauth-20-クライアントidを利用する場合)|
||3||[プログラムの実行](#23-プログラムの実行)|
|3|||[いろいろとAPIを叩いてみる](#3-いろいろとapiを叩いてみる)|
||1||[バケットに対する操作](#31-buckets)|
||2||[管理フォルダ(マネージドフォルダ)に対する操作](#32-managedfolders)|
||3||[オブジェクトに対する操作](#33-objects)|
||4||[HMACキーに対する操作](#34-projectshmackeys)|
||5||[サービスエージェントのメールアドレスを取得](#35-projectsserviceaccount)|
||6||[変更通知(通知サブスクリプション)に対する操作](#36-notifications)|
||7||[変更通知(通知サブスクリプション)の停止](#37-channels)|
||8||[バケットに対するアクセス制御リスト(ACL)の操作](#38-bucketaccesscontrols)|
||9||[デフォルトのアクセス制御リスト(ACL)の操作](#39-defaultobjectaccesscontrols)|
||10||[オブジェクトのアクセス制御リスト(ACL)の操作](#310-objectaccesscontrols)|

# 1. Cloud Storage APIを使用するための準備
設定は下記から行います。
[⧉Google クラウド プラットフォーム](https://console.cloud.google.com/)

やることは大きく分けて下記の2つです。
[１.GCPプロジェクトの作成](#11-プロジェクトの作成)
[2.プログラムで使用するJSONファイルのダウンロード](#12-apiを使用するためのキー取得)

なお、APIの有効化はしなくともAPIが実行できるようです。

### 1.1. プロジェクトの作成
まずはGCPでプロジェクトを作成します。
詳細はこちらの記事を参照ください
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.1. プロジェクトの作成)](https://qiita.com/doran/items/3d43f776188b2281044c/#11-プロジェクトの作成)

### 1.2. APIを使用するためのキー取得
プログラムからAPIを実行するための準備を行います。
サービスアカウントを利用する方法と、OAuth2.0を利用する方法があります。

同じ内容を下記の記事に掲載してますので、下記の記事を参照ください。
[⧉[Google Drive API v3] JavaでDrive APIを使う](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#13-apiを使用するためのキー取得)

# 2. Cloud Storage APIを使ってみる
### 2.1. googleライブラリの読み込み
Cloud Storage APIを使用するためにライブラリのパスを設定します。
私の環境はpom.xmlで下記を指定しています。
Javaのバージョンは21を使用しています。

```xml
<dependencies>
    <dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>google-cloud-storage</artifactId>
    </dependency>
    <!-- OAuth2.0で認証を行う場合のみ使用します -->
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-jetty</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>libraries-bom</artifactId>
            <version>26.34.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
```

### 2.2. Storageインスタンスを取得

#### 2.2.1. サービスアカウントを利用する場合
コード中の「JSONファイルのパス」は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.3. Googleサービスアカウントの作成)](https://qiita.com/doran/items/3d43f776188b2281044c#13-googleサービスアカウントの作成)
で取得したJSONファイルのパスを指定してください。

コード中の「スコープ」は、
実行するAPIによって異なるので適時に変更してください。
```java
private static Storage getStorage() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(InputStream input = new FileInputStream("JSONファイルのパス")){
        GoogleCredentials credentials = GoogleCredentials
                .fromStream(input)
                .createScoped(Arrays.asList("スコープ"));
        
        return new Storage.Builder(transport, jsonFactory, new HttpCredentialsAdapter(credentials)).build();
    }
}
```
#### 2.2.2. OAuth 2.0 クライアントIDを利用する場合
コード中の「JSONファイルのパス」は、

[⧉[Google Drive API v3] JavaでDrive APIを使う(1.3.2.1 認証情報の作成)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#1321-認証情報の作成)
で取得したJSONファイルのパスを指定してください。

コード中の「認証情報を保存するフォルダパス」は、
認証情報が保存されるフォルダのパスを指定してください。
このコードを実行するとOAuth同意画面が表示されます。
ユーザーが同意をすると認証情報を保存するフォルダにファイルが生成されます。
このファイルが存在した場合は、再度実行してもOAuth同意画面は表示されません。

コード中の「スコープ」は、
実行するAPIによって異なるので適時に変更してください。
途中でスコープを変更した場合は再度のOAuth同意が必要になるので
「認証情報を保存するフォルダパス」にあるファイルを削除するか、パスを変えてください。
```java
private static Storage getStorage() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(Reader reader = new InputStreamReader(new FileInputStream("JSONファイルのパス"))){
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory,reader);

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                transport, jsonFactory, clientSecrets, 
                Arrays.asList("スコープ"))
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File("認証情報を保存するフォルダパス")))
            .build();
        
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
        
        return new Storage.Builder(transport, jsonFactory, credential).build();
    }
}
```

### 2.3. プログラムの実行
プログラムを動かします。
サンプルではバケットの一覧を取得しています。

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage2();
    Storage.Buckets bucketAccessControls = storage.buckets();
    Storage.Buckets.List list = bucketAccessControls.list("プロジェクトID");
    
    Buckets res = list.execute();
    System.out.println(res);
}
```
# 3. いろいろとAPIを叩いてみる
いろいろなAPIを叩いてみます。

表中の「料金」は、オペレーションのカテゴリの分類を示しています。
カテゴリは、クラスA、クラスB、無料の3つに分類され、クラスが異なると料金も変わります。
詳細は[公式ドキュメントの「Cloud Storage の料金」](https://cloud.google.com/storage/pricing?hl=ja#operations-pricing)を参照ください。

### 3.1. Buckets
バケットに対する操作				
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete|無料|バケットを削除|[⧉[Cloud Storage API(V2)] Javaでバケットを生成・更新・削除する](https://qiita.com/doran/items/a3d39a5be58209af232e)|
|get|B|バケットのメタデータを取得|[⧉[Cloud Storage API(V2)] Javaでバケットを取得する](https://qiita.com/doran/items/356962d5c905ab88f7b4)|
|getIamPolicy|B|IAM ポリシーを取得|[⧉[Cloud Storage API(V2)] JavaでバケットのIAMポリシーを取得する](https://qiita.com/doran/items/edbdfa530f75241d2419)|
|insert|A|バケットを作成|[⧉[Cloud Storage API(V2)] Javaでバケットを生成・更新・削除する](https://qiita.com/doran/items/a3d39a5be58209af232e)|
|list|A|バケットのリストを取得|[⧉[Cloud Storage API(V2)] Javaでバケットを取得する](https://qiita.com/doran/items/356962d5c905ab88f7b4)|
|lockRetentionPolicy|A|バケットの保持ポリシーをロック|[⧉[Cloud Storage API(V2)] Javaでバケットの保持ポリシーをロックする](https://qiita.com/doran/items/258ba2865c1e6021b33f)|
|patch|A|バケットを更新|[⧉[Cloud Storage API(V2)] Javaでバケットを生成・更新・削除する](https://qiita.com/doran/items/a3d39a5be58209af232e)|
|setIamPolicy|A|IAM ポリシーを更新|[⧉[Cloud Storage API(V2)] JavaでバケットのIAMポリシーを更新する](https://qiita.com/doran/items/9b5d0e0dba42a2bc98e8)|
|testIamPermissions|B|バケットのアクセス許可をテスト|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス権限をテストする](https://qiita.com/doran/items/f01c4975b02524123c41)|
|update|A|バケットを上書き更新|[⧉[Cloud Storage API(V2)] Javaでバケットを生成・更新・削除する](https://qiita.com/doran/items/a3d39a5be58209af232e)|

### 3.2. ManagedFolders
管理フォルダ(マネージドフォルダ)に対する操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete|B|管理フォルダ(マネージドフォルダ)を削除|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)を生成・削除する](https://qiita.com/doran/items/214611720b235ca4f1c5)|
|get|B|管理フォルダ(マネージドフォルダ)のメタデータを取得|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)を取得する](https://qiita.com/doran/items/3975603955e5c8503cbb)|
|getIamPolicy|B|管理フォルダ(マネージドフォルダ)のIAM ポリシーを取得|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)のIAMポリシーを取得する](https://qiita.com/doran/items/147c7188f30e13eb864c)|
|insert|A|管理フォルダ(マネージドフォルダ)を作成|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)を生成・削除する](https://qiita.com/doran/items/214611720b235ca4f1c5)|
|list|B|管理フォルダ(マネージドフォルダ)のリストを取得|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)を取得する](https://qiita.com/doran/items/3975603955e5c8503cbb)|
|setIamPolicy|A|管理フォルダ(マネージドフォルダ)のIAM ポリシーを更新|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)のIAMポリシーを更新する](https://qiita.com/doran/items/e593e6fbb623ff6c527b)|
|testIamPermissions|B|管理フォルダ(マネージドフォルダ)のアクセス許可をテスト|[⧉[Cloud Storage API(V2)] Javaで管理フォルダ(マネージドフォルダ)のアクセス許可をテストする](https://qiita.com/doran/items/7b67020cba5d10d881f0)|

### 3.3. Objects
オブジェクト(個々のデータ)に対する操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|bulkRestore|A|論理的に削除された複数のオブジェクトを一括復元|[⧉[Cloud Storage API(V2)] Javaで論理的削除されたオブジェクトをリストア(復元)する](https://qiita.com/doran/items/a706b5e852d32b93e151)|
|compose|A|オブジェクトを結合|[⧉[Cloud Storage API(V2)] JavaでCloud Storage上のオフジェクトを結合する](https://qiita.com/doran/items/1b33afdfbc19e627ac61)|
|copy|A|オブジェクトをコピー|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのコピー・置換する](https://qiita.com/doran/items/c75edc9ce0e017e14681)|
|delete|無料|オブジェクトとメタデータを削除|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの保存(アップロード)・更新・削除する](https://qiita.com/doran/items/1ae5cd4eb5b77ac92d0b)|
|get|B|オブジェクトのメタデータを取得<br><br>オブジェクトをダウンロード|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの情報を取得する](https://qiita.com/doran/items/41f683394d80ea80ba84)<br><br>[⧉[Cloud Storage API(V2)] Javaでオブジェクトをダウンロードする](https://qiita.com/doran/items/b50298555d4b243d25b7)|
|insert|A|オブジェクトを保存(アップロード)|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの保存(アップロード)・更新・削除する](https://qiita.com/doran/items/1ae5cd4eb5b77ac92d0b)|
|list|A|オブジェクトのリストを取得|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの情報を取得する](https://qiita.com/doran/items/41f683394d80ea80ba84)|
|patch|A|オブジェクトのメタデータを更新|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの保存(アップロード)・更新・削除する](https://qiita.com/doran/items/1ae5cd4eb5b77ac92d0b)|
|rewrite|A|オブジェクトを書き換え|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのコピー・置換する](https://qiita.com/doran/items/c75edc9ce0e017e14681)|
|update|A|オブジェクトを上書き更新|[⧉[Cloud Storage API(V2)] Javaでオブジェクトの保存(アップロード)・更新・削除する](https://qiita.com/doran/items/1ae5cd4eb5b77ac92d0b)|
|watchAll|B|バケット内の全てのオブジェクトの変更を監視|[⧉[Cloud Storage API(V2)] Javaで変更通知(通知サブスクリプション)を登録・削除する](https://qiita.com/doran/items/581ac39147ed907a2c02)|
|restore|A|論理的に削除されたオブジェクトを復元|[⧉[Cloud Storage API(V2)] Javaで論理的削除されたオブジェクトをリストア(復元)する](https://qiita.com/doran/items/a706b5e852d32b93e151)|

### 3.4. Projects.hmacKeys
HMACキーに対する操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|create|B|HMACキーを作成|[⧉[Cloud Storage API(V2)] JavaでCloud StorageのHMACキー情報を作成・更新・削除する](https://qiita.com/doran/items/fc0bf6ef2046203b8918)|
|delete|無料|HMACキーを削除|[⧉[Cloud Storage API(V2)] JavaでCloud StorageのHMACキー情報を作成・更新・削除する](https://qiita.com/doran/items/fc0bf6ef2046203b8918)|
|get|B|HMACキーのメタデータを取得|[⧉[Cloud Storage API(V2)] JavaでCloud StorageのHMACキー情報を取得する](https://qiita.com/doran/items/4b311f798fa612d529b0)|
|list|B|HMACキーのリストを取得|[⧉[Cloud Storage API(V2)] JavaでCloud StorageのHMACキー情報を取得する](https://qiita.com/doran/items/4b311f798fa612d529b0)|
|update|A|HMACキーを更新|[⧉[Cloud Storage API(V2)] JavaでCloud StorageのHMACキー情報を作成・更新・削除する](https://qiita.com/doran/items/fc0bf6ef2046203b8918)|

### 3.5. Projects.serviceAccount
サービスエージェントのメールアドレスを取得
|メソッド|料金|概要|記事|
|---|---|---|---|
|get|B|Cloud Storageサービスエージェントのメールアドレスを取得|[⧉[Cloud Storage API(V2)] JavaでCloud Storageサービスアカウントのメールアドレスを取得する](https://qiita.com/doran/items/1187feb35766e9cb7806)|

### 3.6. Notifications
変更通知(通知サブスクリプション)に対する操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete|A|変更通知(通知サブスクリプション)を削除|[⧉[Cloud Storage API(V2)] Javaで変更通知(通知サブスクリプション)を登録・削除する](https://qiita.com/doran/items/581ac39147ed907a2c02)|
|get|B|変更通知(通知サブスクリプション)を取得|[⧉[Cloud Storage API(V2)] Javaでバケットの変更通知(通知サブスクリプション)を取得する](https://qiita.com/doran/items/727d5a65c4fe30e4c6ee)|
|insert|A|変更通知(通知サブスクリプション)を作成|[⧉[Cloud Storage API(V2)] Javaで変更通知(通知サブスクリプション)を登録・削除する](https://qiita.com/doran/items/581ac39147ed907a2c02)|
|list|B|変更通知(通知サブスクリプション)のリストを取得|[⧉[Cloud Storage API(V2)] Javaでバケットの変更通知(通知サブスクリプション)を取得する](https://qiita.com/doran/items/727d5a65c4fe30e4c6ee)|

### 3.7. Channels
変更通知(通知サブスクリプション)の停止操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|stop|無料|変更通知の受信を停止|[⧉[Cloud Storage API(V2)] Javaで変更通知(通知サブスクリプション)を登録・削除する](https://qiita.com/doran/items/581ac39147ed907a2c02)|

### 3.8. BucketAccessControls
バケットに対するアクセス制御リスト(ACL)の操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete||ACLエントリを削除|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/4a96290f8514f89a8002)|
|get|B|ACLエントリを取得|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/ddb647c377a99535c2fd)|
|insert|A|ACLエントリを作成|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/4a96290f8514f89a8002)|
|list|B|ACLエントリのリストを取得|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/ddb647c377a99535c2fd)|
|patch|A|ACLエントリを更新|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/4a96290f8514f89a8002)|
|update|A|ACLエントリを上書き更新|[⧉[Cloud Storage API(V2)] Javaでバケットのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/4a96290f8514f89a8002)|

### 3.9. DefaultObjectAccessControls
デフォルトのアクセス制御リスト(ACL)の操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete|B|デフォルトのACLエントリを削除|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/a31458eea52f9a02ab9a)|
|get|B|デフォルトのACL エントリを取得|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/495ee5635e3cd78484ca)|
|insert|A|デフォルトのACL エントリを作成|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/a31458eea52f9a02ab9a)|
|list|B|デフォルトのACL エントリのリストを取得|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/495ee5635e3cd78484ca)|
|patch|A|デフォルトのACL エントリを更新|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/a31458eea52f9a02ab9a)|
|update|A|デフォルトのACL エントリを上書き更新|[⧉[Cloud Storage API(V2)] Javaでデフォルトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/a31458eea52f9a02ab9a)|

### 3.10. ObjectAccessControls
オブジェクトのアクセス制御リスト(ACL)の操作
|メソッド|料金|概要|記事|
|---|---|---|---|
|delete|B|オブジェクトのACLエントリを削除|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/d6e99572a9c175806cc0)|
|get|B|オブジェクトのACL エントリを取得|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/47e2e7b733c06e2d3f32)|
|insert|A|オブジェクトのACL エントリを作成|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/d6e99572a9c175806cc0)|
|list|B|オブジェクトのACL エントリのリストを取得|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを取得する](https://qiita.com/doran/items/47e2e7b733c06e2d3f32)|
|patch|A|オブジェクトのACL エントリを更新|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/d6e99572a9c175806cc0)|
|update|A|オブジェクトのACL エントリを上書き更新|[⧉[Cloud Storage API(V2)] Javaでオブジェクトのアクセス制御リスト(ACL)エントリを作成・更新・削除する](https://qiita.com/doran/items/d6e99572a9c175806cc0)|


<br>
<br>
おしまい。。