[Cloud Storage API(V2)] Javaでオブジェクトの保存(アップロード)・更新・削除する

Cloud Storage API V2(Java)を使用して、
Cloud Storageのオブジェクトの保存(アップロード)・更新・削除する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d)
を参照ください。
:::

|No|||目次|
|---|---|---|---|
|1|||[オブジェクトを保存](#1-オブジェクトを保存)|
||1||[スコープ](#11-スコープ)|
||2||[実行](#12-実行)|
||3||[レスポンスの内容](#13-レスポンスの内容)|
|2|||[オブジェクトを上書き](#2-オブジェクトを上書き)|
||1||[スコープ](#21-スコープ)|
||2||[実行](#22-実行)|
||3||[レスポンスの内容](#13-レスポンスの内容)|
|3|||[オブジェクトを更新](#3-オブジェクトを更新)|
||1||[スコープ](#31-スコープ)|
||2||[実行](#32-実行)|
||3||[レスポンスの内容](#33-レスポンスの内容)|
|4|||[オブジェクトを削除](#4-オブジェクトを削除)|
||1||[スコープ](#41-スコープ)|
||2||[実行](#42-実行)|
||3||[レスポンスの内容](#43-レスポンスの内容)|

## 1. オブジェクトを保存
指定したバケットにオブジェクトを保存します。

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

「オブジェクト名」は、アップロードするファイル名とフォルダのパスを指定します。
例えば、「test_file.csv」をいうファイルを./Folder1/Folder2の下にアップロードしたい場合、
「Folder1/Folder2/test_file.csv」と指定します。
ファイルパスに指定したフォルダが存在しない場合は、フォルダも作成されます。

サンプルでは、データのみをアップロードしていますので
setUploadType("media")にして、StorageObjectをnullで渡しています。

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.Objects objects = storage.objects();
    
    try(FileInputStream input = new FileInputStream("アップロードするファイルパス")){
        InputStreamContent mediaContent = new InputStreamContent("アップロードするファイルのMimeType", input);
    
        Storage.Objects.Insert insert = objects.insert("バケットID",null,mediaContent);
        insert.setName("オブジェクト名");
        insert.setUploadType("media");
        
        StorageObject res = insert.execute();
        System.out.println(res);
    }
}
```
#### 1.2.1. HTTPリクエスト
POST:　https:\//storage.googleapis.com/upload/storage/v1/b/{バケットID}/o
が実行されます。

#### 1.2.2. クエリパラメータ
Storage.Objects.Insertのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setName|String|【必須】オブジェクト名|
|setUploadType|String|【必須】[アップロードの方法](#アップロードの方法)|
|setContentEncoding|String|コンテンツのエンコーディング|
|setIfGenerationMatch|Long|世代番号(generation)と一致する場合のみ処理を行う|
|setIfGenerationNotMatch|Long|世代番号(generation)と一致しない場合のみ処理を行う|
|setIfMetagenerationMatch|Long|メタ世代番号(metageneration)と一致する場合のみ処理を行う|
|setIfMetagenerationNotMatch|Long|メタ世代番号(metageneration)と一致しない場合のみ処理を行う|
|setKmsKeyName|String|オブジェクトの暗号化に使用されるCloud KMS 鍵のリソース名|
|setPredefinedAcl|String|バケットに定義する[アクセス制御リスト(ACL)の定義](#アクセス制御リストaclの定義)|
|setProjection|String|レスポンスとして受け取るプロパティの指定<br><br>"full"(全てのプロパティ)、"noAcl"(ACL以外のプロパティ)|

#### アップロードの方法
|定義値|内容|
|---|---|
|media|データのみのアップロード|
|multipart|マルチパートアップロード。データとメタデータの両方をアップロード|
|resumable|メタデータ、データの順にアップロード|

#### アクセス制御リスト(ACL)の定義
|定義値|内容|
|---|---|
|authenticatedRead|プロジェクトチームの所有者がOWNERアクセス権を取得し、アクセス権allAuthenticatedUsersを取得|
|private|プロジェクトチームの所有者がOWNERアクセス権を取得|
|projectPrivate|プロジェクトチームのメンバーは、それぞれの役割に応じてアクセス権を取得|
|publicRead|プロジェクトチームの所有者がOWNERアクセス権を取得し、 アクセス権allUsersを取得|
|publicReadWrite|プロジェクトチームの所有者がOWNERアクセス権を取得し、アクセス権allUsersを取得|

#### 1.2.3. リクエストボディ
StorageObjectのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setName|String|オブジェクトの名前|
|setAcl|List\<[ObjectAccessControl](#objectaccesscontrolset)|オブジェクトのアクセスコントロール |
|setContentDisposition|String|Contentオブジェクトデータの配置|
|setContentEncoding|String|Contentオブジェクトデータのエンコーディング|
|setContentLanguage|String|Contentオブジェクトデータの言語|
|setContentType|String|ContentオブジェクトデータのContent-Type|
|setEventBasedHold|Boolean|オブジェクトがイベントベースの保留の対象か|
|setMd5Hash|String|データのMD5ハッシュ値|
|setMetadata|Map\<String,String\>|ユーザーが提供するメタデータ|
|setRetention|[StorageObject.Retention](#storageobjectretentionset)|オブジェクトの保持設定|
|setStorageClass|String|オブジェクトのストレージクラス|
|setTemporaryHold|Boolean|オブジェクトが 一時保留の対象か|
|setCustomTime|DateTime|ユーザー指定のタイムスタンプ|
|setCrc32c|String|CRC32c チェックサム|

#### ObjectAccessControl(Set)
|メソッド|引数|説明|
|---|---|---|
|setEntity|String|権限を保持するエンティティ<br><br>次のいずれかの形式<br>user-{email}<br>group-{groupId}<br>group-{email}<br>domain-{domain}<br>project-{team-projectId}<br>allUsers<br>allAuthenticatedUsers|
|setRole|String|エンティティのアクセス許可<br>"OWNER"、"READER"、"WRITER"|

#### StorageObject.Retention(Set)
|メソッド|引数|説明|
|---|---|---|
|setMode|String|保持設定のモード<br>"Unlocked"(変更可)、"Locked"(変更不可)|
|setRetainUntilTime|DateTime|オブジェクトを削除または置換が可能になった時刻|

### 1.3. レスポンスの内容
#### StorageObject
|メソッド|戻り値|説明|
|---|---|---|
|getId|String|オブジェクトID|	
|getKind|String|リソースの種類<br>固定文字列："storage#object"| 
|getName|String|オブジェクトの名前|
|getBucket|String|バケット名|
|getSize|BigInteger|データサイズ(バイト単位)|
|getGeneration|Long|世代番号(generation)|
|getMetageneration|Long|メタ世代番号(metageneration)|
|getEtag|String|オブジェクトのHTTPエンティティタグ|
|getMediaLink|String|オブジェクトのデータをダウンロードするためのURL|
|getSelfLink|String|オブジェクトのURL|
|getAcl|List\<[ObjectAccessControl](#objectaccesscontrol)|オブジェクトのアクセスコントロール |
|getCacheControl|String|オブジェクトデータのCache-Controlディレクティブ|
|getComponentCount|Integer|複合オブジェクトの場合の非複合オブジェクトの数|
|getContentDisposition|String|Contentオブジェクトデータの配置|
|getContentEncoding|String|Contentオブジェクトデータのエンコーディング|
|getContentLanguage|String|Contentオブジェクトデータの言語|
|getContentType|String|ContentオブジェクトデータのContent-Type|
|getCustomerEncryption|[StorageObject.CustomerEncryption](#storageobjectcustomerencryption)|顧客が指定した暗号化キーのメタデータ|	
|getEventBasedHold|Boolean|オブジェクトがイベントベースの保留の対象か|
|getKmsKeyName|String|このオブジェクトの暗号化に使用されるCloudKMS鍵|
|getMd5Hash|String|データのMD5ハッシュ値|
|getMetadata|Map\<String,String\>|ユーザーが提供するメタデータ|
|getOwner|[StorageObject.Owner](#storageobjectowner)|オブジェクトの所有者|
|getRetention|[StorageObject.Retention](#storageobjectretention)|オブジェクトの保持設定|
|getRetentionExpirationTime|DateTime|オブジェクトが削除可能なる最も早い時間|
|getSoftDeleteTime|DateTime|オブジェクトが論理的に削除された時刻|	
|getHardDeleteTime|DateTime|論理的に削除されたオブジェクトが完全に削除された時刻|
|getStorageClass|String|オブジェクトのストレージクラス|
|getTemporaryHold|Boolean|オブジェクトが 一時保留の対象か|
|getTimeCreated|DateTime|オブジェクトの作成時刻|
|getTimeDeleted|DateTime|オブジェクトの削除時刻|
|getTimeStorageClassUpdated|DateTime|オブジェクトのストレージクラスが最後に変更された時刻|
|getCustomTime|DateTime|ユーザー指定のタイムスタンプ|
|getUpdated|DateTime|オブジェクトのメタデータ変更時刻|

#### ObjectAccessControl
|メソッド|戻り値|説明|
|---|---|---|
|getKind|String|リソースの種類<br>固定文字列："storage#objectAccessControl"| 
|getDomain|String|エンティティに関連付けられているドメイン|
|getEmail|String|エンティティに関連付けられているメールアドレス|
|getEntity|String|権限を保持するエンティティ<br><br>次のいずれかの形式<br>user-{email}<br>group-{groupId}<br>group-{email}<br>domain-{domain}<br>project-{team-projectId}<br>allUsers<br>allAuthenticatedUsers|
|getEntityId|String|エンティティID|
|getEtag|String|アクセス制御エントリのHTTPエンティティタグ|
|getProjectTeam|[ObjectAccessControl.ProjectTeam](#objectaccesscontrolprojectteam)|エンティティに関連付けられているプロジェクトチーム|
|getRole|String|エンティティのアクセス許可<br>"OWNER"、"READER"、"WRITER"|

#### ObjectAccessControl.ProjectTeam
|メソッド|戻り値|説明|
|---|---|---|
|getProjectNumber|String|プロジェクト番号| 
|getTeam|String|チーム役割<br>"editors"、"owners"、"viewers"|

#### StorageObject.CustomerEncryption
|メソッド|戻り値|説明|
|---|---|---|
|getEncryptionAlgorithm|String|暗号化アルゴリズム|
|getKeySha256|String|暗号化キーの SHA256 ハッシュ値|

#### StorageObject.Owner
|メソッド|戻り値|説明|
|---|---|---|
|getEntity|String|エンティティ|
|getEntityId|String|エンティティID|

#### StorageObject.Retention
|メソッド|戻り値|説明|
|---|---|---|
|getMode|String|保持設定のモード<br>"Unlocked"(変更可)、"Locked"(変更不可)|
|getRetainUntilTime|DateTime|オブジェクトを削除または置換が可能になった時刻|

## 2. オブジェクトを上書き
指定したオブジェクトを上書きします。

[3. オブジェクトを更新](#3-オブジェクトを更新)と違うところは、
指定したオブジェクトを新しいオブジェクトに置き換えます。

### 2.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 2.2. 実行
オブジェクト名は、[StorageObjectのgetName()](#storageobject)で取得できる値を使用します。

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.Objects objects = storage.objects();
    
    StorageObject content = new StorageObject();
    //上書き内容を設定
    
    Storage.Objects.Update update = objects.update("バケットID","オブジェクト名",content);
    
    StorageObject res = update.execute();
    System.out.println(res);
}
```
#### 2.2.1. HTTPリクエスト
PUT:　https:\//storage.googleapis.com/storage/v1/b/{バケットID}/o/{オブジェクト名}
が実行されます。

#### 2.2.2. クエリパラメータ
Storage.Objects.Updateのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setGeneration|Long|世代番号(generation)|	
|setOverrideUnlockedRetention|Boolean|ロックが解除された保持構成を持つオブジェクトに適用するか|
|setIfGenerationMatch|Long|世代番号(generation)と一致する場合のみ処理を行う|
|setIfGenerationNotMatch|Long|世代番号(generation)と一致しない場合のみ処理を行う|
|setIfMetagenerationMatch|Long|メタ世代番号(metageneration)と一致する場合のみ処理を行う|
|setIfMetagenerationNotMatch|Long|メタ世代番号(metageneration)と一致しない場合のみ処理を行う|
|setPredefinedAcl|String|バケットに定義する[アクセス制御リスト(ACL)の定義](#アクセス制御リストaclの定義)|
|setProjection|String|レスポンスとして受け取るプロパティの指定<br><br>"full"(全てのプロパティ)、"noAcl"(ACL以外のプロパティ)|

#### 2.2.3. リクエストボディ
StorageObjectのsetメソッドにより、クエリパラメータを追加できます。

[1.2.3. リクエストボディ](#123-リクエストボディ)と同じです。

### 2.3. レスポンスの内容
#### StorageObject
[1.3. レスポンスの内容(StorageObject)](#storageobject)と同じです。

## 3. オブジェクトを更新
指定したオブジェクトのメタデータを更新します。

[2. オブジェクトを上書き](#2-オブジェクトを上書き)と違うところは、
指定したオブジェクトのメタデータのみを更新します。

### 3.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 3.2. 実行
オブジェクト名は、[StorageObjectのgetName()](#storageobject)で取得できる値を使用します。

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.Objects objects = storage.objects();
    
    StorageObject content = new StorageObject();
    //更新内容を設定
    
    Storage.Objects.Patch patch = objects.patch("バケットID","オブジェクト名",content);
    
    StorageObject res = patch.execute();
    System.out.println(res);
}
```
#### 3.2.1. HTTPリクエスト
PATCH:　https:\//storage.googleapis.com/storage/v1/b/{バケットID}/o/{オブジェクト名}
が実行されます。

#### 3.2.2. クエリパラメータ
Storage.Objects.Patchのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setGeneration|Long|世代番号(generation)|	
|setOverrideUnlockedRetention|Boolean|ロックが解除された保持構成を持つオブジェクトに適用するか|
|setIfGenerationMatch|Long|世代番号(generation)と一致する場合のみ処理を行う|
|setIfGenerationNotMatch|Long|世代番号(generation)と一致しない場合のみ処理を行う|
|setIfMetagenerationMatch|Long|メタ世代番号(metageneration)と一致する場合のみ処理を行う|
|setIfMetagenerationNotMatch|Long|メタ世代番号(metageneration)と一致しない場合のみ処理を行う|
|setPredefinedAcl|String|バケットに定義する[アクセス制御リスト(ACL)の定義](#アクセス制御リストaclの定義)|
|setProjection|String|レスポンスとして受け取るプロパティの指定<br><br>"full"(全てのプロパティ)、"noAcl"(ACL以外のプロパティ)|

#### 3.2.3. リクエストボディ
StorageObjectのsetメソッドにより、クエリパラメータを追加できます。

[1.2.3. リクエストボディ](#123-リクエストボディ)と同じです。

### 3.3. レスポンスの内容
#### StorageObject
[1.3. レスポンスの内容(StorageObject)](#storageobject)と同じです。

## 4. オブジェクトを削除
指定したオブジェクトを削除します。

### 4.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
StorageScopes.CLOUD_PLATFORM
StorageScopes.DEVSTORAGE_FULL_CONTROL
StorageScopes.DEVSTORAGE_READ_WRITE
```
[⧉[Cloud Storage API(V2)] JavaでCloud Storageを使う(2.2 Storageインスタンスを取得)](https://qiita.com/doran/items/2a5f7ef8070fd5b8c94d#22-storageインスタンスを取得)
でスコープを指定してください。

### 4.2. 実行
オブジェクト名は、[StorageObjectのgetName()](#storageobject)で取得できる値を使用します。

```java
public static void main(String[] args) throws Exception{
    Storage storage = getStorage();
    Storage.Objects objects = storage.objects();
    
    Storage.Objects.Delete delete = objects.delete("バケットID","オブジェクト名");
    
    delete.execute();
}
```
#### 4.2.1. HTTPリクエスト
DELETE:　https:\//storage.googleapis.com/storage/v1/b/{バケットID}/o/{オブジェクト名}
が実行されます。

#### 4.2.2. クエリパラメータ
Storage.Objects.Deleteのsetメソッドにより、クエリパラメータを追加できます。

|メソッド|引数|説明|
|---|---|---|
|setGeneration|Long|世代番号(generation)|	
|setIfGenerationMatch|Long|世代番号(generation)と一致する場合のみ処理を行う|
|setIfGenerationNotMatch|Long|世代番号(generation)と一致しない場合のみ処理を行う|
|setIfMetagenerationMatch|Long|メタ世代番号(metageneration)と一致する場合のみ処理を行う|
|setIfMetagenerationNotMatch|Long|メタ世代番号(metageneration)と一致しない場合のみ処理を行う|

#### 4.2.3. リクエストボディ
リクエストボディはありません。

### 4.3. レスポンスの内容
レスポンスはありません。
削除に失敗した場合は例外が発生します。

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